1*7fd79137SRobert Mustacchi /* 2*7fd79137SRobert Mustacchi 3*7fd79137SRobert Mustacchi Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. 4*7fd79137SRobert Mustacchi Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved. 5*7fd79137SRobert Mustacchi 6*7fd79137SRobert Mustacchi This program is free software; you can redistribute it and/or modify it 7*7fd79137SRobert Mustacchi under the terms of version 2.1 of the GNU Lesser General Public License 8*7fd79137SRobert Mustacchi as published by the Free Software Foundation. 9*7fd79137SRobert Mustacchi 10*7fd79137SRobert Mustacchi This program is distributed in the hope that it would be useful, but 11*7fd79137SRobert Mustacchi WITHOUT ANY WARRANTY; without even the implied warranty of 12*7fd79137SRobert Mustacchi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13*7fd79137SRobert Mustacchi 14*7fd79137SRobert Mustacchi Further, this software is distributed without any warranty that it is 15*7fd79137SRobert Mustacchi free of the rightful claim of any third person regarding infringement 16*7fd79137SRobert Mustacchi or the like. Any license provided herein, whether implied or 17*7fd79137SRobert Mustacchi otherwise, applies only to this software file. Patent licenses, if 18*7fd79137SRobert Mustacchi any, provided herein do not apply to combinations of this program with 19*7fd79137SRobert Mustacchi other software, or any other product whatsoever. 20*7fd79137SRobert Mustacchi 21*7fd79137SRobert Mustacchi You should have received a copy of the GNU Lesser General Public 22*7fd79137SRobert Mustacchi License along with this program; if not, write the Free Software 23*7fd79137SRobert Mustacchi Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, 24*7fd79137SRobert Mustacchi USA. 25*7fd79137SRobert Mustacchi 26*7fd79137SRobert Mustacchi Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, 27*7fd79137SRobert Mustacchi Mountain View, CA 94043, or: 28*7fd79137SRobert Mustacchi 29*7fd79137SRobert Mustacchi http://www.sgi.com 30*7fd79137SRobert Mustacchi 31*7fd79137SRobert Mustacchi For further information regarding this notice, see: 32*7fd79137SRobert Mustacchi 33*7fd79137SRobert Mustacchi http://oss.sgi.com/projects/GenInfo/NoticeExplan 34*7fd79137SRobert Mustacchi 35*7fd79137SRobert Mustacchi */ 36*7fd79137SRobert Mustacchi /* The address of the Free Software Foundation is 37*7fd79137SRobert Mustacchi Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 38*7fd79137SRobert Mustacchi Boston, MA 02110-1301, USA. 39*7fd79137SRobert Mustacchi SGI has moved from the Crittenden Lane address. 40*7fd79137SRobert Mustacchi */ 41*7fd79137SRobert Mustacchi 42*7fd79137SRobert Mustacchi 43*7fd79137SRobert Mustacchi /* 44*7fd79137SRobert Mustacchi This implements _dwarf_get_fde_list_internal() 45*7fd79137SRobert Mustacchi and related helper functions for reading cie/fde data. 46*7fd79137SRobert Mustacchi */ 47*7fd79137SRobert Mustacchi 48*7fd79137SRobert Mustacchi 49*7fd79137SRobert Mustacchi 50*7fd79137SRobert Mustacchi #include "config.h" 51*7fd79137SRobert Mustacchi #include "dwarf_incl.h" 52*7fd79137SRobert Mustacchi #include <stdio.h> 53*7fd79137SRobert Mustacchi #include <stdlib.h> 54*7fd79137SRobert Mustacchi #include <sys/types.h> 55*7fd79137SRobert Mustacchi #include "dwarf_frame.h" 56*7fd79137SRobert Mustacchi #include "dwarf_arange.h" /* using Arange as a way to build a 57*7fd79137SRobert Mustacchi list */ 58*7fd79137SRobert Mustacchi 59*7fd79137SRobert Mustacchi 60*7fd79137SRobert Mustacchi static int dwarf_find_existing_cie_ptr(Dwarf_Small * cie_ptr, 61*7fd79137SRobert Mustacchi Dwarf_Cie cur_cie_ptr, 62*7fd79137SRobert Mustacchi Dwarf_Cie * cie_ptr_to_use_out, 63*7fd79137SRobert Mustacchi Dwarf_Cie head_cie_ptr); 64*7fd79137SRobert Mustacchi static void dealloc_fde_cie_list_internal(Dwarf_Fde head_fde_ptr, 65*7fd79137SRobert Mustacchi Dwarf_Cie head_cie_ptr); 66*7fd79137SRobert Mustacchi static int dwarf_create_cie_from_start(Dwarf_Debug dbg, 67*7fd79137SRobert Mustacchi Dwarf_Small * cie_ptr_val, 68*7fd79137SRobert Mustacchi Dwarf_Small * section_ptr, 69*7fd79137SRobert Mustacchi Dwarf_Unsigned section_index, 70*7fd79137SRobert Mustacchi Dwarf_Unsigned section_length, 71*7fd79137SRobert Mustacchi Dwarf_Small * frame_ptr_end, 72*7fd79137SRobert Mustacchi Dwarf_Unsigned cie_id_value, 73*7fd79137SRobert Mustacchi Dwarf_Unsigned cie_count, 74*7fd79137SRobert Mustacchi int use_gnu_cie_calc, 75*7fd79137SRobert Mustacchi Dwarf_Cie * cie_ptr_to_use_out, 76*7fd79137SRobert Mustacchi Dwarf_Error * error); 77*7fd79137SRobert Mustacchi 78*7fd79137SRobert Mustacchi static Dwarf_Small *get_cieptr_given_offset(Dwarf_Unsigned cie_id_value, 79*7fd79137SRobert Mustacchi int use_gnu_cie_calc, 80*7fd79137SRobert Mustacchi Dwarf_Small * section_ptr, 81*7fd79137SRobert Mustacchi Dwarf_Small * cie_id_addr); 82*7fd79137SRobert Mustacchi static int get_gcc_eh_augmentation(Dwarf_Debug dbg, 83*7fd79137SRobert Mustacchi Dwarf_Small * frame_ptr, 84*7fd79137SRobert Mustacchi unsigned long 85*7fd79137SRobert Mustacchi *size_of_augmentation_data, 86*7fd79137SRobert Mustacchi enum Dwarf_augmentation_type augtype, 87*7fd79137SRobert Mustacchi Dwarf_Small * section_pointer, 88*7fd79137SRobert Mustacchi Dwarf_Small * fde_eh_encoding_out, 89*7fd79137SRobert Mustacchi char *augmentation); 90*7fd79137SRobert Mustacchi 91*7fd79137SRobert Mustacchi static int 92*7fd79137SRobert Mustacchi gnu_aug_encodings(Dwarf_Debug dbg, char *augmentation, 93*7fd79137SRobert Mustacchi Dwarf_Small * aug_data, Dwarf_Unsigned aug_data_len, 94*7fd79137SRobert Mustacchi Dwarf_Half address_size, 95*7fd79137SRobert Mustacchi unsigned char *pers_hand_enc_out, 96*7fd79137SRobert Mustacchi unsigned char *lsda_enc_out, 97*7fd79137SRobert Mustacchi unsigned char *fde_begin_enc_out, 98*7fd79137SRobert Mustacchi Dwarf_Addr * gnu_pers_addr_out); 99*7fd79137SRobert Mustacchi 100*7fd79137SRobert Mustacchi 101*7fd79137SRobert Mustacchi static int read_encoded_ptr(Dwarf_Debug dbg, 102*7fd79137SRobert Mustacchi Dwarf_Small * section_pointer, 103*7fd79137SRobert Mustacchi Dwarf_Small * input_field, 104*7fd79137SRobert Mustacchi int gnu_encoding, 105*7fd79137SRobert Mustacchi Dwarf_Half address_size, 106*7fd79137SRobert Mustacchi Dwarf_Unsigned * addr, 107*7fd79137SRobert Mustacchi Dwarf_Small ** input_field_out); 108*7fd79137SRobert Mustacchi 109*7fd79137SRobert Mustacchi 110*7fd79137SRobert Mustacchi 111*7fd79137SRobert Mustacchi static int qsort_compare(const void *elem1, const void *elem2); 112*7fd79137SRobert Mustacchi 113*7fd79137SRobert Mustacchi 114*7fd79137SRobert Mustacchi /* Adds 'newone' to the end of the list starting at 'head' 115*7fd79137SRobert Mustacchi and makes the new one 'cur'rent. */ 116*7fd79137SRobert Mustacchi static void 117*7fd79137SRobert Mustacchi chain_up_fde(Dwarf_Fde newone, Dwarf_Fde * head, Dwarf_Fde * cur) 118*7fd79137SRobert Mustacchi { 119*7fd79137SRobert Mustacchi if (*head == NULL) 120*7fd79137SRobert Mustacchi *head = newone; 121*7fd79137SRobert Mustacchi else { 122*7fd79137SRobert Mustacchi (*cur)->fd_next = newone; 123*7fd79137SRobert Mustacchi } 124*7fd79137SRobert Mustacchi *cur = newone; 125*7fd79137SRobert Mustacchi 126*7fd79137SRobert Mustacchi } 127*7fd79137SRobert Mustacchi 128*7fd79137SRobert Mustacchi /* Adds 'newone' to the end of the list starting at 'head' 129*7fd79137SRobert Mustacchi and makes the new one 'cur'rent. */ 130*7fd79137SRobert Mustacchi static void 131*7fd79137SRobert Mustacchi chain_up_cie(Dwarf_Cie newone, Dwarf_Cie * head, Dwarf_Cie * cur) 132*7fd79137SRobert Mustacchi { 133*7fd79137SRobert Mustacchi if (*head == NULL) { 134*7fd79137SRobert Mustacchi *head = newone; 135*7fd79137SRobert Mustacchi } else { 136*7fd79137SRobert Mustacchi (*cur)->ci_next = newone; 137*7fd79137SRobert Mustacchi } 138*7fd79137SRobert Mustacchi *cur = newone; 139*7fd79137SRobert Mustacchi } 140*7fd79137SRobert Mustacchi 141*7fd79137SRobert Mustacchi /* The size of the length field plus the 142*7fd79137SRobert Mustacchi value of length must be an integral 143*7fd79137SRobert Mustacchi multiple of the address size. Dwarf4 standard. 144*7fd79137SRobert Mustacchi 145*7fd79137SRobert Mustacchi A constant that gives the number of bytes of the CIE 146*7fd79137SRobert Mustacchi structure, not including the length field itself 147*7fd79137SRobert Mustacchi (where length mod <size of an address> == 0) 148*7fd79137SRobert Mustacchi (see Section 7.2.2). Dwarf3 standard. 149*7fd79137SRobert Mustacchi 150*7fd79137SRobert Mustacchi A uword constant that gives the number of bytes of 151*7fd79137SRobert Mustacchi the CIE structure, not including the 152*7fd79137SRobert Mustacchi length field, itself (length mod <addressing unit size> == 0). 153*7fd79137SRobert Mustacchi Dwarf2 standard.*/ 154*7fd79137SRobert Mustacchi static void 155*7fd79137SRobert Mustacchi validate_length(Dwarf_Debug dbg, 156*7fd79137SRobert Mustacchi Dwarf_Cie cieptr, Dwarf_Unsigned length, 157*7fd79137SRobert Mustacchi Dwarf_Unsigned length_size, 158*7fd79137SRobert Mustacchi Dwarf_Unsigned extension_size, 159*7fd79137SRobert Mustacchi Dwarf_Small * section_ptr, 160*7fd79137SRobert Mustacchi Dwarf_Small * ciefde_start, 161*7fd79137SRobert Mustacchi const char * cieorfde) 162*7fd79137SRobert Mustacchi { 163*7fd79137SRobert Mustacchi Dwarf_Unsigned address_size = cieptr->ci_address_size; 164*7fd79137SRobert Mustacchi Dwarf_Unsigned length_field_summed = length_size + extension_size; 165*7fd79137SRobert Mustacchi Dwarf_Unsigned total_len = length + length_field_summed; 166*7fd79137SRobert Mustacchi Dwarf_Unsigned mod = total_len % address_size; 167*7fd79137SRobert Mustacchi 168*7fd79137SRobert Mustacchi if (mod != 0) { 169*7fd79137SRobert Mustacchi char msg[DW_HARMLESS_ERROR_MSG_STRING_SIZE]; 170*7fd79137SRobert Mustacchi Dwarf_Unsigned sectionoffset = ciefde_start - section_ptr; 171*7fd79137SRobert Mustacchi snprintf(msg,sizeof(msg), 172*7fd79137SRobert Mustacchi "DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE" 173*7fd79137SRobert Mustacchi " len=0x%" DW_PR_DUx 174*7fd79137SRobert Mustacchi ", len size=0x%" DW_PR_DUx 175*7fd79137SRobert Mustacchi ", extn size=0x%" DW_PR_DUx 176*7fd79137SRobert Mustacchi ", totl length=0x%" DW_PR_DUx 177*7fd79137SRobert Mustacchi ", addr size=0x%" DW_PR_DUx 178*7fd79137SRobert Mustacchi ", mod=0x%" DW_PR_DUx " must be zero" 179*7fd79137SRobert Mustacchi " in %s" 180*7fd79137SRobert Mustacchi ", offset 0x%" DW_PR_DUx ".", 181*7fd79137SRobert Mustacchi length, 182*7fd79137SRobert Mustacchi length_size, 183*7fd79137SRobert Mustacchi extension_size, 184*7fd79137SRobert Mustacchi total_len,address_size, mod, 185*7fd79137SRobert Mustacchi cieorfde, 186*7fd79137SRobert Mustacchi sectionoffset); 187*7fd79137SRobert Mustacchi dwarf_insert_harmless_error(dbg,msg); 188*7fd79137SRobert Mustacchi } 189*7fd79137SRobert Mustacchi return; 190*7fd79137SRobert Mustacchi } 191*7fd79137SRobert Mustacchi 192*7fd79137SRobert Mustacchi 193*7fd79137SRobert Mustacchi #if 0 194*7fd79137SRobert Mustacchi /* For debugging only. */ 195*7fd79137SRobert Mustacchi static void 196*7fd79137SRobert Mustacchi print_prefix(struct cie_fde_prefix_s *prefix, int line) 197*7fd79137SRobert Mustacchi { 198*7fd79137SRobert Mustacchi printf("prefix-print, prefix at 0x%lx, line %d\n", 199*7fd79137SRobert Mustacchi (long) prefix, line); 200*7fd79137SRobert Mustacchi printf(" start addr 0x%lx after prefix 0x%lx\n", 201*7fd79137SRobert Mustacchi (long) prefix->cf_start_addr, 202*7fd79137SRobert Mustacchi (long) prefix->cf_addr_after_prefix); 203*7fd79137SRobert Mustacchi printf(" length 0x%" DW_PR_DUx ", len size %d ext size %d\n", 204*7fd79137SRobert Mustacchi (Dwarf_Unsigned) prefix->cf_length, 205*7fd79137SRobert Mustacchi prefix->cf_local_length_size, 206*7fd79137SRobert Mustacchi prefix->cf_local_extension_size); 207*7fd79137SRobert Mustacchi printf(" cie_id 0x%" DW_PR_DUx " cie_id cie_id_addr 0x%lx\n", 208*7fd79137SRobert Mustacchi (Dwarf_Unsigned) prefix->cf_cie_id, 209*7fd79137SRobert Mustacchi (long) prefix->cf_cie_id_addr); 210*7fd79137SRobert Mustacchi printf 211*7fd79137SRobert Mustacchi (" sec ptr 0x%lx sec index %" DW_PR_DSd " sec len 0x%" DW_PR_DUx " sec past end 0x%lx\n", 212*7fd79137SRobert Mustacchi (long) prefix->cf_section_ptr, 213*7fd79137SRobert Mustacchi (Dwarf_Signed) prefix->cf_section_index, 214*7fd79137SRobert Mustacchi (Dwarf_Unsigned) prefix->cf_section_length, 215*7fd79137SRobert Mustacchi (long) prefix->cf_section_ptr + prefix->cf_section_length); 216*7fd79137SRobert Mustacchi } 217*7fd79137SRobert Mustacchi #endif 218*7fd79137SRobert Mustacchi 219*7fd79137SRobert Mustacchi 220*7fd79137SRobert Mustacchi 221*7fd79137SRobert Mustacchi /* Internal function called from various places to create 222*7fd79137SRobert Mustacchi lists of CIEs and FDEs. Not directly called 223*7fd79137SRobert Mustacchi by consumer code */ 224*7fd79137SRobert Mustacchi int 225*7fd79137SRobert Mustacchi _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data, 226*7fd79137SRobert Mustacchi Dwarf_Signed * cie_element_count, 227*7fd79137SRobert Mustacchi Dwarf_Fde ** fde_data, 228*7fd79137SRobert Mustacchi Dwarf_Signed * fde_element_count, 229*7fd79137SRobert Mustacchi Dwarf_Small * section_ptr, 230*7fd79137SRobert Mustacchi Dwarf_Unsigned section_index, 231*7fd79137SRobert Mustacchi Dwarf_Unsigned section_length, 232*7fd79137SRobert Mustacchi Dwarf_Unsigned cie_id_value, 233*7fd79137SRobert Mustacchi int use_gnu_cie_calc, Dwarf_Error * error) 234*7fd79137SRobert Mustacchi { 235*7fd79137SRobert Mustacchi /* Scans the debug_frame section. */ 236*7fd79137SRobert Mustacchi Dwarf_Small *frame_ptr = section_ptr; 237*7fd79137SRobert Mustacchi Dwarf_Small *frame_ptr_end = section_ptr + section_length; 238*7fd79137SRobert Mustacchi 239*7fd79137SRobert Mustacchi 240*7fd79137SRobert Mustacchi 241*7fd79137SRobert Mustacchi /* 242*7fd79137SRobert Mustacchi New_cie points to the Cie being read, and head_cie_ptr and 243*7fd79137SRobert Mustacchi cur_cie_ptr are used for chaining them up in sequence. 244*7fd79137SRobert Mustacchi In case cie's are reused aggressively we need tail_cie_ptr 245*7fd79137SRobert Mustacchi to add to the chain. If we re-use an early cie 246*7fd79137SRobert Mustacchi later on, that does not mean we chain a new cie to the early one, 247*7fd79137SRobert Mustacchi we always chain it to the tail. */ 248*7fd79137SRobert Mustacchi Dwarf_Cie head_cie_ptr = NULL; 249*7fd79137SRobert Mustacchi Dwarf_Cie cur_cie_ptr = NULL; 250*7fd79137SRobert Mustacchi Dwarf_Cie tail_cie_ptr = NULL; 251*7fd79137SRobert Mustacchi Dwarf_Word cie_count = 0; 252*7fd79137SRobert Mustacchi 253*7fd79137SRobert Mustacchi /* 254*7fd79137SRobert Mustacchi Points to a list of contiguous pointers to Dwarf_Cie structures. 255*7fd79137SRobert Mustacchi */ 256*7fd79137SRobert Mustacchi Dwarf_Cie *cie_list_ptr = 0; 257*7fd79137SRobert Mustacchi 258*7fd79137SRobert Mustacchi 259*7fd79137SRobert Mustacchi /* 260*7fd79137SRobert Mustacchi New_fde points to the Fde being created, and head_fde_ptr and 261*7fd79137SRobert Mustacchi cur_fde_ptr are used to chain them up. */ 262*7fd79137SRobert Mustacchi Dwarf_Fde head_fde_ptr = NULL; 263*7fd79137SRobert Mustacchi Dwarf_Fde cur_fde_ptr = NULL; 264*7fd79137SRobert Mustacchi Dwarf_Word fde_count = 0; 265*7fd79137SRobert Mustacchi 266*7fd79137SRobert Mustacchi /* 267*7fd79137SRobert Mustacchi Points to a list of contiguous pointers to Dwarf_Fde structures. 268*7fd79137SRobert Mustacchi */ 269*7fd79137SRobert Mustacchi Dwarf_Fde *fde_list_ptr = NULL; 270*7fd79137SRobert Mustacchi 271*7fd79137SRobert Mustacchi Dwarf_Word i = 0; 272*7fd79137SRobert Mustacchi int res = DW_DLV_ERROR; 273*7fd79137SRobert Mustacchi 274*7fd79137SRobert Mustacchi if (frame_ptr == 0) { 275*7fd79137SRobert Mustacchi return DW_DLV_NO_ENTRY; 276*7fd79137SRobert Mustacchi } 277*7fd79137SRobert Mustacchi 278*7fd79137SRobert Mustacchi /* We create the fde and cie arrays. Processing each CIE as we come 279*7fd79137SRobert Mustacchi to it or as an FDE refers to it. We cannot process 'late' CIEs 280*7fd79137SRobert Mustacchi late as GNU .eh_frame complexities mean we need the whole CIE 281*7fd79137SRobert Mustacchi before we can process the FDE correctly. */ 282*7fd79137SRobert Mustacchi while (frame_ptr < frame_ptr_end) { 283*7fd79137SRobert Mustacchi 284*7fd79137SRobert Mustacchi struct cie_fde_prefix_s prefix; 285*7fd79137SRobert Mustacchi 286*7fd79137SRobert Mustacchi /* First read in the 'common prefix' to figure out what we are 287*7fd79137SRobert Mustacchi to do with this entry. */ 288*7fd79137SRobert Mustacchi memset(&prefix, 0, sizeof(prefix)); 289*7fd79137SRobert Mustacchi res = dwarf_read_cie_fde_prefix(dbg, 290*7fd79137SRobert Mustacchi frame_ptr, section_ptr, 291*7fd79137SRobert Mustacchi section_index, 292*7fd79137SRobert Mustacchi section_length, &prefix, error); 293*7fd79137SRobert Mustacchi if (res == DW_DLV_ERROR) { 294*7fd79137SRobert Mustacchi dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); 295*7fd79137SRobert Mustacchi return res; 296*7fd79137SRobert Mustacchi } 297*7fd79137SRobert Mustacchi if (res == DW_DLV_NO_ENTRY) 298*7fd79137SRobert Mustacchi break; 299*7fd79137SRobert Mustacchi frame_ptr = prefix.cf_addr_after_prefix; 300*7fd79137SRobert Mustacchi if (frame_ptr >= frame_ptr_end) { 301*7fd79137SRobert Mustacchi dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); 302*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); 303*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 304*7fd79137SRobert Mustacchi 305*7fd79137SRobert Mustacchi } 306*7fd79137SRobert Mustacchi 307*7fd79137SRobert Mustacchi if (prefix.cf_cie_id == cie_id_value) { 308*7fd79137SRobert Mustacchi /* This is a CIE. */ 309*7fd79137SRobert Mustacchi Dwarf_Cie cie_ptr_to_use = 0; 310*7fd79137SRobert Mustacchi 311*7fd79137SRobert Mustacchi int res = dwarf_find_existing_cie_ptr(prefix.cf_start_addr, 312*7fd79137SRobert Mustacchi cur_cie_ptr, 313*7fd79137SRobert Mustacchi &cie_ptr_to_use, 314*7fd79137SRobert Mustacchi head_cie_ptr); 315*7fd79137SRobert Mustacchi 316*7fd79137SRobert Mustacchi if (res == DW_DLV_OK) { 317*7fd79137SRobert Mustacchi cur_cie_ptr = cie_ptr_to_use; 318*7fd79137SRobert Mustacchi /* Ok. Seen already. */ 319*7fd79137SRobert Mustacchi } else if (res == DW_DLV_NO_ENTRY) { 320*7fd79137SRobert Mustacchi /* CIE before its FDE in this case. */ 321*7fd79137SRobert Mustacchi res = dwarf_create_cie_from_after_start(dbg, 322*7fd79137SRobert Mustacchi &prefix, 323*7fd79137SRobert Mustacchi section_ptr, 324*7fd79137SRobert Mustacchi frame_ptr, 325*7fd79137SRobert Mustacchi cie_count, 326*7fd79137SRobert Mustacchi use_gnu_cie_calc, 327*7fd79137SRobert Mustacchi &cie_ptr_to_use, 328*7fd79137SRobert Mustacchi error); 329*7fd79137SRobert Mustacchi /* ASSERT: res==DW_DLV_NO_ENTRY impossible. */ 330*7fd79137SRobert Mustacchi if (res == DW_DLV_ERROR) { 331*7fd79137SRobert Mustacchi dealloc_fde_cie_list_internal(head_fde_ptr, 332*7fd79137SRobert Mustacchi head_cie_ptr); 333*7fd79137SRobert Mustacchi return res; 334*7fd79137SRobert Mustacchi } 335*7fd79137SRobert Mustacchi /* ASSERT res != DW_DLV_NO_ENTRY */ 336*7fd79137SRobert Mustacchi cie_count++; 337*7fd79137SRobert Mustacchi chain_up_cie(cie_ptr_to_use, &head_cie_ptr, 338*7fd79137SRobert Mustacchi &tail_cie_ptr); 339*7fd79137SRobert Mustacchi cur_cie_ptr = tail_cie_ptr; 340*7fd79137SRobert Mustacchi } else { /* res == DW_DLV_ERROR */ 341*7fd79137SRobert Mustacchi 342*7fd79137SRobert Mustacchi dealloc_fde_cie_list_internal(head_fde_ptr, 343*7fd79137SRobert Mustacchi head_cie_ptr); 344*7fd79137SRobert Mustacchi return res; 345*7fd79137SRobert Mustacchi } 346*7fd79137SRobert Mustacchi frame_ptr = cie_ptr_to_use->ci_cie_start + 347*7fd79137SRobert Mustacchi cie_ptr_to_use->ci_length + 348*7fd79137SRobert Mustacchi cie_ptr_to_use->ci_length_size + 349*7fd79137SRobert Mustacchi cie_ptr_to_use->ci_extension_size; 350*7fd79137SRobert Mustacchi continue; 351*7fd79137SRobert Mustacchi } else { 352*7fd79137SRobert Mustacchi /* this is an FDE, Frame Description Entry, see the Dwarf 353*7fd79137SRobert Mustacchi Spec, section 6.4.1 */ 354*7fd79137SRobert Mustacchi int res = DW_DLV_ERROR; 355*7fd79137SRobert Mustacchi Dwarf_Cie cie_ptr_to_use = 0; 356*7fd79137SRobert Mustacchi Dwarf_Fde fde_ptr_to_use = 0; 357*7fd79137SRobert Mustacchi 358*7fd79137SRobert Mustacchi /* Do not call this twice on one prefix, as 359*7fd79137SRobert Mustacchi prefix.cf_cie_id_addr is altered as a side effect. */ 360*7fd79137SRobert Mustacchi Dwarf_Small *cieptr_val = 361*7fd79137SRobert Mustacchi get_cieptr_given_offset(prefix.cf_cie_id, 362*7fd79137SRobert Mustacchi use_gnu_cie_calc, 363*7fd79137SRobert Mustacchi section_ptr, 364*7fd79137SRobert Mustacchi prefix.cf_cie_id_addr); 365*7fd79137SRobert Mustacchi 366*7fd79137SRobert Mustacchi res = dwarf_find_existing_cie_ptr(cieptr_val, 367*7fd79137SRobert Mustacchi cur_cie_ptr, 368*7fd79137SRobert Mustacchi &cie_ptr_to_use, 369*7fd79137SRobert Mustacchi head_cie_ptr); 370*7fd79137SRobert Mustacchi if (res == DW_DLV_OK) { 371*7fd79137SRobert Mustacchi cur_cie_ptr = cie_ptr_to_use; 372*7fd79137SRobert Mustacchi /* Ok. Seen CIE already. */ 373*7fd79137SRobert Mustacchi } else if (res == DW_DLV_NO_ENTRY) { 374*7fd79137SRobert Mustacchi res = dwarf_create_cie_from_start(dbg, 375*7fd79137SRobert Mustacchi cieptr_val, 376*7fd79137SRobert Mustacchi section_ptr, 377*7fd79137SRobert Mustacchi section_index, 378*7fd79137SRobert Mustacchi section_length, 379*7fd79137SRobert Mustacchi frame_ptr_end, 380*7fd79137SRobert Mustacchi cie_id_value, 381*7fd79137SRobert Mustacchi cie_count, 382*7fd79137SRobert Mustacchi use_gnu_cie_calc, 383*7fd79137SRobert Mustacchi &cie_ptr_to_use, 384*7fd79137SRobert Mustacchi error); 385*7fd79137SRobert Mustacchi if (res == DW_DLV_ERROR) { 386*7fd79137SRobert Mustacchi dealloc_fde_cie_list_internal(head_fde_ptr, 387*7fd79137SRobert Mustacchi head_cie_ptr); 388*7fd79137SRobert Mustacchi return res; 389*7fd79137SRobert Mustacchi } else if (res == DW_DLV_NO_ENTRY) { 390*7fd79137SRobert Mustacchi return res; 391*7fd79137SRobert Mustacchi } 392*7fd79137SRobert Mustacchi ++cie_count; 393*7fd79137SRobert Mustacchi chain_up_cie(cie_ptr_to_use, &head_cie_ptr, 394*7fd79137SRobert Mustacchi &tail_cie_ptr); 395*7fd79137SRobert Mustacchi cur_cie_ptr = tail_cie_ptr; 396*7fd79137SRobert Mustacchi 397*7fd79137SRobert Mustacchi } else { 398*7fd79137SRobert Mustacchi /* DW_DLV_ERROR */ 399*7fd79137SRobert Mustacchi return res; 400*7fd79137SRobert Mustacchi } 401*7fd79137SRobert Mustacchi 402*7fd79137SRobert Mustacchi res = dwarf_create_fde_from_after_start(dbg, 403*7fd79137SRobert Mustacchi &prefix, 404*7fd79137SRobert Mustacchi section_ptr, 405*7fd79137SRobert Mustacchi frame_ptr, 406*7fd79137SRobert Mustacchi use_gnu_cie_calc, 407*7fd79137SRobert Mustacchi cie_ptr_to_use, 408*7fd79137SRobert Mustacchi &fde_ptr_to_use, 409*7fd79137SRobert Mustacchi error); 410*7fd79137SRobert Mustacchi if (res == DW_DLV_ERROR) { 411*7fd79137SRobert Mustacchi return res; 412*7fd79137SRobert Mustacchi } 413*7fd79137SRobert Mustacchi chain_up_fde(fde_ptr_to_use, &head_fde_ptr, &cur_fde_ptr); 414*7fd79137SRobert Mustacchi fde_count++; 415*7fd79137SRobert Mustacchi /* ASSERT: DW_DLV_OK. */ 416*7fd79137SRobert Mustacchi frame_ptr = fde_ptr_to_use->fd_fde_start + 417*7fd79137SRobert Mustacchi fde_ptr_to_use->fd_length + 418*7fd79137SRobert Mustacchi fde_ptr_to_use->fd_length_size + 419*7fd79137SRobert Mustacchi fde_ptr_to_use->fd_extension_size; 420*7fd79137SRobert Mustacchi continue; 421*7fd79137SRobert Mustacchi 422*7fd79137SRobert Mustacchi } 423*7fd79137SRobert Mustacchi 424*7fd79137SRobert Mustacchi } 425*7fd79137SRobert Mustacchi 426*7fd79137SRobert Mustacchi /* Now build list of CIEs from the list. If there are no CIEs 427*7fd79137SRobert Mustacchi there should be no FDEs. */ 428*7fd79137SRobert Mustacchi if (cie_count > 0) { 429*7fd79137SRobert Mustacchi cie_list_ptr = (Dwarf_Cie *) 430*7fd79137SRobert Mustacchi _dwarf_get_alloc(dbg, DW_DLA_LIST, cie_count); 431*7fd79137SRobert Mustacchi } else { 432*7fd79137SRobert Mustacchi if(fde_count > 0) { 433*7fd79137SRobert Mustacchi dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); 434*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ORPHAN_FDE); 435*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 436*7fd79137SRobert Mustacchi } 437*7fd79137SRobert Mustacchi dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); 438*7fd79137SRobert Mustacchi return DW_DLV_NO_ENTRY; 439*7fd79137SRobert Mustacchi } 440*7fd79137SRobert Mustacchi if (cie_list_ptr == NULL) { 441*7fd79137SRobert Mustacchi dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr); 442*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 443*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 444*7fd79137SRobert Mustacchi } 445*7fd79137SRobert Mustacchi cur_cie_ptr = head_cie_ptr; 446*7fd79137SRobert Mustacchi for (i = 0; i < cie_count; i++) { 447*7fd79137SRobert Mustacchi *(cie_list_ptr + i) = cur_cie_ptr; 448*7fd79137SRobert Mustacchi cur_cie_ptr = cur_cie_ptr->ci_next; 449*7fd79137SRobert Mustacchi } 450*7fd79137SRobert Mustacchi 451*7fd79137SRobert Mustacchi 452*7fd79137SRobert Mustacchi 453*7fd79137SRobert Mustacchi /* Now build array of FDEs from the list. 454*7fd79137SRobert Mustacchi With orphan CIEs (meaning no FDEs) lets not return DW_DLV_NO_ENTRY */ 455*7fd79137SRobert Mustacchi if (fde_count > 0) { 456*7fd79137SRobert Mustacchi fde_list_ptr = (Dwarf_Fde *) 457*7fd79137SRobert Mustacchi _dwarf_get_alloc(dbg, DW_DLA_LIST, fde_count); 458*7fd79137SRobert Mustacchi } 459*7fd79137SRobert Mustacchi 460*7fd79137SRobert Mustacchi /* It is ok if fde_list_ptr is NULL, we just have no fdes. */ 461*7fd79137SRobert Mustacchi cur_fde_ptr = head_fde_ptr; 462*7fd79137SRobert Mustacchi for (i = 0; i < fde_count; i++) { 463*7fd79137SRobert Mustacchi *(fde_list_ptr + i) = cur_fde_ptr; 464*7fd79137SRobert Mustacchi cur_fde_ptr = cur_fde_ptr->fd_next; 465*7fd79137SRobert Mustacchi } 466*7fd79137SRobert Mustacchi 467*7fd79137SRobert Mustacchi 468*7fd79137SRobert Mustacchi /* Return arguments. */ 469*7fd79137SRobert Mustacchi *cie_data = cie_list_ptr; 470*7fd79137SRobert Mustacchi *cie_element_count = cie_count; 471*7fd79137SRobert Mustacchi 472*7fd79137SRobert Mustacchi *fde_data = fde_list_ptr; 473*7fd79137SRobert Mustacchi *fde_element_count = fde_count; 474*7fd79137SRobert Mustacchi if(use_gnu_cie_calc) { 475*7fd79137SRobert Mustacchi dbg->de_fde_data_eh = fde_list_ptr; 476*7fd79137SRobert Mustacchi dbg->de_fde_count_eh = fde_count; 477*7fd79137SRobert Mustacchi dbg->de_cie_data_eh = cie_list_ptr; 478*7fd79137SRobert Mustacchi dbg->de_cie_count_eh = cie_count; 479*7fd79137SRobert Mustacchi } else { 480*7fd79137SRobert Mustacchi dbg->de_fde_data = fde_list_ptr; 481*7fd79137SRobert Mustacchi dbg->de_fde_count = fde_count; 482*7fd79137SRobert Mustacchi dbg->de_cie_data = cie_list_ptr; 483*7fd79137SRobert Mustacchi dbg->de_cie_count = cie_count; 484*7fd79137SRobert Mustacchi } 485*7fd79137SRobert Mustacchi 486*7fd79137SRobert Mustacchi /* Sort the list by the address so that dwarf_get_fde_at_pc() can 487*7fd79137SRobert Mustacchi binary search this list. */ 488*7fd79137SRobert Mustacchi if(fde_count > 0) { 489*7fd79137SRobert Mustacchi qsort((void *) fde_list_ptr, fde_count, sizeof(Dwarf_Ptr), 490*7fd79137SRobert Mustacchi qsort_compare); 491*7fd79137SRobert Mustacchi } 492*7fd79137SRobert Mustacchi 493*7fd79137SRobert Mustacchi return (DW_DLV_OK); 494*7fd79137SRobert Mustacchi } 495*7fd79137SRobert Mustacchi 496*7fd79137SRobert Mustacchi /* Internal function, not called by consumer code. 497*7fd79137SRobert Mustacchi 'prefix' has accumulated the info up thru the cie-id 498*7fd79137SRobert Mustacchi and now we consume the rest and build a Dwarf_Cie_s structure. 499*7fd79137SRobert Mustacchi */ 500*7fd79137SRobert Mustacchi int 501*7fd79137SRobert Mustacchi dwarf_create_cie_from_after_start(Dwarf_Debug dbg, 502*7fd79137SRobert Mustacchi struct cie_fde_prefix_s *prefix, 503*7fd79137SRobert Mustacchi Dwarf_Small * section_pointer, 504*7fd79137SRobert Mustacchi Dwarf_Small * frame_ptr, 505*7fd79137SRobert Mustacchi Dwarf_Unsigned cie_count, 506*7fd79137SRobert Mustacchi int use_gnu_cie_calc, 507*7fd79137SRobert Mustacchi Dwarf_Cie * cie_ptr_out, 508*7fd79137SRobert Mustacchi Dwarf_Error * error) 509*7fd79137SRobert Mustacchi { 510*7fd79137SRobert Mustacchi Dwarf_Cie new_cie = 0; 511*7fd79137SRobert Mustacchi 512*7fd79137SRobert Mustacchi /* egcs-1.1.2 .eh_frame uses 0 as the distinguishing id. sgi uses 513*7fd79137SRobert Mustacchi -1 (in .debug_frame). .eh_frame not quite identical to 514*7fd79137SRobert Mustacchi .debug_frame */ 515*7fd79137SRobert Mustacchi /* We here default the address size as it is not present 516*7fd79137SRobert Mustacchi in DWARF2 or DWARF3 cie data, below we set it right if 517*7fd79137SRobert Mustacchi it is present. */ 518*7fd79137SRobert Mustacchi Dwarf_Half address_size = dbg->de_pointer_size; 519*7fd79137SRobert Mustacchi Dwarf_Small eh_fde_encoding = 0; 520*7fd79137SRobert Mustacchi Dwarf_Small *augmentation = 0; 521*7fd79137SRobert Mustacchi Dwarf_Half segment_size = 0; 522*7fd79137SRobert Mustacchi Dwarf_Sword data_alignment_factor = -1; 523*7fd79137SRobert Mustacchi Dwarf_Word code_alignment_factor = 4; 524*7fd79137SRobert Mustacchi Dwarf_Unsigned return_address_register = 31; 525*7fd79137SRobert Mustacchi int local_length_size = 0; 526*7fd79137SRobert Mustacchi Dwarf_Word leb128_length = 0; 527*7fd79137SRobert Mustacchi Dwarf_Unsigned cie_aug_data_len = 0; 528*7fd79137SRobert Mustacchi Dwarf_Small *cie_aug_data = 0; 529*7fd79137SRobert Mustacchi Dwarf_Addr gnu_personality_handler_addr = 0; 530*7fd79137SRobert Mustacchi unsigned char gnu_personality_handler_encoding = 0; 531*7fd79137SRobert Mustacchi unsigned char gnu_lsda_encoding = 0; 532*7fd79137SRobert Mustacchi unsigned char gnu_fde_begin_encoding = 0; 533*7fd79137SRobert Mustacchi 534*7fd79137SRobert Mustacchi 535*7fd79137SRobert Mustacchi enum Dwarf_augmentation_type augt = aug_unknown; 536*7fd79137SRobert Mustacchi 537*7fd79137SRobert Mustacchi 538*7fd79137SRobert Mustacchi /* this is a CIE, Common Information Entry: See the dwarf spec, 539*7fd79137SRobert Mustacchi section 6.4.1 */ 540*7fd79137SRobert Mustacchi Dwarf_Small version = *(Dwarf_Small *) frame_ptr; 541*7fd79137SRobert Mustacchi 542*7fd79137SRobert Mustacchi frame_ptr++; 543*7fd79137SRobert Mustacchi if (version != DW_CIE_VERSION && version != DW_CIE_VERSION3 && 544*7fd79137SRobert Mustacchi version != DW_CIE_VERSION4) { 545*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_FRAME_VERSION_BAD); 546*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 547*7fd79137SRobert Mustacchi } 548*7fd79137SRobert Mustacchi 549*7fd79137SRobert Mustacchi augmentation = frame_ptr; 550*7fd79137SRobert Mustacchi frame_ptr = frame_ptr + strlen((char *) frame_ptr) + 1; 551*7fd79137SRobert Mustacchi augt = _dwarf_get_augmentation_type(dbg, 552*7fd79137SRobert Mustacchi augmentation, use_gnu_cie_calc); 553*7fd79137SRobert Mustacchi if (augt == aug_eh) { 554*7fd79137SRobert Mustacchi /* REFERENCED *//* Not used in this instance */ 555*7fd79137SRobert Mustacchi Dwarf_Unsigned exception_table_addr; 556*7fd79137SRobert Mustacchi 557*7fd79137SRobert Mustacchi /* this is per egcs-1.1.2 as on RH 6.0 */ 558*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, exception_table_addr, 559*7fd79137SRobert Mustacchi Dwarf_Unsigned, frame_ptr, local_length_size); 560*7fd79137SRobert Mustacchi frame_ptr += local_length_size; 561*7fd79137SRobert Mustacchi } 562*7fd79137SRobert Mustacchi { 563*7fd79137SRobert Mustacchi Dwarf_Unsigned lreg = 0; 564*7fd79137SRobert Mustacchi unsigned long size = 0; 565*7fd79137SRobert Mustacchi 566*7fd79137SRobert Mustacchi if( version == DW_CIE_VERSION4) { 567*7fd79137SRobert Mustacchi address_size = *((unsigned char *)frame_ptr); 568*7fd79137SRobert Mustacchi ++frame_ptr; 569*7fd79137SRobert Mustacchi segment_size = *((unsigned char *)frame_ptr); 570*7fd79137SRobert Mustacchi ++frame_ptr; 571*7fd79137SRobert Mustacchi } 572*7fd79137SRobert Mustacchi 573*7fd79137SRobert Mustacchi DECODE_LEB128_UWORD(frame_ptr, lreg); 574*7fd79137SRobert Mustacchi code_alignment_factor = (Dwarf_Word) lreg; 575*7fd79137SRobert Mustacchi 576*7fd79137SRobert Mustacchi data_alignment_factor = 577*7fd79137SRobert Mustacchi (Dwarf_Sword) _dwarf_decode_s_leb128(frame_ptr, 578*7fd79137SRobert Mustacchi &leb128_length); 579*7fd79137SRobert Mustacchi 580*7fd79137SRobert Mustacchi frame_ptr = frame_ptr + leb128_length; 581*7fd79137SRobert Mustacchi 582*7fd79137SRobert Mustacchi return_address_register = 583*7fd79137SRobert Mustacchi _dwarf_get_return_address_reg(frame_ptr, version, &size); 584*7fd79137SRobert Mustacchi if (return_address_register > dbg->de_frame_reg_rules_entry_count) { 585*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_CIE_RET_ADDR_REG_ERROR); 586*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 587*7fd79137SRobert Mustacchi } 588*7fd79137SRobert Mustacchi frame_ptr += size; 589*7fd79137SRobert Mustacchi } 590*7fd79137SRobert Mustacchi switch (augt) { 591*7fd79137SRobert Mustacchi case aug_empty_string: 592*7fd79137SRobert Mustacchi break; 593*7fd79137SRobert Mustacchi case aug_irix_mti_v1: 594*7fd79137SRobert Mustacchi break; 595*7fd79137SRobert Mustacchi case aug_irix_exception_table:{ 596*7fd79137SRobert Mustacchi Dwarf_Unsigned lreg = 0; 597*7fd79137SRobert Mustacchi Dwarf_Word length_of_augmented_fields; 598*7fd79137SRobert Mustacchi 599*7fd79137SRobert Mustacchi /* Decode the length of augmented fields. */ 600*7fd79137SRobert Mustacchi DECODE_LEB128_UWORD(frame_ptr, lreg); 601*7fd79137SRobert Mustacchi length_of_augmented_fields = (Dwarf_Word) lreg; 602*7fd79137SRobert Mustacchi 603*7fd79137SRobert Mustacchi 604*7fd79137SRobert Mustacchi /* set the frame_ptr to point at the instruction start. */ 605*7fd79137SRobert Mustacchi frame_ptr += length_of_augmented_fields; 606*7fd79137SRobert Mustacchi } 607*7fd79137SRobert Mustacchi break; 608*7fd79137SRobert Mustacchi 609*7fd79137SRobert Mustacchi case aug_eh:{ 610*7fd79137SRobert Mustacchi 611*7fd79137SRobert Mustacchi int err = 0; 612*7fd79137SRobert Mustacchi unsigned long increment = 0; 613*7fd79137SRobert Mustacchi 614*7fd79137SRobert Mustacchi if (!use_gnu_cie_calc) { 615*7fd79137SRobert Mustacchi /* This should be impossible. */ 616*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, 617*7fd79137SRobert Mustacchi DW_DLE_FRAME_AUGMENTATION_UNKNOWN); 618*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 619*7fd79137SRobert Mustacchi } 620*7fd79137SRobert Mustacchi 621*7fd79137SRobert Mustacchi err = get_gcc_eh_augmentation(dbg, frame_ptr, &increment, 622*7fd79137SRobert Mustacchi augt, 623*7fd79137SRobert Mustacchi prefix->cf_section_ptr, 624*7fd79137SRobert Mustacchi &eh_fde_encoding, 625*7fd79137SRobert Mustacchi (char *) augmentation); 626*7fd79137SRobert Mustacchi if (err == DW_DLV_ERROR) { 627*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, 628*7fd79137SRobert Mustacchi DW_DLE_FRAME_AUGMENTATION_UNKNOWN); 629*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 630*7fd79137SRobert Mustacchi } 631*7fd79137SRobert Mustacchi frame_ptr += increment; 632*7fd79137SRobert Mustacchi break; 633*7fd79137SRobert Mustacchi } 634*7fd79137SRobert Mustacchi case aug_gcc_eh_z:{ 635*7fd79137SRobert Mustacchi /* Here we have Augmentation Data Length (uleb128) followed 636*7fd79137SRobert Mustacchi by Augmentation Data bytes. */ 637*7fd79137SRobert Mustacchi int res = DW_DLV_ERROR; 638*7fd79137SRobert Mustacchi Dwarf_Unsigned adlen = 0; 639*7fd79137SRobert Mustacchi 640*7fd79137SRobert Mustacchi DECODE_LEB128_UWORD(frame_ptr, adlen); 641*7fd79137SRobert Mustacchi cie_aug_data_len = adlen; 642*7fd79137SRobert Mustacchi cie_aug_data = frame_ptr; 643*7fd79137SRobert Mustacchi res = gnu_aug_encodings(dbg, 644*7fd79137SRobert Mustacchi (char *) augmentation, 645*7fd79137SRobert Mustacchi cie_aug_data, 646*7fd79137SRobert Mustacchi cie_aug_data_len, 647*7fd79137SRobert Mustacchi address_size, 648*7fd79137SRobert Mustacchi &gnu_personality_handler_encoding, 649*7fd79137SRobert Mustacchi &gnu_lsda_encoding, 650*7fd79137SRobert Mustacchi &gnu_fde_begin_encoding, 651*7fd79137SRobert Mustacchi &gnu_personality_handler_addr); 652*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 653*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, 654*7fd79137SRobert Mustacchi DW_DLE_FRAME_AUGMENTATION_UNKNOWN); 655*7fd79137SRobert Mustacchi return res; 656*7fd79137SRobert Mustacchi } 657*7fd79137SRobert Mustacchi 658*7fd79137SRobert Mustacchi 659*7fd79137SRobert Mustacchi frame_ptr += adlen; 660*7fd79137SRobert Mustacchi break; 661*7fd79137SRobert Mustacchi } 662*7fd79137SRobert Mustacchi case aug_armcc: 663*7fd79137SRobert Mustacchi break; 664*7fd79137SRobert Mustacchi default:{ 665*7fd79137SRobert Mustacchi /* We do not understand the augmentation string. No 666*7fd79137SRobert Mustacchi assumption can be made about any fields other than what 667*7fd79137SRobert Mustacchi we have already read. */ 668*7fd79137SRobert Mustacchi frame_ptr = prefix->cf_start_addr + 669*7fd79137SRobert Mustacchi prefix->cf_length + prefix->cf_local_length_size 670*7fd79137SRobert Mustacchi + prefix->cf_local_extension_size; 671*7fd79137SRobert Mustacchi /* FIX -- What are the values of data_alignment_factor, 672*7fd79137SRobert Mustacchi code_alignement_factor, return_address_register and 673*7fd79137SRobert Mustacchi instruction start? They were clearly uninitalized in the 674*7fd79137SRobert Mustacchi previous version and I am leaving them the same way. */ 675*7fd79137SRobert Mustacchi break; 676*7fd79137SRobert Mustacchi } 677*7fd79137SRobert Mustacchi } /* End switch on augmentation type. */ 678*7fd79137SRobert Mustacchi 679*7fd79137SRobert Mustacchi new_cie = (Dwarf_Cie) _dwarf_get_alloc(dbg, DW_DLA_CIE, 1); 680*7fd79137SRobert Mustacchi if (new_cie == NULL) { 681*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 682*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 683*7fd79137SRobert Mustacchi } 684*7fd79137SRobert Mustacchi 685*7fd79137SRobert Mustacchi new_cie->ci_cie_version_number = version; 686*7fd79137SRobert Mustacchi new_cie->ci_initial_table = NULL; 687*7fd79137SRobert Mustacchi new_cie->ci_length = (Dwarf_Word) prefix->cf_length; 688*7fd79137SRobert Mustacchi new_cie->ci_length_size = prefix->cf_local_length_size; 689*7fd79137SRobert Mustacchi new_cie->ci_extension_size = prefix->cf_local_extension_size; 690*7fd79137SRobert Mustacchi new_cie->ci_augmentation = (char *) augmentation; 691*7fd79137SRobert Mustacchi 692*7fd79137SRobert Mustacchi new_cie->ci_data_alignment_factor = 693*7fd79137SRobert Mustacchi (Dwarf_Sbyte) data_alignment_factor; 694*7fd79137SRobert Mustacchi new_cie->ci_code_alignment_factor = 695*7fd79137SRobert Mustacchi (Dwarf_Small) code_alignment_factor; 696*7fd79137SRobert Mustacchi new_cie->ci_return_address_register = return_address_register; 697*7fd79137SRobert Mustacchi new_cie->ci_cie_start = prefix->cf_start_addr; 698*7fd79137SRobert Mustacchi new_cie->ci_cie_instr_start = frame_ptr; 699*7fd79137SRobert Mustacchi new_cie->ci_dbg = dbg; 700*7fd79137SRobert Mustacchi new_cie->ci_augmentation_type = augt; 701*7fd79137SRobert Mustacchi new_cie->ci_gnu_eh_augmentation_len = cie_aug_data_len; 702*7fd79137SRobert Mustacchi new_cie->ci_gnu_eh_augmentation_bytes = cie_aug_data; 703*7fd79137SRobert Mustacchi new_cie->ci_gnu_personality_handler_encoding = 704*7fd79137SRobert Mustacchi gnu_personality_handler_encoding; 705*7fd79137SRobert Mustacchi new_cie->ci_gnu_personality_handler_addr = 706*7fd79137SRobert Mustacchi gnu_personality_handler_addr; 707*7fd79137SRobert Mustacchi new_cie->ci_gnu_lsda_encoding = gnu_lsda_encoding; 708*7fd79137SRobert Mustacchi new_cie->ci_gnu_fde_begin_encoding = gnu_fde_begin_encoding; 709*7fd79137SRobert Mustacchi 710*7fd79137SRobert Mustacchi new_cie->ci_index = cie_count; 711*7fd79137SRobert Mustacchi new_cie->ci_section_ptr = prefix->cf_section_ptr; 712*7fd79137SRobert Mustacchi /* The Following new in DWARF4 */ 713*7fd79137SRobert Mustacchi new_cie->ci_address_size = address_size; 714*7fd79137SRobert Mustacchi new_cie->ci_segment_size = segment_size; 715*7fd79137SRobert Mustacchi validate_length(dbg,new_cie,new_cie->ci_length, 716*7fd79137SRobert Mustacchi new_cie->ci_length_size, new_cie->ci_extension_size, 717*7fd79137SRobert Mustacchi new_cie->ci_section_ptr, 718*7fd79137SRobert Mustacchi new_cie->ci_cie_start,"cie"); 719*7fd79137SRobert Mustacchi 720*7fd79137SRobert Mustacchi *cie_ptr_out = new_cie; 721*7fd79137SRobert Mustacchi return DW_DLV_OK; 722*7fd79137SRobert Mustacchi 723*7fd79137SRobert Mustacchi } 724*7fd79137SRobert Mustacchi 725*7fd79137SRobert Mustacchi 726*7fd79137SRobert Mustacchi /* Internal function, not called by consumer code. 727*7fd79137SRobert Mustacchi 'prefix' has accumulated the info up thru the cie-id 728*7fd79137SRobert Mustacchi and now we consume the rest and build a Dwarf_Fde_s structure. 729*7fd79137SRobert Mustacchi */ 730*7fd79137SRobert Mustacchi 731*7fd79137SRobert Mustacchi int 732*7fd79137SRobert Mustacchi dwarf_create_fde_from_after_start(Dwarf_Debug dbg, 733*7fd79137SRobert Mustacchi struct cie_fde_prefix_s *prefix, 734*7fd79137SRobert Mustacchi Dwarf_Small * section_pointer, 735*7fd79137SRobert Mustacchi Dwarf_Small * frame_ptr, 736*7fd79137SRobert Mustacchi int use_gnu_cie_calc, 737*7fd79137SRobert Mustacchi Dwarf_Cie cie_ptr_in, 738*7fd79137SRobert Mustacchi Dwarf_Fde * fde_ptr_out, 739*7fd79137SRobert Mustacchi Dwarf_Error * error) 740*7fd79137SRobert Mustacchi { 741*7fd79137SRobert Mustacchi Dwarf_Fde new_fde = 0; 742*7fd79137SRobert Mustacchi Dwarf_Cie cieptr = cie_ptr_in; 743*7fd79137SRobert Mustacchi Dwarf_Small *saved_frame_ptr = 0; 744*7fd79137SRobert Mustacchi 745*7fd79137SRobert Mustacchi Dwarf_Small *initloc = frame_ptr; 746*7fd79137SRobert Mustacchi Dwarf_Signed offset_into_exception_tables 747*7fd79137SRobert Mustacchi /* must be min dwarf_sfixed in size */ 748*7fd79137SRobert Mustacchi = (Dwarf_Signed) DW_DLX_NO_EH_OFFSET; 749*7fd79137SRobert Mustacchi Dwarf_Small *fde_aug_data = 0; 750*7fd79137SRobert Mustacchi Dwarf_Unsigned fde_aug_data_len = 0; 751*7fd79137SRobert Mustacchi Dwarf_Addr cie_base_offset = prefix->cf_cie_id; 752*7fd79137SRobert Mustacchi Dwarf_Addr initial_location = 0; /* must be min de_pointer_size 753*7fd79137SRobert Mustacchi bytes in size */ 754*7fd79137SRobert Mustacchi Dwarf_Addr address_range = 0; /* must be min de_pointer_size 755*7fd79137SRobert Mustacchi bytes in size */ 756*7fd79137SRobert Mustacchi Dwarf_Half address_size = cie_ptr_in->ci_address_size; 757*7fd79137SRobert Mustacchi 758*7fd79137SRobert Mustacchi enum Dwarf_augmentation_type augt = cieptr->ci_augmentation_type; 759*7fd79137SRobert Mustacchi 760*7fd79137SRobert Mustacchi if (augt == aug_gcc_eh_z) { 761*7fd79137SRobert Mustacchi /* If z augmentation this is eh_frame, and initial_location and 762*7fd79137SRobert Mustacchi address_range in the FDE are read according to the CIE 763*7fd79137SRobert Mustacchi augmentation string instructions. */ 764*7fd79137SRobert Mustacchi 765*7fd79137SRobert Mustacchi { 766*7fd79137SRobert Mustacchi Dwarf_Small *fp_updated = 0; 767*7fd79137SRobert Mustacchi int res = read_encoded_ptr(dbg, 768*7fd79137SRobert Mustacchi section_pointer, 769*7fd79137SRobert Mustacchi frame_ptr, 770*7fd79137SRobert Mustacchi cieptr-> ci_gnu_fde_begin_encoding, 771*7fd79137SRobert Mustacchi address_size, 772*7fd79137SRobert Mustacchi &initial_location, 773*7fd79137SRobert Mustacchi &fp_updated); 774*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 775*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, 776*7fd79137SRobert Mustacchi DW_DLE_FRAME_AUGMENTATION_UNKNOWN); 777*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 778*7fd79137SRobert Mustacchi } 779*7fd79137SRobert Mustacchi frame_ptr = fp_updated; 780*7fd79137SRobert Mustacchi /* For the address-range it makes no sense to be 781*7fd79137SRobert Mustacchi pc-relative, so we turn it off with a section_pointer of 782*7fd79137SRobert Mustacchi NULL. Masking off DW_EH_PE_pcrel from the 783*7fd79137SRobert Mustacchi ci_gnu_fde_begin_encoding in this call would also work 784*7fd79137SRobert Mustacchi to turn off DW_EH_PE_pcrel. */ 785*7fd79137SRobert Mustacchi res = read_encoded_ptr(dbg, (Dwarf_Small *) NULL, 786*7fd79137SRobert Mustacchi frame_ptr, 787*7fd79137SRobert Mustacchi cieptr->ci_gnu_fde_begin_encoding, 788*7fd79137SRobert Mustacchi address_size, 789*7fd79137SRobert Mustacchi &address_range, &fp_updated); 790*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 791*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, 792*7fd79137SRobert Mustacchi DW_DLE_FRAME_AUGMENTATION_UNKNOWN); 793*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 794*7fd79137SRobert Mustacchi } 795*7fd79137SRobert Mustacchi frame_ptr = fp_updated; 796*7fd79137SRobert Mustacchi } 797*7fd79137SRobert Mustacchi { 798*7fd79137SRobert Mustacchi Dwarf_Unsigned adlen = 0; 799*7fd79137SRobert Mustacchi 800*7fd79137SRobert Mustacchi DECODE_LEB128_UWORD(frame_ptr, adlen); 801*7fd79137SRobert Mustacchi fde_aug_data_len = adlen; 802*7fd79137SRobert Mustacchi fde_aug_data = frame_ptr; 803*7fd79137SRobert Mustacchi frame_ptr += adlen; 804*7fd79137SRobert Mustacchi } 805*7fd79137SRobert Mustacchi 806*7fd79137SRobert Mustacchi } else { 807*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, initial_location, Dwarf_Addr, 808*7fd79137SRobert Mustacchi frame_ptr, address_size); 809*7fd79137SRobert Mustacchi frame_ptr += address_size; 810*7fd79137SRobert Mustacchi 811*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, address_range, Dwarf_Addr, 812*7fd79137SRobert Mustacchi frame_ptr, address_size); 813*7fd79137SRobert Mustacchi frame_ptr += address_size; 814*7fd79137SRobert Mustacchi } 815*7fd79137SRobert Mustacchi 816*7fd79137SRobert Mustacchi 817*7fd79137SRobert Mustacchi 818*7fd79137SRobert Mustacchi 819*7fd79137SRobert Mustacchi 820*7fd79137SRobert Mustacchi switch (augt) { 821*7fd79137SRobert Mustacchi case aug_irix_mti_v1: 822*7fd79137SRobert Mustacchi case aug_empty_string: 823*7fd79137SRobert Mustacchi break; 824*7fd79137SRobert Mustacchi case aug_irix_exception_table:{ 825*7fd79137SRobert Mustacchi Dwarf_Unsigned lreg = 0; 826*7fd79137SRobert Mustacchi Dwarf_Word length_of_augmented_fields = 0; 827*7fd79137SRobert Mustacchi 828*7fd79137SRobert Mustacchi DECODE_LEB128_UWORD(frame_ptr, lreg); 829*7fd79137SRobert Mustacchi length_of_augmented_fields = (Dwarf_Word) lreg; 830*7fd79137SRobert Mustacchi 831*7fd79137SRobert Mustacchi saved_frame_ptr = frame_ptr; 832*7fd79137SRobert Mustacchi /* The first word is an offset into exception tables. 833*7fd79137SRobert Mustacchi Defined as a 32bit offset even for CC -64. */ 834*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset_into_exception_tables, 835*7fd79137SRobert Mustacchi Dwarf_Addr, frame_ptr, sizeof(Dwarf_sfixed)); 836*7fd79137SRobert Mustacchi SIGN_EXTEND(offset_into_exception_tables, 837*7fd79137SRobert Mustacchi sizeof(Dwarf_sfixed)); 838*7fd79137SRobert Mustacchi frame_ptr = saved_frame_ptr + length_of_augmented_fields; 839*7fd79137SRobert Mustacchi } 840*7fd79137SRobert Mustacchi break; 841*7fd79137SRobert Mustacchi case aug_eh:{ 842*7fd79137SRobert Mustacchi Dwarf_Unsigned eh_table_value = 0; 843*7fd79137SRobert Mustacchi 844*7fd79137SRobert Mustacchi if (!use_gnu_cie_calc) { 845*7fd79137SRobert Mustacchi /* This should be impossible. */ 846*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, 847*7fd79137SRobert Mustacchi DW_DLE_FRAME_AUGMENTATION_UNKNOWN); 848*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 849*7fd79137SRobert Mustacchi } 850*7fd79137SRobert Mustacchi 851*7fd79137SRobert Mustacchi /* gnu eh fde case. we do not need to do anything */ 852*7fd79137SRobert Mustacchi /*REFERENCED*/ /* Not used in this instance of the 853*7fd79137SRobert Mustacchi macro */ 854*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, eh_table_value, 855*7fd79137SRobert Mustacchi Dwarf_Unsigned, frame_ptr, 856*7fd79137SRobert Mustacchi address_size); 857*7fd79137SRobert Mustacchi frame_ptr += address_size; 858*7fd79137SRobert Mustacchi } 859*7fd79137SRobert Mustacchi break; 860*7fd79137SRobert Mustacchi 861*7fd79137SRobert Mustacchi case aug_gcc_eh_z:{ 862*7fd79137SRobert Mustacchi /* The Augmentation Data Length is here, followed by the 863*7fd79137SRobert Mustacchi Augmentation Data bytes themselves. */ 864*7fd79137SRobert Mustacchi } 865*7fd79137SRobert Mustacchi break; 866*7fd79137SRobert Mustacchi case aug_armcc: 867*7fd79137SRobert Mustacchi break; 868*7fd79137SRobert Mustacchi case aug_past_last: 869*7fd79137SRobert Mustacchi break; 870*7fd79137SRobert Mustacchi case aug_unknown: 871*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); 872*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 873*7fd79137SRobert Mustacchi } /* End switch on augmentation type */ 874*7fd79137SRobert Mustacchi new_fde = (Dwarf_Fde) _dwarf_get_alloc(dbg, DW_DLA_FDE, 1); 875*7fd79137SRobert Mustacchi if (new_fde == NULL) { 876*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 877*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 878*7fd79137SRobert Mustacchi } 879*7fd79137SRobert Mustacchi 880*7fd79137SRobert Mustacchi new_fde->fd_length = prefix->cf_length; 881*7fd79137SRobert Mustacchi new_fde->fd_length_size = prefix->cf_local_length_size; 882*7fd79137SRobert Mustacchi new_fde->fd_extension_size = prefix->cf_local_extension_size; 883*7fd79137SRobert Mustacchi new_fde->fd_is_eh = use_gnu_cie_calc; 884*7fd79137SRobert Mustacchi new_fde->fd_cie_offset = cie_base_offset; 885*7fd79137SRobert Mustacchi new_fde->fd_cie_index = cieptr->ci_index; 886*7fd79137SRobert Mustacchi new_fde->fd_cie = cieptr; 887*7fd79137SRobert Mustacchi new_fde->fd_initial_location = initial_location; 888*7fd79137SRobert Mustacchi new_fde->fd_initial_loc_pos = initloc; 889*7fd79137SRobert Mustacchi new_fde->fd_address_range = address_range; 890*7fd79137SRobert Mustacchi new_fde->fd_fde_start = prefix->cf_start_addr; 891*7fd79137SRobert Mustacchi new_fde->fd_fde_instr_start = frame_ptr; 892*7fd79137SRobert Mustacchi new_fde->fd_dbg = dbg; 893*7fd79137SRobert Mustacchi new_fde->fd_offset_into_exception_tables = 894*7fd79137SRobert Mustacchi offset_into_exception_tables; 895*7fd79137SRobert Mustacchi 896*7fd79137SRobert Mustacchi new_fde->fd_section_ptr = prefix->cf_section_ptr; 897*7fd79137SRobert Mustacchi new_fde->fd_section_index = prefix->cf_section_index; 898*7fd79137SRobert Mustacchi new_fde->fd_section_length = prefix->cf_section_length; 899*7fd79137SRobert Mustacchi 900*7fd79137SRobert Mustacchi new_fde->fd_gnu_eh_augmentation_bytes = fde_aug_data; 901*7fd79137SRobert Mustacchi new_fde->fd_gnu_eh_augmentation_len = fde_aug_data_len; 902*7fd79137SRobert Mustacchi validate_length(dbg,cieptr,new_fde->fd_length, 903*7fd79137SRobert Mustacchi new_fde->fd_length_size, new_fde->fd_extension_size, 904*7fd79137SRobert Mustacchi new_fde->fd_section_ptr,new_fde->fd_fde_start,"fde"); 905*7fd79137SRobert Mustacchi 906*7fd79137SRobert Mustacchi 907*7fd79137SRobert Mustacchi *fde_ptr_out = new_fde; 908*7fd79137SRobert Mustacchi return DW_DLV_OK; 909*7fd79137SRobert Mustacchi } 910*7fd79137SRobert Mustacchi 911*7fd79137SRobert Mustacchi /* called by qsort to compare FDE entries. 912*7fd79137SRobert Mustacchi Consumer code expects the array of FDE pointers to be in address order. 913*7fd79137SRobert Mustacchi */ 914*7fd79137SRobert Mustacchi static int 915*7fd79137SRobert Mustacchi qsort_compare(const void *elem1, const void *elem2) 916*7fd79137SRobert Mustacchi { 917*7fd79137SRobert Mustacchi Dwarf_Fde fde1 = *(Dwarf_Fde *) elem1; 918*7fd79137SRobert Mustacchi Dwarf_Fde fde2 = *(Dwarf_Fde *) elem2; 919*7fd79137SRobert Mustacchi Dwarf_Addr addr1 = fde1->fd_initial_location; 920*7fd79137SRobert Mustacchi Dwarf_Addr addr2 = fde2->fd_initial_location; 921*7fd79137SRobert Mustacchi 922*7fd79137SRobert Mustacchi if (addr1 < addr2) { 923*7fd79137SRobert Mustacchi return -1; 924*7fd79137SRobert Mustacchi } else if (addr1 > addr2) { 925*7fd79137SRobert Mustacchi return 1; 926*7fd79137SRobert Mustacchi } 927*7fd79137SRobert Mustacchi return 0; 928*7fd79137SRobert Mustacchi } 929*7fd79137SRobert Mustacchi 930*7fd79137SRobert Mustacchi 931*7fd79137SRobert Mustacchi /* Read in the common cie/fde prefix, including reading 932*7fd79137SRobert Mustacchi * the cie-value which shows which this is: cie or fde. 933*7fd79137SRobert Mustacchi * */ 934*7fd79137SRobert Mustacchi int 935*7fd79137SRobert Mustacchi dwarf_read_cie_fde_prefix(Dwarf_Debug dbg, 936*7fd79137SRobert Mustacchi Dwarf_Small * frame_ptr_in, 937*7fd79137SRobert Mustacchi Dwarf_Small * section_ptr_in, 938*7fd79137SRobert Mustacchi Dwarf_Unsigned section_index_in, 939*7fd79137SRobert Mustacchi Dwarf_Unsigned section_length_in, 940*7fd79137SRobert Mustacchi struct cie_fde_prefix_s *data_out, 941*7fd79137SRobert Mustacchi Dwarf_Error * error) 942*7fd79137SRobert Mustacchi { 943*7fd79137SRobert Mustacchi Dwarf_Unsigned length = 0; 944*7fd79137SRobert Mustacchi int local_length_size = 0; 945*7fd79137SRobert Mustacchi int local_extension_size = 0; 946*7fd79137SRobert Mustacchi Dwarf_Small *frame_ptr = frame_ptr_in; 947*7fd79137SRobert Mustacchi Dwarf_Small *cie_ptr_addr = 0; 948*7fd79137SRobert Mustacchi Dwarf_Unsigned cie_id = 0; 949*7fd79137SRobert Mustacchi 950*7fd79137SRobert Mustacchi /* READ_AREA_LENGTH updates frame_ptr for consumed bytes */ 951*7fd79137SRobert Mustacchi READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned, 952*7fd79137SRobert Mustacchi frame_ptr, local_length_size, 953*7fd79137SRobert Mustacchi local_extension_size); 954*7fd79137SRobert Mustacchi 955*7fd79137SRobert Mustacchi if (length == 0) { 956*7fd79137SRobert Mustacchi /* nul bytes at end of section, seen at end of egcs eh_frame 957*7fd79137SRobert Mustacchi sections (in a.out). Take this as meaning no more CIE/FDE 958*7fd79137SRobert Mustacchi data. We should be very close to end of section. */ 959*7fd79137SRobert Mustacchi return DW_DLV_NO_ENTRY; 960*7fd79137SRobert Mustacchi } 961*7fd79137SRobert Mustacchi 962*7fd79137SRobert Mustacchi cie_ptr_addr = frame_ptr; 963*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, cie_id, Dwarf_Unsigned, 964*7fd79137SRobert Mustacchi frame_ptr, local_length_size); 965*7fd79137SRobert Mustacchi SIGN_EXTEND(cie_id, local_length_size); 966*7fd79137SRobert Mustacchi frame_ptr += local_length_size; 967*7fd79137SRobert Mustacchi 968*7fd79137SRobert Mustacchi data_out->cf_start_addr = frame_ptr_in; 969*7fd79137SRobert Mustacchi data_out->cf_addr_after_prefix = frame_ptr; 970*7fd79137SRobert Mustacchi 971*7fd79137SRobert Mustacchi data_out->cf_length = length; 972*7fd79137SRobert Mustacchi data_out->cf_local_length_size = local_length_size; 973*7fd79137SRobert Mustacchi data_out->cf_local_extension_size = local_extension_size; 974*7fd79137SRobert Mustacchi data_out->cf_cie_id = cie_id; 975*7fd79137SRobert Mustacchi data_out->cf_cie_id_addr = cie_ptr_addr; 976*7fd79137SRobert Mustacchi data_out->cf_section_ptr = section_ptr_in; 977*7fd79137SRobert Mustacchi data_out->cf_section_index = section_index_in; 978*7fd79137SRobert Mustacchi data_out->cf_section_length = section_length_in; 979*7fd79137SRobert Mustacchi return DW_DLV_OK; 980*7fd79137SRobert Mustacchi } 981*7fd79137SRobert Mustacchi 982*7fd79137SRobert Mustacchi /* On various errors previously-allocated CIEs and FDEs 983*7fd79137SRobert Mustacchi must be cleaned up. 984*7fd79137SRobert Mustacchi This helps avoid leaks in case of errors. 985*7fd79137SRobert Mustacchi */ 986*7fd79137SRobert Mustacchi static void 987*7fd79137SRobert Mustacchi dealloc_fde_cie_list_internal(Dwarf_Fde head_fde_ptr, 988*7fd79137SRobert Mustacchi Dwarf_Cie head_cie_ptr) 989*7fd79137SRobert Mustacchi { 990*7fd79137SRobert Mustacchi Dwarf_Fde curfde = 0; 991*7fd79137SRobert Mustacchi Dwarf_Cie curcie = 0; 992*7fd79137SRobert Mustacchi Dwarf_Fde nextfde = 0; 993*7fd79137SRobert Mustacchi Dwarf_Cie nextcie = 0; 994*7fd79137SRobert Mustacchi 995*7fd79137SRobert Mustacchi for (curfde = head_fde_ptr; curfde; curfde = nextfde) { 996*7fd79137SRobert Mustacchi nextfde = curfde->fd_next; 997*7fd79137SRobert Mustacchi dwarf_dealloc(curfde->fd_dbg, curfde, DW_DLA_FDE); 998*7fd79137SRobert Mustacchi } 999*7fd79137SRobert Mustacchi for (curcie = head_cie_ptr; curcie; curcie = nextcie) { 1000*7fd79137SRobert Mustacchi Dwarf_Frame frame = curcie->ci_initial_table; 1001*7fd79137SRobert Mustacchi 1002*7fd79137SRobert Mustacchi nextcie = curcie->ci_next; 1003*7fd79137SRobert Mustacchi if (frame) 1004*7fd79137SRobert Mustacchi dwarf_dealloc(curcie->ci_dbg, frame, DW_DLA_FRAME); 1005*7fd79137SRobert Mustacchi dwarf_dealloc(curcie->ci_dbg, curcie, DW_DLA_CIE); 1006*7fd79137SRobert Mustacchi } 1007*7fd79137SRobert Mustacchi } 1008*7fd79137SRobert Mustacchi 1009*7fd79137SRobert Mustacchi /* Find the cie whose id value is given: the id 1010*7fd79137SRobert Mustacchi * value is, per DWARF2/3, an offset in the section. 1011*7fd79137SRobert Mustacchi * For .debug_frame, zero is a legal offset. For 1012*7fd79137SRobert Mustacchi * GNU .eh_frame it is not a legal offset. 1013*7fd79137SRobert Mustacchi * 'cie_ptr' is a pointer into our section, not an offset. */ 1014*7fd79137SRobert Mustacchi static int 1015*7fd79137SRobert Mustacchi dwarf_find_existing_cie_ptr(Dwarf_Small * cie_ptr, 1016*7fd79137SRobert Mustacchi Dwarf_Cie cur_cie_ptr, 1017*7fd79137SRobert Mustacchi Dwarf_Cie * cie_ptr_to_use_out, 1018*7fd79137SRobert Mustacchi Dwarf_Cie head_cie_ptr) 1019*7fd79137SRobert Mustacchi { 1020*7fd79137SRobert Mustacchi Dwarf_Cie next = 0; 1021*7fd79137SRobert Mustacchi 1022*7fd79137SRobert Mustacchi if (cur_cie_ptr && cie_ptr == cur_cie_ptr->ci_cie_start) { 1023*7fd79137SRobert Mustacchi /* Usually, we use the same cie again and again. */ 1024*7fd79137SRobert Mustacchi *cie_ptr_to_use_out = cur_cie_ptr; 1025*7fd79137SRobert Mustacchi return DW_DLV_OK; 1026*7fd79137SRobert Mustacchi } 1027*7fd79137SRobert Mustacchi for (next = head_cie_ptr; next; next = next->ci_next) { 1028*7fd79137SRobert Mustacchi if (cie_ptr == next->ci_cie_start) { 1029*7fd79137SRobert Mustacchi *cie_ptr_to_use_out = next; 1030*7fd79137SRobert Mustacchi return DW_DLV_OK; 1031*7fd79137SRobert Mustacchi } 1032*7fd79137SRobert Mustacchi } 1033*7fd79137SRobert Mustacchi return DW_DLV_NO_ENTRY; 1034*7fd79137SRobert Mustacchi } 1035*7fd79137SRobert Mustacchi 1036*7fd79137SRobert Mustacchi 1037*7fd79137SRobert Mustacchi /* We have a valid cie_ptr_val that has not been 1038*7fd79137SRobert Mustacchi * turned into an internal Cie yet. Do so now. 1039*7fd79137SRobert Mustacchi * Returns DW_DLV_OK or DW_DLV_ERROR, never 1040*7fd79137SRobert Mustacchi * DW_DLV_NO_ENTRY. 1041*7fd79137SRobert Mustacchi 1042*7fd79137SRobert Mustacchi 'section_ptr' - Points to first byte of section data. 1043*7fd79137SRobert Mustacchi 'section_length' - Length of the section, in bytes. 1044*7fd79137SRobert Mustacchi 'frame_ptr_end' - Points 1-past last byte of section data. 1045*7fd79137SRobert Mustacchi * */ 1046*7fd79137SRobert Mustacchi static int 1047*7fd79137SRobert Mustacchi dwarf_create_cie_from_start(Dwarf_Debug dbg, 1048*7fd79137SRobert Mustacchi Dwarf_Small * cie_ptr_val, 1049*7fd79137SRobert Mustacchi Dwarf_Small * section_ptr, 1050*7fd79137SRobert Mustacchi Dwarf_Unsigned section_index, 1051*7fd79137SRobert Mustacchi Dwarf_Unsigned section_length, 1052*7fd79137SRobert Mustacchi Dwarf_Small * frame_ptr_end, 1053*7fd79137SRobert Mustacchi Dwarf_Unsigned cie_id_value, 1054*7fd79137SRobert Mustacchi Dwarf_Unsigned cie_count, 1055*7fd79137SRobert Mustacchi int use_gnu_cie_calc, 1056*7fd79137SRobert Mustacchi Dwarf_Cie * cie_ptr_to_use_out, 1057*7fd79137SRobert Mustacchi Dwarf_Error * error) 1058*7fd79137SRobert Mustacchi { 1059*7fd79137SRobert Mustacchi struct cie_fde_prefix_s prefix; 1060*7fd79137SRobert Mustacchi int res = DW_DLV_ERROR; 1061*7fd79137SRobert Mustacchi Dwarf_Small *frame_ptr = cie_ptr_val; 1062*7fd79137SRobert Mustacchi 1063*7fd79137SRobert Mustacchi if (frame_ptr < section_ptr || frame_ptr > frame_ptr_end) { 1064*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); 1065*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 1066*7fd79137SRobert Mustacchi } 1067*7fd79137SRobert Mustacchi /* First read in the 'common prefix' to figure out what * we are to 1068*7fd79137SRobert Mustacchi do with this entry. If it is not a cie * we are in big trouble. */ 1069*7fd79137SRobert Mustacchi memset(&prefix, 0, sizeof(prefix)); 1070*7fd79137SRobert Mustacchi res = dwarf_read_cie_fde_prefix(dbg, frame_ptr, section_ptr, 1071*7fd79137SRobert Mustacchi section_index, section_length, 1072*7fd79137SRobert Mustacchi &prefix, error); 1073*7fd79137SRobert Mustacchi if (res == DW_DLV_ERROR) { 1074*7fd79137SRobert Mustacchi return res; 1075*7fd79137SRobert Mustacchi } 1076*7fd79137SRobert Mustacchi if (res == DW_DLV_NO_ENTRY) { 1077*7fd79137SRobert Mustacchi /* error. */ 1078*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_FRAME_CIE_DECODE_ERROR); 1079*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 1080*7fd79137SRobert Mustacchi 1081*7fd79137SRobert Mustacchi } 1082*7fd79137SRobert Mustacchi 1083*7fd79137SRobert Mustacchi if (prefix.cf_cie_id != cie_id_value) { 1084*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_FRAME_CIE_DECODE_ERROR); 1085*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 1086*7fd79137SRobert Mustacchi } 1087*7fd79137SRobert Mustacchi frame_ptr = prefix.cf_addr_after_prefix; 1088*7fd79137SRobert Mustacchi res = dwarf_create_cie_from_after_start(dbg, 1089*7fd79137SRobert Mustacchi &prefix, 1090*7fd79137SRobert Mustacchi section_ptr, 1091*7fd79137SRobert Mustacchi frame_ptr, 1092*7fd79137SRobert Mustacchi cie_count, 1093*7fd79137SRobert Mustacchi use_gnu_cie_calc, 1094*7fd79137SRobert Mustacchi cie_ptr_to_use_out, error); 1095*7fd79137SRobert Mustacchi return res; 1096*7fd79137SRobert Mustacchi 1097*7fd79137SRobert Mustacchi } 1098*7fd79137SRobert Mustacchi 1099*7fd79137SRobert Mustacchi 1100*7fd79137SRobert Mustacchi /* This is for gnu eh frames, the 'z' case. 1101*7fd79137SRobert Mustacchi We find the letter involved 1102*7fd79137SRobert Mustacchi Return the augmentation character and, if applicable, 1103*7fd79137SRobert Mustacchi the personality routine address. 1104*7fd79137SRobert Mustacchi 1105*7fd79137SRobert Mustacchi personality_routine_out - 1106*7fd79137SRobert Mustacchi if 'P' is augchar, is personality handler addr. 1107*7fd79137SRobert Mustacchi Otherwise is not set. 1108*7fd79137SRobert Mustacchi aug_data - if 'P' points to data space of the 1109*7fd79137SRobert Mustacchi aug_data_len - length of areas aug_data points to. 1110*7fd79137SRobert Mustacchi 1111*7fd79137SRobert Mustacchi */ 1112*7fd79137SRobert Mustacchi #if 0 1113*7fd79137SRobert Mustacchi /* For debugging only. */ 1114*7fd79137SRobert Mustacchi void 1115*7fd79137SRobert Mustacchi dump_bytes(Dwarf_Small * start, long len) 1116*7fd79137SRobert Mustacchi { 1117*7fd79137SRobert Mustacchi Dwarf_Small *end = start + len; 1118*7fd79137SRobert Mustacchi Dwarf_Small *cur = start; 1119*7fd79137SRobert Mustacchi 1120*7fd79137SRobert Mustacchi for (; cur < end; cur++) { 1121*7fd79137SRobert Mustacchi printf(" byte %d, data %02x\n", (int) (cur - start), *cur); 1122*7fd79137SRobert Mustacchi } 1123*7fd79137SRobert Mustacchi 1124*7fd79137SRobert Mustacchi } 1125*7fd79137SRobert Mustacchi #endif 1126*7fd79137SRobert Mustacchi static int 1127*7fd79137SRobert Mustacchi gnu_aug_encodings(Dwarf_Debug dbg, char *augmentation, 1128*7fd79137SRobert Mustacchi Dwarf_Small * aug_data, Dwarf_Unsigned aug_data_len, 1129*7fd79137SRobert Mustacchi Dwarf_Half address_size, 1130*7fd79137SRobert Mustacchi unsigned char *pers_hand_enc_out, 1131*7fd79137SRobert Mustacchi unsigned char *lsda_enc_out, 1132*7fd79137SRobert Mustacchi unsigned char *fde_begin_enc_out, 1133*7fd79137SRobert Mustacchi Dwarf_Addr * gnu_pers_addr_out) 1134*7fd79137SRobert Mustacchi { 1135*7fd79137SRobert Mustacchi char *nc = 0; 1136*7fd79137SRobert Mustacchi Dwarf_Small *cur_aug_p = aug_data; 1137*7fd79137SRobert Mustacchi Dwarf_Small *end_aug_p = aug_data + aug_data_len; 1138*7fd79137SRobert Mustacchi 1139*7fd79137SRobert Mustacchi for (nc = augmentation; *nc; ++nc) { 1140*7fd79137SRobert Mustacchi char c = *nc; 1141*7fd79137SRobert Mustacchi 1142*7fd79137SRobert Mustacchi switch (c) { 1143*7fd79137SRobert Mustacchi case 'z': 1144*7fd79137SRobert Mustacchi /* Means that the augmentation data is present. */ 1145*7fd79137SRobert Mustacchi continue; 1146*7fd79137SRobert Mustacchi 1147*7fd79137SRobert Mustacchi case 'S': 1148*7fd79137SRobert Mustacchi /* Indicates this is a signal stack frame. Debuggers have to do 1149*7fd79137SRobert Mustacchi special handling. We don't need to do more than print this flag at 1150*7fd79137SRobert Mustacchi the right time, though (see dwarfdump where it prints the augmentation 1151*7fd79137SRobert Mustacchi string). 1152*7fd79137SRobert Mustacchi A signal stack frame (in some OS's) can only be 1153*7fd79137SRobert Mustacchi unwound (backtraced) by knowing it is a signal stack frame 1154*7fd79137SRobert Mustacchi (perhaps by noticing the name of the function for the stack frame 1155*7fd79137SRobert Mustacchi if the name can be found somehow) and figuring 1156*7fd79137SRobert Mustacchi out (or knowing) how the kernel and libc pushed a structure 1157*7fd79137SRobert Mustacchi onto the stack and loading registers from that structure. 1158*7fd79137SRobert Mustacchi Totally different from normal stack unwinding. 1159*7fd79137SRobert Mustacchi This flag gives an unwinder a big leg up by decoupling the 1160*7fd79137SRobert Mustacchi 'hint: this is a stack frame' from knowledge like 1161*7fd79137SRobert Mustacchi the function name (the name might be unavailable at unwind time). 1162*7fd79137SRobert Mustacchi */ 1163*7fd79137SRobert Mustacchi break; 1164*7fd79137SRobert Mustacchi 1165*7fd79137SRobert Mustacchi case 'L': 1166*7fd79137SRobert Mustacchi if (cur_aug_p > end_aug_p) { 1167*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 1168*7fd79137SRobert Mustacchi } 1169*7fd79137SRobert Mustacchi *lsda_enc_out = *(unsigned char *) cur_aug_p; 1170*7fd79137SRobert Mustacchi ++cur_aug_p; 1171*7fd79137SRobert Mustacchi break; 1172*7fd79137SRobert Mustacchi case 'R': 1173*7fd79137SRobert Mustacchi /* Followed by a one byte argument giving the 1174*7fd79137SRobert Mustacchi pointer encoding for the address pointers in the fde. */ 1175*7fd79137SRobert Mustacchi if (cur_aug_p >= end_aug_p) { 1176*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 1177*7fd79137SRobert Mustacchi } 1178*7fd79137SRobert Mustacchi *fde_begin_enc_out = *(unsigned char *) cur_aug_p; 1179*7fd79137SRobert Mustacchi ++cur_aug_p; 1180*7fd79137SRobert Mustacchi break; 1181*7fd79137SRobert Mustacchi case 'P':{ 1182*7fd79137SRobert Mustacchi int res = DW_DLV_ERROR; 1183*7fd79137SRobert Mustacchi Dwarf_Small *updated_aug_p = 0; 1184*7fd79137SRobert Mustacchi unsigned char encoding = 0; 1185*7fd79137SRobert Mustacchi 1186*7fd79137SRobert Mustacchi if (cur_aug_p >= end_aug_p) { 1187*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 1188*7fd79137SRobert Mustacchi } 1189*7fd79137SRobert Mustacchi encoding = *(unsigned char *) cur_aug_p; 1190*7fd79137SRobert Mustacchi *pers_hand_enc_out = encoding; 1191*7fd79137SRobert Mustacchi ++cur_aug_p; 1192*7fd79137SRobert Mustacchi if (cur_aug_p > end_aug_p) { 1193*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 1194*7fd79137SRobert Mustacchi } 1195*7fd79137SRobert Mustacchi /* DW_EH_PE_pcrel makes no sense here, so we turn it 1196*7fd79137SRobert Mustacchi off via a section pointer of NULL. */ 1197*7fd79137SRobert Mustacchi res = read_encoded_ptr(dbg, 1198*7fd79137SRobert Mustacchi (Dwarf_Small *) NULL, 1199*7fd79137SRobert Mustacchi cur_aug_p, 1200*7fd79137SRobert Mustacchi encoding, 1201*7fd79137SRobert Mustacchi address_size, 1202*7fd79137SRobert Mustacchi gnu_pers_addr_out, 1203*7fd79137SRobert Mustacchi &updated_aug_p); 1204*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 1205*7fd79137SRobert Mustacchi return res; 1206*7fd79137SRobert Mustacchi } 1207*7fd79137SRobert Mustacchi cur_aug_p = updated_aug_p; 1208*7fd79137SRobert Mustacchi if (cur_aug_p > end_aug_p) { 1209*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 1210*7fd79137SRobert Mustacchi } 1211*7fd79137SRobert Mustacchi } 1212*7fd79137SRobert Mustacchi break; 1213*7fd79137SRobert Mustacchi default: 1214*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 1215*7fd79137SRobert Mustacchi 1216*7fd79137SRobert Mustacchi } 1217*7fd79137SRobert Mustacchi } 1218*7fd79137SRobert Mustacchi 1219*7fd79137SRobert Mustacchi return DW_DLV_OK; 1220*7fd79137SRobert Mustacchi } 1221*7fd79137SRobert Mustacchi 1222*7fd79137SRobert Mustacchi /* Given augmentation character (the encoding) giving the 1223*7fd79137SRobert Mustacchi address format, read the address from input_field 1224*7fd79137SRobert Mustacchi and return an incremented value 1 past the input bytes of the 1225*7fd79137SRobert Mustacchi address. 1226*7fd79137SRobert Mustacchi Push the address read back thru the *addr pointer. 1227*7fd79137SRobert Mustacchi See LSB (Linux Standar Base) exception handling documents. 1228*7fd79137SRobert Mustacchi */ 1229*7fd79137SRobert Mustacchi static int 1230*7fd79137SRobert Mustacchi read_encoded_ptr(Dwarf_Debug dbg, 1231*7fd79137SRobert Mustacchi Dwarf_Small * section_pointer, 1232*7fd79137SRobert Mustacchi Dwarf_Small * input_field, 1233*7fd79137SRobert Mustacchi int gnu_encoding, 1234*7fd79137SRobert Mustacchi Dwarf_Half address_size, 1235*7fd79137SRobert Mustacchi Dwarf_Unsigned * addr, 1236*7fd79137SRobert Mustacchi Dwarf_Small ** input_field_updated) 1237*7fd79137SRobert Mustacchi { 1238*7fd79137SRobert Mustacchi Dwarf_Word length = 0; 1239*7fd79137SRobert Mustacchi int value_type = gnu_encoding & 0xf; 1240*7fd79137SRobert Mustacchi Dwarf_Small *input_field_original = input_field; 1241*7fd79137SRobert Mustacchi 1242*7fd79137SRobert Mustacchi if (gnu_encoding == 0xff) { 1243*7fd79137SRobert Mustacchi /* There is no data here. */ 1244*7fd79137SRobert Mustacchi 1245*7fd79137SRobert Mustacchi *addr = 0; 1246*7fd79137SRobert Mustacchi *input_field_updated = input_field; 1247*7fd79137SRobert Mustacchi /* Should we return DW_DLV_NO_ENTRY? */ 1248*7fd79137SRobert Mustacchi return DW_DLV_OK; 1249*7fd79137SRobert Mustacchi } 1250*7fd79137SRobert Mustacchi switch (value_type) { 1251*7fd79137SRobert Mustacchi case DW_EH_PE_absptr:{ 1252*7fd79137SRobert Mustacchi /* value_type is zero. Treat as pointer size of the object. 1253*7fd79137SRobert Mustacchi */ 1254*7fd79137SRobert Mustacchi Dwarf_Unsigned ret_value = 0; 1255*7fd79137SRobert Mustacchi 1256*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, 1257*7fd79137SRobert Mustacchi input_field, address_size); 1258*7fd79137SRobert Mustacchi *addr = ret_value; 1259*7fd79137SRobert Mustacchi *input_field_updated = input_field + address_size; 1260*7fd79137SRobert Mustacchi } 1261*7fd79137SRobert Mustacchi break; 1262*7fd79137SRobert Mustacchi case DW_EH_PE_uleb128:{ 1263*7fd79137SRobert Mustacchi Dwarf_Unsigned val = _dwarf_decode_u_leb128(input_field, 1264*7fd79137SRobert Mustacchi &length); 1265*7fd79137SRobert Mustacchi 1266*7fd79137SRobert Mustacchi *addr = val; 1267*7fd79137SRobert Mustacchi *input_field_updated = input_field + length; 1268*7fd79137SRobert Mustacchi } 1269*7fd79137SRobert Mustacchi break; 1270*7fd79137SRobert Mustacchi case DW_EH_PE_udata2:{ 1271*7fd79137SRobert Mustacchi Dwarf_Unsigned ret_value = 0; 1272*7fd79137SRobert Mustacchi 1273*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, 1274*7fd79137SRobert Mustacchi input_field, 2); 1275*7fd79137SRobert Mustacchi *addr = ret_value; 1276*7fd79137SRobert Mustacchi *input_field_updated = input_field + 2; 1277*7fd79137SRobert Mustacchi } 1278*7fd79137SRobert Mustacchi break; 1279*7fd79137SRobert Mustacchi 1280*7fd79137SRobert Mustacchi case DW_EH_PE_udata4:{ 1281*7fd79137SRobert Mustacchi 1282*7fd79137SRobert Mustacchi Dwarf_Unsigned ret_value = 0; 1283*7fd79137SRobert Mustacchi 1284*7fd79137SRobert Mustacchi /* ASSERT: sizeof(Dwarf_ufixed) == 4 */ 1285*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, 1286*7fd79137SRobert Mustacchi input_field, sizeof(Dwarf_ufixed)); 1287*7fd79137SRobert Mustacchi *addr = ret_value; 1288*7fd79137SRobert Mustacchi *input_field_updated = input_field + sizeof(Dwarf_ufixed); 1289*7fd79137SRobert Mustacchi } 1290*7fd79137SRobert Mustacchi break; 1291*7fd79137SRobert Mustacchi 1292*7fd79137SRobert Mustacchi case DW_EH_PE_udata8:{ 1293*7fd79137SRobert Mustacchi Dwarf_Unsigned ret_value = 0; 1294*7fd79137SRobert Mustacchi 1295*7fd79137SRobert Mustacchi /* ASSERT: sizeof(Dwarf_Unsigned) == 8 */ 1296*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, 1297*7fd79137SRobert Mustacchi input_field, sizeof(Dwarf_Unsigned)); 1298*7fd79137SRobert Mustacchi *addr = ret_value; 1299*7fd79137SRobert Mustacchi *input_field_updated = input_field + sizeof(Dwarf_Unsigned); 1300*7fd79137SRobert Mustacchi } 1301*7fd79137SRobert Mustacchi break; 1302*7fd79137SRobert Mustacchi 1303*7fd79137SRobert Mustacchi case DW_EH_PE_sleb128:{ 1304*7fd79137SRobert Mustacchi Dwarf_Signed val = _dwarf_decode_s_leb128(input_field, 1305*7fd79137SRobert Mustacchi &length); 1306*7fd79137SRobert Mustacchi 1307*7fd79137SRobert Mustacchi *addr = (Dwarf_Unsigned) val; 1308*7fd79137SRobert Mustacchi *input_field_updated = input_field + length; 1309*7fd79137SRobert Mustacchi } 1310*7fd79137SRobert Mustacchi break; 1311*7fd79137SRobert Mustacchi case DW_EH_PE_sdata2:{ 1312*7fd79137SRobert Mustacchi Dwarf_Unsigned val = 0; 1313*7fd79137SRobert Mustacchi 1314*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, val, Dwarf_Unsigned, input_field, 2); 1315*7fd79137SRobert Mustacchi SIGN_EXTEND(val, 2); 1316*7fd79137SRobert Mustacchi *addr = (Dwarf_Unsigned) val; 1317*7fd79137SRobert Mustacchi *input_field_updated = input_field + 2; 1318*7fd79137SRobert Mustacchi } 1319*7fd79137SRobert Mustacchi break; 1320*7fd79137SRobert Mustacchi 1321*7fd79137SRobert Mustacchi case DW_EH_PE_sdata4:{ 1322*7fd79137SRobert Mustacchi Dwarf_Unsigned val = 0; 1323*7fd79137SRobert Mustacchi 1324*7fd79137SRobert Mustacchi /* ASSERT: sizeof(Dwarf_ufixed) == 4 */ 1325*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, val, 1326*7fd79137SRobert Mustacchi Dwarf_Unsigned, input_field, 1327*7fd79137SRobert Mustacchi sizeof(Dwarf_ufixed)); 1328*7fd79137SRobert Mustacchi SIGN_EXTEND(val, sizeof(Dwarf_ufixed)); 1329*7fd79137SRobert Mustacchi *addr = (Dwarf_Unsigned) val; 1330*7fd79137SRobert Mustacchi *input_field_updated = input_field + sizeof(Dwarf_ufixed); 1331*7fd79137SRobert Mustacchi } 1332*7fd79137SRobert Mustacchi break; 1333*7fd79137SRobert Mustacchi case DW_EH_PE_sdata8:{ 1334*7fd79137SRobert Mustacchi Dwarf_Unsigned val = 0; 1335*7fd79137SRobert Mustacchi 1336*7fd79137SRobert Mustacchi /* ASSERT: sizeof(Dwarf_Unsigned) == 8 */ 1337*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, val, 1338*7fd79137SRobert Mustacchi Dwarf_Unsigned, input_field, 1339*7fd79137SRobert Mustacchi sizeof(Dwarf_Unsigned)); 1340*7fd79137SRobert Mustacchi *addr = (Dwarf_Unsigned) val; 1341*7fd79137SRobert Mustacchi *input_field_updated = input_field + sizeof(Dwarf_Unsigned); 1342*7fd79137SRobert Mustacchi } 1343*7fd79137SRobert Mustacchi break; 1344*7fd79137SRobert Mustacchi default: 1345*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 1346*7fd79137SRobert Mustacchi 1347*7fd79137SRobert Mustacchi }; 1348*7fd79137SRobert Mustacchi /* The ELF ABI for gnu does not document the meaning of 1349*7fd79137SRobert Mustacchi DW_EH_PE_pcrel, which is awkward. It apparently means the value 1350*7fd79137SRobert Mustacchi we got above is pc-relative (meaning section-relative), so we 1351*7fd79137SRobert Mustacchi adjust the value. Section_pointer may be null if it is known 1352*7fd79137SRobert Mustacchi DW_EH_PE_pcrel cannot apply, such as for .debug_frame or for an 1353*7fd79137SRobert Mustacchi address-range value. */ 1354*7fd79137SRobert Mustacchi if (section_pointer && ((gnu_encoding & 0x70) == DW_EH_PE_pcrel)) { 1355*7fd79137SRobert Mustacchi /* Address (*addr) above is pc relative with respect to a 1356*7fd79137SRobert Mustacchi section. Add to the offset the base address (from elf) of 1357*7fd79137SRobert Mustacchi section and the distance of the field we are reading from 1358*7fd79137SRobert Mustacchi the section-beginning to get the actual address. */ 1359*7fd79137SRobert Mustacchi /* ASSERT: input_field_original >= section_pointer */ 1360*7fd79137SRobert Mustacchi Dwarf_Unsigned distance = 1361*7fd79137SRobert Mustacchi input_field_original - section_pointer; 1362*7fd79137SRobert Mustacchi *addr += dbg->de_debug_frame_eh_gnu.dss_addr + distance; 1363*7fd79137SRobert Mustacchi } 1364*7fd79137SRobert Mustacchi 1365*7fd79137SRobert Mustacchi return DW_DLV_OK; 1366*7fd79137SRobert Mustacchi } 1367*7fd79137SRobert Mustacchi 1368*7fd79137SRobert Mustacchi 1369*7fd79137SRobert Mustacchi 1370*7fd79137SRobert Mustacchi 1371*7fd79137SRobert Mustacchi /* 1372*7fd79137SRobert Mustacchi All augmentation string checking done here now. 1373*7fd79137SRobert Mustacchi 1374*7fd79137SRobert Mustacchi For .eh_frame, gcc from 3.3 uses the z style, earlier used 1375*7fd79137SRobert Mustacchi only "eh" as augmentation. We don't yet handle 1376*7fd79137SRobert Mustacchi decoding .eh_frame with the z style extensions like L P. 1377*7fd79137SRobert Mustacchi 1378*7fd79137SRobert Mustacchi These are nasty heuristics, but then that's life 1379*7fd79137SRobert Mustacchi as augmentations are implementation specific. 1380*7fd79137SRobert Mustacchi */ 1381*7fd79137SRobert Mustacchi /* ARGSUSED */ 1382*7fd79137SRobert Mustacchi enum Dwarf_augmentation_type 1383*7fd79137SRobert Mustacchi _dwarf_get_augmentation_type(Dwarf_Debug dbg, 1384*7fd79137SRobert Mustacchi Dwarf_Small * augmentation_string, 1385*7fd79137SRobert Mustacchi int is_gcc_eh_frame) 1386*7fd79137SRobert Mustacchi { 1387*7fd79137SRobert Mustacchi enum Dwarf_augmentation_type t = aug_unknown; 1388*7fd79137SRobert Mustacchi char *ag_string = (char *) augmentation_string; 1389*7fd79137SRobert Mustacchi 1390*7fd79137SRobert Mustacchi if (ag_string[0] == 0) { 1391*7fd79137SRobert Mustacchi /* Empty string. We'll just guess that we know what this means: 1392*7fd79137SRobert Mustacchi standard dwarf2/3 with no implementation-defined fields. */ 1393*7fd79137SRobert Mustacchi t = aug_empty_string; 1394*7fd79137SRobert Mustacchi } else if (strcmp(ag_string, DW_DEBUG_FRAME_AUGMENTER_STRING) == 0) { 1395*7fd79137SRobert Mustacchi /* The string is "mti v1". Used internally at SGI, probably 1396*7fd79137SRobert Mustacchi never shipped. Replaced by "z". Treat like 'nothing 1397*7fd79137SRobert Mustacchi special'. */ 1398*7fd79137SRobert Mustacchi t = aug_irix_mti_v1; 1399*7fd79137SRobert Mustacchi } else if (ag_string[0] == 'z') { 1400*7fd79137SRobert Mustacchi /* If it's IRIX cc, z means aug_irix_exception_table. z1 z2 1401*7fd79137SRobert Mustacchi were designed as for IRIX CC, but never implemented */ 1402*7fd79137SRobert Mustacchi /* If it's gcc, z may be any of several things. "z" or z 1403*7fd79137SRobert Mustacchi followed optionally followed by one or more of L R P, each 1404*7fd79137SRobert Mustacchi of which means a value may be present. Should be in eh_frame 1405*7fd79137SRobert Mustacchi only, I think. */ 1406*7fd79137SRobert Mustacchi if (is_gcc_eh_frame) { 1407*7fd79137SRobert Mustacchi t = aug_gcc_eh_z; 1408*7fd79137SRobert Mustacchi } else if (ag_string[1] == 0) { 1409*7fd79137SRobert Mustacchi /* This is the normal IRIX C++ case, where there is an 1410*7fd79137SRobert Mustacchi offset into a table in each fde. The table being for 1411*7fd79137SRobert Mustacchi IRIX CC exception handling. */ 1412*7fd79137SRobert Mustacchi /* DW_CIE_AUGMENTER_STRING_V0 "z" */ 1413*7fd79137SRobert Mustacchi t = aug_irix_exception_table; 1414*7fd79137SRobert Mustacchi } /* Else unknown. */ 1415*7fd79137SRobert Mustacchi } else if (strncmp(ag_string, "eh", 2) == 0) { 1416*7fd79137SRobert Mustacchi /* gcc .eh_frame augmentation for egcs and gcc 2.x, at least 1417*7fd79137SRobert Mustacchi for x86. */ 1418*7fd79137SRobert Mustacchi t = aug_eh; 1419*7fd79137SRobert Mustacchi } else if (strcmp(ag_string, "armcc+") == 0) { 1420*7fd79137SRobert Mustacchi /* Arm uses this string to mean a bug in 1421*7fd79137SRobert Mustacchi in Arm compilers was fixed, changing to the standard 1422*7fd79137SRobert Mustacchi calculation of the CFA. See 1423*7fd79137SRobert Mustacchi http://sourceware.org/ml/gdb-patches/2006-12/msg00249.html 1424*7fd79137SRobert Mustacchi for details. */ 1425*7fd79137SRobert Mustacchi t = aug_armcc; 1426*7fd79137SRobert Mustacchi } else { 1427*7fd79137SRobert Mustacchi 1428*7fd79137SRobert Mustacchi } 1429*7fd79137SRobert Mustacchi return t; 1430*7fd79137SRobert Mustacchi } 1431*7fd79137SRobert Mustacchi 1432*7fd79137SRobert Mustacchi /* Using augmentation, and version 1433*7fd79137SRobert Mustacchi read in the augmentation data for GNU eh. 1434*7fd79137SRobert Mustacchi 1435*7fd79137SRobert Mustacchi Return DW_DLV_OK if we succeeded, 1436*7fd79137SRobert Mustacchi DW_DLV_ERR if we fail. 1437*7fd79137SRobert Mustacchi 1438*7fd79137SRobert Mustacchi On success, update 'size_of_augmentation_data' with 1439*7fd79137SRobert Mustacchi the length of the fields that are part of augmentation (so the 1440*7fd79137SRobert Mustacchi caller can increment frame_ptr appropriately). 1441*7fd79137SRobert Mustacchi 1442*7fd79137SRobert Mustacchi 'frame_ptr' points within section. 1443*7fd79137SRobert Mustacchi 'section_pointer' points to section base address in memory. 1444*7fd79137SRobert Mustacchi */ 1445*7fd79137SRobert Mustacchi /* ARGSUSED */ 1446*7fd79137SRobert Mustacchi static int 1447*7fd79137SRobert Mustacchi get_gcc_eh_augmentation(Dwarf_Debug dbg, Dwarf_Small * frame_ptr, 1448*7fd79137SRobert Mustacchi unsigned long *size_of_augmentation_data, 1449*7fd79137SRobert Mustacchi enum Dwarf_augmentation_type augtype, 1450*7fd79137SRobert Mustacchi Dwarf_Small * section_pointer, 1451*7fd79137SRobert Mustacchi Dwarf_Small * fde_eh_encoding_out, 1452*7fd79137SRobert Mustacchi char *augmentation) 1453*7fd79137SRobert Mustacchi { 1454*7fd79137SRobert Mustacchi char *suffix = 0; 1455*7fd79137SRobert Mustacchi unsigned long augdata_size = 0; 1456*7fd79137SRobert Mustacchi 1457*7fd79137SRobert Mustacchi if (augtype == aug_gcc_eh_z) { 1458*7fd79137SRobert Mustacchi /* Has leading 'z'. */ 1459*7fd79137SRobert Mustacchi Dwarf_Word leb128_length = 0; 1460*7fd79137SRobert Mustacchi 1461*7fd79137SRobert Mustacchi /* Dwarf_Unsigned eh_value = */ 1462*7fd79137SRobert Mustacchi _dwarf_decode_u_leb128(frame_ptr, &leb128_length); 1463*7fd79137SRobert Mustacchi augdata_size += leb128_length; 1464*7fd79137SRobert Mustacchi frame_ptr += leb128_length; 1465*7fd79137SRobert Mustacchi suffix = augmentation + 1; 1466*7fd79137SRobert Mustacchi } else { 1467*7fd79137SRobert Mustacchi /* Prefix is 'eh'. As in gcc 3.2. No suffix present 1468*7fd79137SRobert Mustacchi apparently. */ 1469*7fd79137SRobert Mustacchi suffix = augmentation + 2; 1470*7fd79137SRobert Mustacchi } 1471*7fd79137SRobert Mustacchi for (; *suffix; ++suffix) { 1472*7fd79137SRobert Mustacchi /* We have no idea what this is as yet. Some extensions beyond 1473*7fd79137SRobert Mustacchi dwarf exist which we do not yet handle. */ 1474*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 1475*7fd79137SRobert Mustacchi 1476*7fd79137SRobert Mustacchi } 1477*7fd79137SRobert Mustacchi 1478*7fd79137SRobert Mustacchi *size_of_augmentation_data = augdata_size; 1479*7fd79137SRobert Mustacchi return DW_DLV_OK; 1480*7fd79137SRobert Mustacchi } 1481*7fd79137SRobert Mustacchi 1482*7fd79137SRobert Mustacchi 1483*7fd79137SRobert Mustacchi /* Make the 'cie_id_addr' consistent across .debug_frame and .eh_frame. 1484*7fd79137SRobert Mustacchi Calculate a pointer into section bytes given a cie_id, which is 1485*7fd79137SRobert Mustacchi trivial for .debug_frame, but a bit more work for .eh_frame. 1486*7fd79137SRobert Mustacchi */ 1487*7fd79137SRobert Mustacchi static Dwarf_Small * 1488*7fd79137SRobert Mustacchi get_cieptr_given_offset(Dwarf_Unsigned cie_id_value, 1489*7fd79137SRobert Mustacchi int use_gnu_cie_calc, 1490*7fd79137SRobert Mustacchi Dwarf_Small * section_ptr, 1491*7fd79137SRobert Mustacchi Dwarf_Small * cie_id_addr) 1492*7fd79137SRobert Mustacchi { 1493*7fd79137SRobert Mustacchi Dwarf_Small *cieptr = 0; 1494*7fd79137SRobert Mustacchi 1495*7fd79137SRobert Mustacchi if (use_gnu_cie_calc) { 1496*7fd79137SRobert Mustacchi /* cie_id value is offset, in section, of the cie_id itself, to 1497*7fd79137SRobert Mustacchi use vm ptr of the value, less the value, to get to the cie 1498*7fd79137SRobert Mustacchi itself. In addition, munge *cie_id_addr to look *as if* it 1499*7fd79137SRobert Mustacchi was from real dwarf. */ 1500*7fd79137SRobert Mustacchi cieptr = (Dwarf_Small *)(uintptr_t) 1501*7fd79137SRobert Mustacchi ((Dwarf_Unsigned)(uintptr_t)cie_id_addr) - 1502*7fd79137SRobert Mustacchi ((Dwarf_Unsigned) cie_id_value); 1503*7fd79137SRobert Mustacchi } else { 1504*7fd79137SRobert Mustacchi /* Traditional dwarf section offset is in cie_id */ 1505*7fd79137SRobert Mustacchi cieptr = (section_ptr + cie_id_value); 1506*7fd79137SRobert Mustacchi } 1507*7fd79137SRobert Mustacchi return cieptr; 1508*7fd79137SRobert Mustacchi } 1509*7fd79137SRobert Mustacchi 1510*7fd79137SRobert Mustacchi /* To properly release all spaced used. 1511*7fd79137SRobert Mustacchi Earlier approaches (before July 15, 2005) 1512*7fd79137SRobert Mustacchi letting client do the dealloc directly left 1513*7fd79137SRobert Mustacchi some data allocated. 1514*7fd79137SRobert Mustacchi This is directly called by consumer code. 1515*7fd79137SRobert Mustacchi */ 1516*7fd79137SRobert Mustacchi void 1517*7fd79137SRobert Mustacchi dwarf_fde_cie_list_dealloc(Dwarf_Debug dbg, 1518*7fd79137SRobert Mustacchi Dwarf_Cie * cie_data, 1519*7fd79137SRobert Mustacchi Dwarf_Signed cie_element_count, 1520*7fd79137SRobert Mustacchi Dwarf_Fde * fde_data, 1521*7fd79137SRobert Mustacchi Dwarf_Signed fde_element_count) 1522*7fd79137SRobert Mustacchi { 1523*7fd79137SRobert Mustacchi Dwarf_Signed i = 0; 1524*7fd79137SRobert Mustacchi 1525*7fd79137SRobert Mustacchi for (i = 0; i < cie_element_count; ++i) { 1526*7fd79137SRobert Mustacchi Dwarf_Frame frame = cie_data[i]->ci_initial_table; 1527*7fd79137SRobert Mustacchi 1528*7fd79137SRobert Mustacchi if (frame) 1529*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, frame, DW_DLA_FRAME); 1530*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, cie_data[i], DW_DLA_CIE); 1531*7fd79137SRobert Mustacchi } 1532*7fd79137SRobert Mustacchi for (i = 0; i < fde_element_count; ++i) { 1533*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, fde_data[i], DW_DLA_FDE); 1534*7fd79137SRobert Mustacchi } 1535*7fd79137SRobert Mustacchi if (cie_data) 1536*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, cie_data, DW_DLA_LIST); 1537*7fd79137SRobert Mustacchi if (fde_data) 1538*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, fde_data, DW_DLA_LIST); 1539*7fd79137SRobert Mustacchi 1540*7fd79137SRobert Mustacchi } 1541