1*7fd79137SRobert Mustacchi /* 2*7fd79137SRobert Mustacchi 3*7fd79137SRobert Mustacchi Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. 4*7fd79137SRobert Mustacchi 5*7fd79137SRobert Mustacchi This program is free software; you can redistribute it and/or modify it 6*7fd79137SRobert Mustacchi under the terms of version 2.1 of the GNU Lesser General Public License 7*7fd79137SRobert Mustacchi as published by the Free Software Foundation. 8*7fd79137SRobert Mustacchi 9*7fd79137SRobert Mustacchi This program is distributed in the hope that it would be useful, but 10*7fd79137SRobert Mustacchi WITHOUT ANY WARRANTY; without even the implied warranty of 11*7fd79137SRobert Mustacchi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12*7fd79137SRobert Mustacchi 13*7fd79137SRobert Mustacchi Further, this software is distributed without any warranty that it is 14*7fd79137SRobert Mustacchi free of the rightful claim of any third person regarding infringement 15*7fd79137SRobert Mustacchi or the like. Any license provided herein, whether implied or 16*7fd79137SRobert Mustacchi otherwise, applies only to this software file. Patent licenses, if 17*7fd79137SRobert Mustacchi any, provided herein do not apply to combinations of this program with 18*7fd79137SRobert Mustacchi other software, or any other product whatsoever. 19*7fd79137SRobert Mustacchi 20*7fd79137SRobert Mustacchi You should have received a copy of the GNU Lesser General Public 21*7fd79137SRobert Mustacchi License along with this program; if not, write the Free Software 22*7fd79137SRobert Mustacchi Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, 23*7fd79137SRobert Mustacchi USA. 24*7fd79137SRobert Mustacchi 25*7fd79137SRobert Mustacchi Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, 26*7fd79137SRobert Mustacchi Mountain View, CA 94043, or: 27*7fd79137SRobert Mustacchi 28*7fd79137SRobert Mustacchi http://www.sgi.com 29*7fd79137SRobert Mustacchi 30*7fd79137SRobert Mustacchi For further information regarding this notice, see: 31*7fd79137SRobert Mustacchi 32*7fd79137SRobert Mustacchi http://oss.sgi.com/projects/GenInfo/NoticeExplan 33*7fd79137SRobert Mustacchi 34*7fd79137SRobert Mustacchi */ 35*7fd79137SRobert Mustacchi /* This code used by SGI-IRIX rqs processing, not needed by 36*7fd79137SRobert Mustacchi any other system or application. 37*7fd79137SRobert Mustacchi */ 38*7fd79137SRobert Mustacchi 39*7fd79137SRobert Mustacchi #include "config.h" 40*7fd79137SRobert Mustacchi #include "libdwarfdefs.h" 41*7fd79137SRobert Mustacchi #ifdef HAVE_ELF_H 42*7fd79137SRobert Mustacchi #include <elf.h> 43*7fd79137SRobert Mustacchi #endif 44*7fd79137SRobert Mustacchi #include <dwarf.h> 45*7fd79137SRobert Mustacchi #include <libdwarf.h> 46*7fd79137SRobert Mustacchi #include "dwarf_base_types.h" 47*7fd79137SRobert Mustacchi #include "dwarf_alloc.h" 48*7fd79137SRobert Mustacchi #include "dwarf_opaque.h" 49*7fd79137SRobert Mustacchi #include "dwarf_arange.h" 50*7fd79137SRobert Mustacchi #include "dwarf_line.h" 51*7fd79137SRobert Mustacchi #include "dwarf_frame.h" 52*7fd79137SRobert Mustacchi #include <cmplrs/dwarf_addr_finder.h> 53*7fd79137SRobert Mustacchi #include "dwarf_error.h" 54*7fd79137SRobert Mustacchi 55*7fd79137SRobert Mustacchi typedef unsigned long long ull; 56*7fd79137SRobert Mustacchi 57*7fd79137SRobert Mustacchi static int do_this_die_and_dealloc(Dwarf_Debug dbg, Dwarf_Die die, 58*7fd79137SRobert Mustacchi int *errval); 59*7fd79137SRobert Mustacchi static int 60*7fd79137SRobert Mustacchi handle_debug_info(Dwarf_Debug dbg, int *errval); 61*7fd79137SRobert Mustacchi static int 62*7fd79137SRobert Mustacchi handle_debug_frame(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func, int *errval); 63*7fd79137SRobert Mustacchi static int 64*7fd79137SRobert Mustacchi handle_debug_aranges(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func, int *errval); 65*7fd79137SRobert Mustacchi static int 66*7fd79137SRobert Mustacchi handle_debug_line(Dwarf_Debug dbg, Dwarf_Die cu_die, Dwarf_addr_callback_func cb_func, int *errval); 67*7fd79137SRobert Mustacchi static int 68*7fd79137SRobert Mustacchi handle_debug_loc(void); 69*7fd79137SRobert Mustacchi 70*7fd79137SRobert Mustacchi 71*7fd79137SRobert Mustacchi static Dwarf_addr_callback_func send_addr_note; 72*7fd79137SRobert Mustacchi 73*7fd79137SRobert Mustacchi int 74*7fd79137SRobert Mustacchi _dwarf_addr_finder(dwarf_elf_handle elf_file_ptr, 75*7fd79137SRobert Mustacchi Dwarf_addr_callback_func cb_func, int *dwerr) 76*7fd79137SRobert Mustacchi { 77*7fd79137SRobert Mustacchi 78*7fd79137SRobert Mustacchi Dwarf_Error err = 0; 79*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0; 80*7fd79137SRobert Mustacchi int res = 0; 81*7fd79137SRobert Mustacchi int errval = 0; 82*7fd79137SRobert Mustacchi int sections_found = 0; 83*7fd79137SRobert Mustacchi 84*7fd79137SRobert Mustacchi res = dwarf_elf_init(elf_file_ptr, DW_DLC_READ, /* errhand */ 0, 85*7fd79137SRobert Mustacchi /* errarg */ 0, &dbg, &err); 86*7fd79137SRobert Mustacchi if (res == DW_DLV_ERROR) { 87*7fd79137SRobert Mustacchi int errv = (int) dwarf_errno(err); 88*7fd79137SRobert Mustacchi 89*7fd79137SRobert Mustacchi return errv; 90*7fd79137SRobert Mustacchi } 91*7fd79137SRobert Mustacchi if (res == DW_DLV_NO_ENTRY) { 92*7fd79137SRobert Mustacchi return res; 93*7fd79137SRobert Mustacchi } 94*7fd79137SRobert Mustacchi 95*7fd79137SRobert Mustacchi send_addr_note = cb_func; 96*7fd79137SRobert Mustacchi 97*7fd79137SRobert Mustacchi res = handle_debug_info(dbg, &errval); 98*7fd79137SRobert Mustacchi switch (res) { 99*7fd79137SRobert Mustacchi case DW_DLV_OK: 100*7fd79137SRobert Mustacchi ++sections_found; 101*7fd79137SRobert Mustacchi break; 102*7fd79137SRobert Mustacchi case DW_DLV_NO_ENTRY: 103*7fd79137SRobert Mustacchi 104*7fd79137SRobert Mustacchi break; 105*7fd79137SRobert Mustacchi default: 106*7fd79137SRobert Mustacchi case DW_DLV_ERROR: 107*7fd79137SRobert Mustacchi dwarf_finish(dbg, &err); 108*7fd79137SRobert Mustacchi *dwerr = errval; 109*7fd79137SRobert Mustacchi return res; 110*7fd79137SRobert Mustacchi } 111*7fd79137SRobert Mustacchi 112*7fd79137SRobert Mustacchi res = handle_debug_aranges(dbg, cb_func, &errval); 113*7fd79137SRobert Mustacchi switch (res) { 114*7fd79137SRobert Mustacchi case DW_DLV_OK: 115*7fd79137SRobert Mustacchi ++sections_found; 116*7fd79137SRobert Mustacchi break; 117*7fd79137SRobert Mustacchi case DW_DLV_NO_ENTRY: 118*7fd79137SRobert Mustacchi break; 119*7fd79137SRobert Mustacchi default: 120*7fd79137SRobert Mustacchi case DW_DLV_ERROR: 121*7fd79137SRobert Mustacchi dwarf_finish(dbg, &err); 122*7fd79137SRobert Mustacchi *dwerr = errval; 123*7fd79137SRobert Mustacchi return res; 124*7fd79137SRobert Mustacchi } 125*7fd79137SRobert Mustacchi res = handle_debug_frame(dbg, cb_func, &errval); 126*7fd79137SRobert Mustacchi switch (res) { 127*7fd79137SRobert Mustacchi case DW_DLV_OK: 128*7fd79137SRobert Mustacchi ++sections_found; 129*7fd79137SRobert Mustacchi break; 130*7fd79137SRobert Mustacchi case DW_DLV_NO_ENTRY: 131*7fd79137SRobert Mustacchi break; 132*7fd79137SRobert Mustacchi default: 133*7fd79137SRobert Mustacchi case DW_DLV_ERROR: 134*7fd79137SRobert Mustacchi dwarf_finish(dbg, &err); 135*7fd79137SRobert Mustacchi *dwerr = errval; 136*7fd79137SRobert Mustacchi return res; 137*7fd79137SRobert Mustacchi } 138*7fd79137SRobert Mustacchi 139*7fd79137SRobert Mustacchi res = handle_debug_loc(); /* does nothing */ 140*7fd79137SRobert Mustacchi switch (res) { 141*7fd79137SRobert Mustacchi case DW_DLV_OK: 142*7fd79137SRobert Mustacchi ++sections_found; 143*7fd79137SRobert Mustacchi break; 144*7fd79137SRobert Mustacchi case DW_DLV_NO_ENTRY: 145*7fd79137SRobert Mustacchi break; 146*7fd79137SRobert Mustacchi default: 147*7fd79137SRobert Mustacchi case DW_DLV_ERROR: 148*7fd79137SRobert Mustacchi /* IMPOSSIBLE : handle_debug_loc cannot return this */ 149*7fd79137SRobert Mustacchi dwarf_finish(dbg, &err); 150*7fd79137SRobert Mustacchi *dwerr = errval; 151*7fd79137SRobert Mustacchi return res; 152*7fd79137SRobert Mustacchi } 153*7fd79137SRobert Mustacchi 154*7fd79137SRobert Mustacchi 155*7fd79137SRobert Mustacchi 156*7fd79137SRobert Mustacchi *dwerr = 0; 157*7fd79137SRobert Mustacchi res = dwarf_finish(dbg, &err); 158*7fd79137SRobert Mustacchi if (res == DW_DLV_ERROR) { 159*7fd79137SRobert Mustacchi *dwerr = (int) dwarf_errno(err); 160*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 161*7fd79137SRobert Mustacchi } 162*7fd79137SRobert Mustacchi if (sections_found == 0) { 163*7fd79137SRobert Mustacchi return DW_DLV_NO_ENTRY; 164*7fd79137SRobert Mustacchi } 165*7fd79137SRobert Mustacchi return DW_DLV_OK; 166*7fd79137SRobert Mustacchi 167*7fd79137SRobert Mustacchi } 168*7fd79137SRobert Mustacchi 169*7fd79137SRobert Mustacchi /* 170*7fd79137SRobert Mustacchi Return DW_DLV_OK, ERROR, or NO_ENTRY. 171*7fd79137SRobert Mustacchi */ 172*7fd79137SRobert Mustacchi static int 173*7fd79137SRobert Mustacchi handle_debug_info(Dwarf_Debug dbg, int *errval) 174*7fd79137SRobert Mustacchi { 175*7fd79137SRobert Mustacchi Dwarf_Unsigned nxtoff = 1; 176*7fd79137SRobert Mustacchi Dwarf_Unsigned hdr_length; 177*7fd79137SRobert Mustacchi Dwarf_Half version_stamp; 178*7fd79137SRobert Mustacchi Dwarf_Unsigned abbrev_offset; 179*7fd79137SRobert Mustacchi Dwarf_Half addr_size; 180*7fd79137SRobert Mustacchi Dwarf_Error err; 181*7fd79137SRobert Mustacchi int terminate_now = 0; 182*7fd79137SRobert Mustacchi int res = 0; 183*7fd79137SRobert Mustacchi Dwarf_Die sibdie; 184*7fd79137SRobert Mustacchi int sibres; 185*7fd79137SRobert Mustacchi int nres = DW_DLV_OK; 186*7fd79137SRobert Mustacchi 187*7fd79137SRobert Mustacchi 188*7fd79137SRobert Mustacchi for (nres = dwarf_next_cu_header(dbg, &hdr_length, &version_stamp, 189*7fd79137SRobert Mustacchi &abbrev_offset, 190*7fd79137SRobert Mustacchi &addr_size, &nxtoff, &err); 191*7fd79137SRobert Mustacchi terminate_now == 0 && nres == DW_DLV_OK; 192*7fd79137SRobert Mustacchi nres = dwarf_next_cu_header(dbg, &hdr_length, &version_stamp, 193*7fd79137SRobert Mustacchi &abbrev_offset, 194*7fd79137SRobert Mustacchi &addr_size, &nxtoff, &err) 195*7fd79137SRobert Mustacchi ) { 196*7fd79137SRobert Mustacchi 197*7fd79137SRobert Mustacchi Dwarf_Die curdie = 0; 198*7fd79137SRobert Mustacchi 199*7fd79137SRobert Mustacchi /* try to get the compilation unit die */ 200*7fd79137SRobert Mustacchi sibres = dwarf_siblingof(dbg, curdie, &sibdie, &err); 201*7fd79137SRobert Mustacchi if (sibres == DW_DLV_OK) { 202*7fd79137SRobert Mustacchi res = do_this_die_and_dealloc(dbg, sibdie, errval); 203*7fd79137SRobert Mustacchi switch (res) { 204*7fd79137SRobert Mustacchi case DW_DLV_OK: 205*7fd79137SRobert Mustacchi break; 206*7fd79137SRobert Mustacchi case DW_DLV_NO_ENTRY: 207*7fd79137SRobert Mustacchi break; 208*7fd79137SRobert Mustacchi default: 209*7fd79137SRobert Mustacchi case DW_DLV_ERROR: 210*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 211*7fd79137SRobert Mustacchi } 212*7fd79137SRobert Mustacchi } else if (sibres == DW_DLV_ERROR) { 213*7fd79137SRobert Mustacchi *errval = (int) dwarf_errno(err); 214*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 215*7fd79137SRobert Mustacchi } else { 216*7fd79137SRobert Mustacchi /* NO ENTRY! */ 217*7fd79137SRobert Mustacchi /* impossible? */ 218*7fd79137SRobert Mustacchi } 219*7fd79137SRobert Mustacchi 220*7fd79137SRobert Mustacchi } 221*7fd79137SRobert Mustacchi if (nres == DW_DLV_ERROR) { 222*7fd79137SRobert Mustacchi int localerr = (int) dwarf_errno(err); 223*7fd79137SRobert Mustacchi 224*7fd79137SRobert Mustacchi *errval = localerr; 225*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 226*7fd79137SRobert Mustacchi } 227*7fd79137SRobert Mustacchi return DW_DLV_OK; 228*7fd79137SRobert Mustacchi } 229*7fd79137SRobert Mustacchi 230*7fd79137SRobert Mustacchi static int 231*7fd79137SRobert Mustacchi might_have_addr[] = { 232*7fd79137SRobert Mustacchi DW_AT_high_pc, 233*7fd79137SRobert Mustacchi DW_AT_low_pc, 234*7fd79137SRobert Mustacchi }; 235*7fd79137SRobert Mustacchi static int 236*7fd79137SRobert Mustacchi might_have_locdesc[] = { 237*7fd79137SRobert Mustacchi DW_AT_segment, 238*7fd79137SRobert Mustacchi DW_AT_return_addr, 239*7fd79137SRobert Mustacchi DW_AT_frame_base, 240*7fd79137SRobert Mustacchi DW_AT_static_link, 241*7fd79137SRobert Mustacchi DW_AT_data_member_location, 242*7fd79137SRobert Mustacchi DW_AT_string_length, 243*7fd79137SRobert Mustacchi DW_AT_location, 244*7fd79137SRobert Mustacchi DW_AT_use_location, 245*7fd79137SRobert Mustacchi DW_AT_vtable_elem_location, 246*7fd79137SRobert Mustacchi }; 247*7fd79137SRobert Mustacchi 248*7fd79137SRobert Mustacchi /* 249*7fd79137SRobert Mustacchi Return DW_DLV_OK if handling this went ok. 250*7fd79137SRobert Mustacchi */ 251*7fd79137SRobert Mustacchi static int 252*7fd79137SRobert Mustacchi handle_attr_addr(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half attrnum, 253*7fd79137SRobert Mustacchi Dwarf_Error * perr) 254*7fd79137SRobert Mustacchi { 255*7fd79137SRobert Mustacchi int res = DW_DLV_OK; 256*7fd79137SRobert Mustacchi Dwarf_Off offset; 257*7fd79137SRobert Mustacchi Dwarf_Addr addr; 258*7fd79137SRobert Mustacchi Dwarf_Half form; 259*7fd79137SRobert Mustacchi int ares; 260*7fd79137SRobert Mustacchi 261*7fd79137SRobert Mustacchi Dwarf_Attribute attr; 262*7fd79137SRobert Mustacchi 263*7fd79137SRobert Mustacchi ares = dwarf_attr(die, attrnum, &attr, perr); 264*7fd79137SRobert Mustacchi if (ares == DW_DLV_OK) { 265*7fd79137SRobert Mustacchi int formres = dwarf_whatform(attr, &form, perr); 266*7fd79137SRobert Mustacchi 267*7fd79137SRobert Mustacchi switch (formres) { 268*7fd79137SRobert Mustacchi case DW_DLV_OK: 269*7fd79137SRobert Mustacchi break; 270*7fd79137SRobert Mustacchi case DW_DLV_ERROR: 271*7fd79137SRobert Mustacchi case DW_DLV_NO_ENTRY: /* impossible. */ 272*7fd79137SRobert Mustacchi return formres; 273*7fd79137SRobert Mustacchi 274*7fd79137SRobert Mustacchi } 275*7fd79137SRobert Mustacchi 276*7fd79137SRobert Mustacchi switch (form) { 277*7fd79137SRobert Mustacchi case DW_FORM_ref_addr: 278*7fd79137SRobert Mustacchi case DW_FORM_addr: 279*7fd79137SRobert Mustacchi res = dwarf_attr_offset(die, attr, &offset, perr); 280*7fd79137SRobert Mustacchi if (res == DW_DLV_OK) { 281*7fd79137SRobert Mustacchi ares = dwarf_formaddr(attr, &addr, perr); 282*7fd79137SRobert Mustacchi if (ares == DW_DLV_OK) { 283*7fd79137SRobert Mustacchi send_addr_note(DW_SECTION_INFO, offset, addr); 284*7fd79137SRobert Mustacchi } else if (ares == DW_DLV_ERROR) { 285*7fd79137SRobert Mustacchi return ares; 286*7fd79137SRobert Mustacchi } /* no entry: ok. */ 287*7fd79137SRobert Mustacchi } else { 288*7fd79137SRobert Mustacchi res = DW_DLV_ERROR; /* NO_ENTRY is impossible. */ 289*7fd79137SRobert Mustacchi } 290*7fd79137SRobert Mustacchi break; 291*7fd79137SRobert Mustacchi 292*7fd79137SRobert Mustacchi default: 293*7fd79137SRobert Mustacchi /* surprising! An error? */ 294*7fd79137SRobert Mustacchi 295*7fd79137SRobert Mustacchi ; /* do nothing */ 296*7fd79137SRobert Mustacchi } 297*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, attr, DW_DLA_ATTR); 298*7fd79137SRobert Mustacchi 299*7fd79137SRobert Mustacchi } else { 300*7fd79137SRobert Mustacchi res = ares; 301*7fd79137SRobert Mustacchi } 302*7fd79137SRobert Mustacchi return res; 303*7fd79137SRobert Mustacchi } 304*7fd79137SRobert Mustacchi 305*7fd79137SRobert Mustacchi /* 306*7fd79137SRobert Mustacchi Return DW_DLV_OK if handling this went ok. 307*7fd79137SRobert Mustacchi */ 308*7fd79137SRobert Mustacchi static int 309*7fd79137SRobert Mustacchi handle_attr_locdesc(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half attrnum, 310*7fd79137SRobert Mustacchi Dwarf_Error * perr) 311*7fd79137SRobert Mustacchi { 312*7fd79137SRobert Mustacchi int retval = DW_DLV_OK; 313*7fd79137SRobert Mustacchi Dwarf_Attribute attr; 314*7fd79137SRobert Mustacchi Dwarf_Locdesc *llbuf; 315*7fd79137SRobert Mustacchi Dwarf_Signed i; 316*7fd79137SRobert Mustacchi Dwarf_Off offset; 317*7fd79137SRobert Mustacchi Dwarf_Loc *locp; 318*7fd79137SRobert Mustacchi unsigned int entindx; 319*7fd79137SRobert Mustacchi int res; 320*7fd79137SRobert Mustacchi int ares; 321*7fd79137SRobert Mustacchi 322*7fd79137SRobert Mustacchi 323*7fd79137SRobert Mustacchi ares = dwarf_attr(die, attrnum, &attr, perr); 324*7fd79137SRobert Mustacchi if (ares == DW_DLV_OK) { 325*7fd79137SRobert Mustacchi Dwarf_Half form; 326*7fd79137SRobert Mustacchi int fres = dwarf_whatform(attr, &form, perr); 327*7fd79137SRobert Mustacchi 328*7fd79137SRobert Mustacchi if (fres == DW_DLV_OK) { 329*7fd79137SRobert Mustacchi switch (form) { 330*7fd79137SRobert Mustacchi case DW_FORM_block1: 331*7fd79137SRobert Mustacchi case DW_FORM_block2: 332*7fd79137SRobert Mustacchi case DW_FORM_block4: 333*7fd79137SRobert Mustacchi /* must be location description */ 334*7fd79137SRobert Mustacchi res = dwarf_attr_offset(die, attr, &offset, perr); 335*7fd79137SRobert Mustacchi llbuf = 0; 336*7fd79137SRobert Mustacchi if (res == DW_DLV_OK) { 337*7fd79137SRobert Mustacchi Dwarf_Signed count; 338*7fd79137SRobert Mustacchi int lres = dwarf_loclist(attr, &llbuf, &count, perr); 339*7fd79137SRobert Mustacchi if (lres != DW_DLV_OK) { 340*7fd79137SRobert Mustacchi return lres; 341*7fd79137SRobert Mustacchi } 342*7fd79137SRobert Mustacchi if (count != 1) { 343*7fd79137SRobert Mustacchi /* this cannot happen! */ 344*7fd79137SRobert Mustacchi /* perr? */ 345*7fd79137SRobert Mustacchi _dwarf_error(dbg, perr, 346*7fd79137SRobert Mustacchi DW_DLE_LOCDESC_COUNT_WRONG); 347*7fd79137SRobert Mustacchi retval = DW_DLV_ERROR; 348*7fd79137SRobert Mustacchi return retval; 349*7fd79137SRobert Mustacchi } 350*7fd79137SRobert Mustacchi for (i = 0; i < count; ++i) { 351*7fd79137SRobert Mustacchi unsigned int ents = llbuf[i].ld_cents; 352*7fd79137SRobert Mustacchi 353*7fd79137SRobert Mustacchi locp = llbuf[i].ld_s; 354*7fd79137SRobert Mustacchi for (entindx = 0; entindx < ents; entindx++) { 355*7fd79137SRobert Mustacchi Dwarf_Loc *llocp; 356*7fd79137SRobert Mustacchi 357*7fd79137SRobert Mustacchi llocp = locp + entindx; 358*7fd79137SRobert Mustacchi if (llocp->lr_atom == DW_OP_addr) { 359*7fd79137SRobert Mustacchi send_addr_note(DW_SECTION_INFO, offset + 360*7fd79137SRobert Mustacchi llocp->lr_offset + 1 361*7fd79137SRobert Mustacchi /* The offset is the 362*7fd79137SRobert Mustacchi offset of the atom, 363*7fd79137SRobert Mustacchi ** and we know the 364*7fd79137SRobert Mustacchi addr is 1 past it. */ 365*7fd79137SRobert Mustacchi , llocp->lr_number); 366*7fd79137SRobert Mustacchi } 367*7fd79137SRobert Mustacchi } 368*7fd79137SRobert Mustacchi } 369*7fd79137SRobert Mustacchi 370*7fd79137SRobert Mustacchi 371*7fd79137SRobert Mustacchi if (count > 0) { 372*7fd79137SRobert Mustacchi for (i = 0; i < count; ++i) { 373*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, llbuf[i].ld_s, 374*7fd79137SRobert Mustacchi DW_DLA_LOC_BLOCK); 375*7fd79137SRobert Mustacchi } 376*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC); 377*7fd79137SRobert Mustacchi } 378*7fd79137SRobert Mustacchi } else { 379*7fd79137SRobert Mustacchi retval = res; 380*7fd79137SRobert Mustacchi } 381*7fd79137SRobert Mustacchi break; 382*7fd79137SRobert Mustacchi 383*7fd79137SRobert Mustacchi default: 384*7fd79137SRobert Mustacchi /* must be a const offset in debug_loc */ 385*7fd79137SRobert Mustacchi ; /* do nothing */ 386*7fd79137SRobert Mustacchi } 387*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, attr, DW_DLA_ATTR); 388*7fd79137SRobert Mustacchi } /* else error or no entry */ 389*7fd79137SRobert Mustacchi retval = fres; 390*7fd79137SRobert Mustacchi } else { 391*7fd79137SRobert Mustacchi retval = ares; 392*7fd79137SRobert Mustacchi } 393*7fd79137SRobert Mustacchi return retval; 394*7fd79137SRobert Mustacchi } 395*7fd79137SRobert Mustacchi 396*7fd79137SRobert Mustacchi /* 397*7fd79137SRobert Mustacchi Return DW_DLV_OK, or DW_DLV_ERROR 398*7fd79137SRobert Mustacchi 399*7fd79137SRobert Mustacchi Handle the addrs in a single die. 400*7fd79137SRobert Mustacchi */ 401*7fd79137SRobert Mustacchi static int 402*7fd79137SRobert Mustacchi process_this_die_attrs(Dwarf_Debug dbg, Dwarf_Die newdie, int *errval) 403*7fd79137SRobert Mustacchi { 404*7fd79137SRobert Mustacchi Dwarf_Error err; 405*7fd79137SRobert Mustacchi Dwarf_Half i; 406*7fd79137SRobert Mustacchi Dwarf_Half newattrnum; 407*7fd79137SRobert Mustacchi int res; 408*7fd79137SRobert Mustacchi int tres; 409*7fd79137SRobert Mustacchi Dwarf_Half ltag; 410*7fd79137SRobert Mustacchi 411*7fd79137SRobert Mustacchi Dwarf_Off doff; 412*7fd79137SRobert Mustacchi int doffres = dwarf_dieoffset(newdie, &doff, &err); 413*7fd79137SRobert Mustacchi 414*7fd79137SRobert Mustacchi if (doffres != DW_DLV_OK) { 415*7fd79137SRobert Mustacchi if (doffres == DW_DLV_ERROR) { 416*7fd79137SRobert Mustacchi *errval = (int) dwarf_errno(err); 417*7fd79137SRobert Mustacchi } 418*7fd79137SRobert Mustacchi return doffres; 419*7fd79137SRobert Mustacchi } 420*7fd79137SRobert Mustacchi tres = dwarf_tag(newdie, <ag, &err); 421*7fd79137SRobert Mustacchi if (tres != DW_DLV_OK) { 422*7fd79137SRobert Mustacchi return tres; 423*7fd79137SRobert Mustacchi } 424*7fd79137SRobert Mustacchi if (DW_TAG_compile_unit == ltag) { 425*7fd79137SRobert Mustacchi /* because of the way the dwarf_line code works, we do lines 426*7fd79137SRobert Mustacchi only per compile unit. This may turn out to be wrong if 427*7fd79137SRobert Mustacchi we have lines left unconnected to a CU. of course such 428*7fd79137SRobert Mustacchi lines will not, at present, be used by gnome. This is 429*7fd79137SRobert Mustacchi not ideal as coded due to the dwarf_line.c issue. */ 430*7fd79137SRobert Mustacchi int lres = handle_debug_line(dbg, newdie, send_addr_note, errval); 431*7fd79137SRobert Mustacchi if (lres == DW_DLV_ERROR) { 432*7fd79137SRobert Mustacchi return lres; 433*7fd79137SRobert Mustacchi } 434*7fd79137SRobert Mustacchi } 435*7fd79137SRobert Mustacchi 436*7fd79137SRobert Mustacchi for (i = 0; i < sizeof(might_have_addr) / sizeof(int); i++) { 437*7fd79137SRobert Mustacchi int resattr; 438*7fd79137SRobert Mustacchi Dwarf_Bool hasattr; 439*7fd79137SRobert Mustacchi 440*7fd79137SRobert Mustacchi newattrnum = might_have_addr[i]; 441*7fd79137SRobert Mustacchi err = 0; 442*7fd79137SRobert Mustacchi resattr = dwarf_hasattr(newdie, newattrnum, &hasattr, &err); 443*7fd79137SRobert Mustacchi if (DW_DLV_OK == resattr) { 444*7fd79137SRobert Mustacchi if (hasattr) { 445*7fd79137SRobert Mustacchi res = handle_attr_addr(dbg, newdie, newattrnum, &err); 446*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 447*7fd79137SRobert Mustacchi *errval = (int) dwarf_errno(err); 448*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 449*7fd79137SRobert Mustacchi } 450*7fd79137SRobert Mustacchi } 451*7fd79137SRobert Mustacchi } else { 452*7fd79137SRobert Mustacchi if (resattr == DW_DLV_ERROR) { 453*7fd79137SRobert Mustacchi *errval = (int) dwarf_errno(err); 454*7fd79137SRobert Mustacchi return resattr; 455*7fd79137SRobert Mustacchi } 456*7fd79137SRobert Mustacchi } 457*7fd79137SRobert Mustacchi } 458*7fd79137SRobert Mustacchi for (i = 0; i < sizeof(might_have_locdesc) / sizeof(int); i++) { 459*7fd79137SRobert Mustacchi int resattr; 460*7fd79137SRobert Mustacchi Dwarf_Bool hasattr; 461*7fd79137SRobert Mustacchi 462*7fd79137SRobert Mustacchi newattrnum = might_have_locdesc[i]; 463*7fd79137SRobert Mustacchi err = 0; 464*7fd79137SRobert Mustacchi resattr = dwarf_hasattr(newdie, newattrnum, &hasattr, &err); 465*7fd79137SRobert Mustacchi if (DW_DLV_OK == resattr) { 466*7fd79137SRobert Mustacchi if (hasattr) { 467*7fd79137SRobert Mustacchi res = 468*7fd79137SRobert Mustacchi handle_attr_locdesc(dbg, newdie, newattrnum, &err); 469*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 470*7fd79137SRobert Mustacchi *errval = (int) dwarf_errno(err); 471*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 472*7fd79137SRobert Mustacchi } 473*7fd79137SRobert Mustacchi } 474*7fd79137SRobert Mustacchi } else { 475*7fd79137SRobert Mustacchi if (resattr == DW_DLV_ERROR) { 476*7fd79137SRobert Mustacchi *errval = (int) dwarf_errno(err); 477*7fd79137SRobert Mustacchi return resattr; 478*7fd79137SRobert Mustacchi } 479*7fd79137SRobert Mustacchi } 480*7fd79137SRobert Mustacchi } 481*7fd79137SRobert Mustacchi 482*7fd79137SRobert Mustacchi return DW_DLV_OK; 483*7fd79137SRobert Mustacchi } 484*7fd79137SRobert Mustacchi 485*7fd79137SRobert Mustacchi /* 486*7fd79137SRobert Mustacchi Handle siblings as a list, 487*7fd79137SRobert Mustacchi Do children by recursing. 488*7fd79137SRobert Mustacchi Effectively this is walking the tree preorder. 489*7fd79137SRobert Mustacchi 490*7fd79137SRobert Mustacchi This dealloc's any die passed to it, so the 491*7fd79137SRobert Mustacchi caller should not do that dealloc. 492*7fd79137SRobert Mustacchi It seems more logical to have the one causing 493*7fd79137SRobert Mustacchi the alloc to do the dealloc, but that way this 494*7fd79137SRobert Mustacchi routine became a mess. 495*7fd79137SRobert Mustacchi 496*7fd79137SRobert Mustacchi */ 497*7fd79137SRobert Mustacchi static int 498*7fd79137SRobert Mustacchi do_this_die_and_dealloc(Dwarf_Debug dbg, Dwarf_Die die, int *errval) 499*7fd79137SRobert Mustacchi { 500*7fd79137SRobert Mustacchi 501*7fd79137SRobert Mustacchi Dwarf_Die prevdie = 0; 502*7fd79137SRobert Mustacchi Dwarf_Die newdie = die; 503*7fd79137SRobert Mustacchi Dwarf_Error err = 0; 504*7fd79137SRobert Mustacchi int res = 0; 505*7fd79137SRobert Mustacchi int sibres = DW_DLV_OK; 506*7fd79137SRobert Mustacchi int tres = DW_DLV_OK; 507*7fd79137SRobert Mustacchi Dwarf_Die sibdie; 508*7fd79137SRobert Mustacchi 509*7fd79137SRobert Mustacchi while (sibres == DW_DLV_OK) { 510*7fd79137SRobert Mustacchi Dwarf_Die ch_die; 511*7fd79137SRobert Mustacchi 512*7fd79137SRobert Mustacchi 513*7fd79137SRobert Mustacchi res = process_this_die_attrs(dbg, newdie, errval); 514*7fd79137SRobert Mustacchi switch (res) { 515*7fd79137SRobert Mustacchi case DW_DLV_OK: 516*7fd79137SRobert Mustacchi break; 517*7fd79137SRobert Mustacchi case DW_DLV_NO_ENTRY: 518*7fd79137SRobert Mustacchi break; 519*7fd79137SRobert Mustacchi default: 520*7fd79137SRobert Mustacchi case DW_DLV_ERROR: 521*7fd79137SRobert Mustacchi if (prevdie) { 522*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, prevdie, DW_DLA_DIE); 523*7fd79137SRobert Mustacchi prevdie = 0; 524*7fd79137SRobert Mustacchi } 525*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 526*7fd79137SRobert Mustacchi } 527*7fd79137SRobert Mustacchi 528*7fd79137SRobert Mustacchi tres = dwarf_child(newdie, &ch_die, &err); 529*7fd79137SRobert Mustacchi 530*7fd79137SRobert Mustacchi if (tres == DW_DLV_OK) { 531*7fd79137SRobert Mustacchi res = do_this_die_and_dealloc(dbg, ch_die, errval); 532*7fd79137SRobert Mustacchi switch (res) { 533*7fd79137SRobert Mustacchi case DW_DLV_OK: 534*7fd79137SRobert Mustacchi break; 535*7fd79137SRobert Mustacchi case DW_DLV_NO_ENTRY: 536*7fd79137SRobert Mustacchi break; 537*7fd79137SRobert Mustacchi default: 538*7fd79137SRobert Mustacchi case DW_DLV_ERROR: 539*7fd79137SRobert Mustacchi if (prevdie) { 540*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, prevdie, DW_DLA_DIE); 541*7fd79137SRobert Mustacchi prevdie = 0; 542*7fd79137SRobert Mustacchi } 543*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 544*7fd79137SRobert Mustacchi } 545*7fd79137SRobert Mustacchi } else if (tres == DW_DLV_ERROR) { 546*7fd79137SRobert Mustacchi /* An error! */ 547*7fd79137SRobert Mustacchi *errval = (int) dwarf_errno(err); 548*7fd79137SRobert Mustacchi if (prevdie) { 549*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, prevdie, DW_DLA_DIE); 550*7fd79137SRobert Mustacchi prevdie = 0; 551*7fd79137SRobert Mustacchi } 552*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, err, DW_DLA_ERROR); 553*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 554*7fd79137SRobert Mustacchi } /* else was NO ENTRY */ 555*7fd79137SRobert Mustacchi prevdie = newdie; 556*7fd79137SRobert Mustacchi sibdie = 0; 557*7fd79137SRobert Mustacchi sibres = dwarf_siblingof(dbg, newdie, &sibdie, &err); 558*7fd79137SRobert Mustacchi if (prevdie) { 559*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, prevdie, DW_DLA_DIE); 560*7fd79137SRobert Mustacchi prevdie = 0; 561*7fd79137SRobert Mustacchi } 562*7fd79137SRobert Mustacchi newdie = sibdie; 563*7fd79137SRobert Mustacchi 564*7fd79137SRobert Mustacchi } 565*7fd79137SRobert Mustacchi if (sibres == DW_DLV_NO_ENTRY) { 566*7fd79137SRobert Mustacchi return DW_DLV_OK; 567*7fd79137SRobert Mustacchi } 568*7fd79137SRobert Mustacchi /* error. */ 569*7fd79137SRobert Mustacchi *errval = (int) dwarf_errno(err); 570*7fd79137SRobert Mustacchi if (prevdie) { 571*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, prevdie, DW_DLA_DIE); 572*7fd79137SRobert Mustacchi prevdie = 0; 573*7fd79137SRobert Mustacchi } 574*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, err, DW_DLA_ERROR); 575*7fd79137SRobert Mustacchi return DW_DLV_ERROR; 576*7fd79137SRobert Mustacchi 577*7fd79137SRobert Mustacchi } 578*7fd79137SRobert Mustacchi 579*7fd79137SRobert Mustacchi 580*7fd79137SRobert Mustacchi static int 581*7fd79137SRobert Mustacchi handle_debug_frame(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func, 582*7fd79137SRobert Mustacchi int *errval) 583*7fd79137SRobert Mustacchi { 584*7fd79137SRobert Mustacchi int retval = DW_DLV_OK; 585*7fd79137SRobert Mustacchi int res; 586*7fd79137SRobert Mustacchi Dwarf_Error err; 587*7fd79137SRobert Mustacchi Dwarf_Addr *addrlist; 588*7fd79137SRobert Mustacchi Dwarf_Off *offsetlist; 589*7fd79137SRobert Mustacchi Dwarf_Signed count; 590*7fd79137SRobert Mustacchi int i; 591*7fd79137SRobert Mustacchi 592*7fd79137SRobert Mustacchi res = 593*7fd79137SRobert Mustacchi _dwarf_frame_address_offsets(dbg, &addrlist, &offsetlist, 594*7fd79137SRobert Mustacchi &count, &err); 595*7fd79137SRobert Mustacchi if (res == DW_DLV_OK) { 596*7fd79137SRobert Mustacchi for (i = 0; i < count; i++) { 597*7fd79137SRobert Mustacchi cb_func(DW_SECTION_FRAME, offsetlist[i], addrlist[i]); 598*7fd79137SRobert Mustacchi } 599*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, offsetlist, DW_DLA_ADDR); 600*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, addrlist, DW_DLA_ADDR); 601*7fd79137SRobert Mustacchi } else if (res == DW_DLV_NO_ENTRY) { 602*7fd79137SRobert Mustacchi retval = res; 603*7fd79137SRobert Mustacchi } else { 604*7fd79137SRobert Mustacchi *errval = (int) dwarf_errno(err); 605*7fd79137SRobert Mustacchi retval = DW_DLV_ERROR; 606*7fd79137SRobert Mustacchi } 607*7fd79137SRobert Mustacchi return retval; 608*7fd79137SRobert Mustacchi 609*7fd79137SRobert Mustacchi } 610*7fd79137SRobert Mustacchi static int 611*7fd79137SRobert Mustacchi handle_debug_aranges(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func, 612*7fd79137SRobert Mustacchi int *errval) 613*7fd79137SRobert Mustacchi { 614*7fd79137SRobert Mustacchi int retval = DW_DLV_OK; 615*7fd79137SRobert Mustacchi Dwarf_Error err; 616*7fd79137SRobert Mustacchi Dwarf_Addr *aranges; 617*7fd79137SRobert Mustacchi Dwarf_Signed count; 618*7fd79137SRobert Mustacchi int indx; 619*7fd79137SRobert Mustacchi Dwarf_Off *offsets; 620*7fd79137SRobert Mustacchi 621*7fd79137SRobert Mustacchi retval = 622*7fd79137SRobert Mustacchi _dwarf_get_aranges_addr_offsets(dbg, &aranges, &offsets, &count, 623*7fd79137SRobert Mustacchi &err); 624*7fd79137SRobert Mustacchi if (retval == DW_DLV_OK) { 625*7fd79137SRobert Mustacchi if (count == 0) { 626*7fd79137SRobert Mustacchi retval = DW_DLV_NO_ENTRY; 627*7fd79137SRobert Mustacchi } else { 628*7fd79137SRobert Mustacchi for (indx = 0; indx < count; indx++) { 629*7fd79137SRobert Mustacchi cb_func(DW_SECTION_ARANGES, offsets[indx], 630*7fd79137SRobert Mustacchi aranges[indx]); 631*7fd79137SRobert Mustacchi } 632*7fd79137SRobert Mustacchi } 633*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, aranges, DW_DLA_ADDR); 634*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, offsets, DW_DLA_ADDR); 635*7fd79137SRobert Mustacchi } else if (retval == DW_DLV_NO_ENTRY) { 636*7fd79137SRobert Mustacchi ; /* do nothing */ 637*7fd79137SRobert Mustacchi } else { 638*7fd79137SRobert Mustacchi *errval = (int) dwarf_errno(err); 639*7fd79137SRobert Mustacchi retval = DW_DLV_ERROR; 640*7fd79137SRobert Mustacchi } 641*7fd79137SRobert Mustacchi return retval; 642*7fd79137SRobert Mustacchi } 643*7fd79137SRobert Mustacchi static int 644*7fd79137SRobert Mustacchi handle_debug_line(Dwarf_Debug dbg, Dwarf_Die cu_die, 645*7fd79137SRobert Mustacchi Dwarf_addr_callback_func cb_func, int *errval) 646*7fd79137SRobert Mustacchi { 647*7fd79137SRobert Mustacchi int retval = DW_DLV_OK; 648*7fd79137SRobert Mustacchi int res; 649*7fd79137SRobert Mustacchi Dwarf_Error err; 650*7fd79137SRobert Mustacchi Dwarf_Addr *addrlist; 651*7fd79137SRobert Mustacchi Dwarf_Off *offsetlist; 652*7fd79137SRobert Mustacchi Dwarf_Unsigned count; 653*7fd79137SRobert Mustacchi Dwarf_Unsigned i; 654*7fd79137SRobert Mustacchi 655*7fd79137SRobert Mustacchi res = 656*7fd79137SRobert Mustacchi _dwarf_line_address_offsets(dbg, cu_die, &addrlist, &offsetlist, 657*7fd79137SRobert Mustacchi &count, &err); 658*7fd79137SRobert Mustacchi if (res == DW_DLV_OK) { 659*7fd79137SRobert Mustacchi for (i = 0; i < count; i++) { 660*7fd79137SRobert Mustacchi cb_func(DW_SECTION_LINE, offsetlist[i], addrlist[i]); 661*7fd79137SRobert Mustacchi 662*7fd79137SRobert Mustacchi } 663*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, offsetlist, DW_DLA_ADDR); 664*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, addrlist, DW_DLA_ADDR); 665*7fd79137SRobert Mustacchi } else if (res == DW_DLV_NO_ENTRY) { 666*7fd79137SRobert Mustacchi retval = res; 667*7fd79137SRobert Mustacchi } else { 668*7fd79137SRobert Mustacchi *errval = (int) dwarf_errno(err); 669*7fd79137SRobert Mustacchi retval = DW_DLV_ERROR; 670*7fd79137SRobert Mustacchi } 671*7fd79137SRobert Mustacchi return retval; 672*7fd79137SRobert Mustacchi } 673*7fd79137SRobert Mustacchi 674*7fd79137SRobert Mustacchi /* 675*7fd79137SRobert Mustacchi We need to add support for this. Currently we do not 676*7fd79137SRobert Mustacchi generate this section. 677*7fd79137SRobert Mustacchi FIX! 678*7fd79137SRobert Mustacchi */ 679*7fd79137SRobert Mustacchi static int 680*7fd79137SRobert Mustacchi handle_debug_loc(void) 681*7fd79137SRobert Mustacchi { 682*7fd79137SRobert Mustacchi int retval = DW_DLV_NO_ENTRY; 683*7fd79137SRobert Mustacchi 684*7fd79137SRobert Mustacchi return retval; 685*7fd79137SRobert Mustacchi } 686