1*7fd79137SRobert Mustacchi /* 2*7fd79137SRobert Mustacchi 3*7fd79137SRobert Mustacchi Copyright (C) 2000,2004,2006 Silicon Graphics, Inc. All Rights Reserved. 4*7fd79137SRobert Mustacchi Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved. 5*7fd79137SRobert Mustacchi Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. 6*7fd79137SRobert Mustacchi 7*7fd79137SRobert Mustacchi This program is free software; you can redistribute it and/or modify it 8*7fd79137SRobert Mustacchi under the terms of version 2.1 of the GNU Lesser General Public License 9*7fd79137SRobert Mustacchi as published by the Free Software Foundation. 10*7fd79137SRobert Mustacchi 11*7fd79137SRobert Mustacchi This program is distributed in the hope that it would be useful, but 12*7fd79137SRobert Mustacchi WITHOUT ANY WARRANTY; without even the implied warranty of 13*7fd79137SRobert Mustacchi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 14*7fd79137SRobert Mustacchi 15*7fd79137SRobert Mustacchi Further, this software is distributed without any warranty that it is 16*7fd79137SRobert Mustacchi free of the rightful claim of any third person regarding infringement 17*7fd79137SRobert Mustacchi or the like. Any license provided herein, whether implied or 18*7fd79137SRobert Mustacchi otherwise, applies only to this software file. Patent licenses, if 19*7fd79137SRobert Mustacchi any, provided herein do not apply to combinations of this program with 20*7fd79137SRobert Mustacchi other software, or any other product whatsoever. 21*7fd79137SRobert Mustacchi 22*7fd79137SRobert Mustacchi You should have received a copy of the GNU Lesser General Public 23*7fd79137SRobert Mustacchi License along with this program; if not, write the Free Software 24*7fd79137SRobert Mustacchi Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, 25*7fd79137SRobert Mustacchi USA. 26*7fd79137SRobert Mustacchi 27*7fd79137SRobert Mustacchi Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, 28*7fd79137SRobert Mustacchi Mountain View, CA 94043, or: 29*7fd79137SRobert Mustacchi 30*7fd79137SRobert Mustacchi http://www.sgi.com 31*7fd79137SRobert Mustacchi 32*7fd79137SRobert Mustacchi For further information regarding this notice, see: 33*7fd79137SRobert Mustacchi 34*7fd79137SRobert Mustacchi http://oss.sgi.com/projects/GenInfo/NoticeExplan 35*7fd79137SRobert Mustacchi 36*7fd79137SRobert Mustacchi */ 37*7fd79137SRobert Mustacchi /* 38*7fd79137SRobert Mustacchi SGI has moved from the Crittenden Lane address. 39*7fd79137SRobert Mustacchi */ 40*7fd79137SRobert Mustacchi 41*7fd79137SRobert Mustacchi 42*7fd79137SRobert Mustacchi 43*7fd79137SRobert Mustacchi 44*7fd79137SRobert Mustacchi 45*7fd79137SRobert Mustacchi #include "config.h" 46*7fd79137SRobert Mustacchi #include "libdwarfdefs.h" 47*7fd79137SRobert Mustacchi #include <stdio.h> 48*7fd79137SRobert Mustacchi #include <string.h> 49*7fd79137SRobert Mustacchi #ifdef HAVE_ELFACCESS_H 50*7fd79137SRobert Mustacchi #include <elfaccess.h> 51*7fd79137SRobert Mustacchi #endif 52*7fd79137SRobert Mustacchi #include "pro_incl.h" 53*7fd79137SRobert Mustacchi #include "pro_section.h" 54*7fd79137SRobert Mustacchi #include "pro_line.h" 55*7fd79137SRobert Mustacchi #include "pro_frame.h" 56*7fd79137SRobert Mustacchi #include "pro_die.h" 57*7fd79137SRobert Mustacchi #include "pro_macinfo.h" 58*7fd79137SRobert Mustacchi #include "pro_types.h" 59*7fd79137SRobert Mustacchi 60*7fd79137SRobert Mustacchi #ifndef SHF_MIPS_NOSTRIP 61*7fd79137SRobert Mustacchi /* if this is not defined, we probably don't need it: just use 0 */ 62*7fd79137SRobert Mustacchi #define SHF_MIPS_NOSTRIP 0 63*7fd79137SRobert Mustacchi #endif 64*7fd79137SRobert Mustacchi #ifndef R_MIPS_NONE 65*7fd79137SRobert Mustacchi #define R_MIPS_NONE 0 66*7fd79137SRobert Mustacchi #endif 67*7fd79137SRobert Mustacchi 68*7fd79137SRobert Mustacchi #ifndef TRUE 69*7fd79137SRobert Mustacchi #define TRUE 1 70*7fd79137SRobert Mustacchi #endif 71*7fd79137SRobert Mustacchi #ifndef FALSE 72*7fd79137SRobert Mustacchi #define FALSE 0 73*7fd79137SRobert Mustacchi #endif 74*7fd79137SRobert Mustacchi 75*7fd79137SRobert Mustacchi /* must match up with pro_section.h defines of DEBUG_INFO etc 76*7fd79137SRobert Mustacchi and sectnames (below). REL_SEC_PREFIX is either ".rel" or ".rela" 77*7fd79137SRobert Mustacchi see pro_incl.h 78*7fd79137SRobert Mustacchi */ 79*7fd79137SRobert Mustacchi char *_dwarf_rel_section_names[] = { 80*7fd79137SRobert Mustacchi REL_SEC_PREFIX ".debug_info", 81*7fd79137SRobert Mustacchi REL_SEC_PREFIX ".debug_line", 82*7fd79137SRobert Mustacchi REL_SEC_PREFIX ".debug_abbrev", /* no relocations on this, really */ 83*7fd79137SRobert Mustacchi REL_SEC_PREFIX ".debug_frame", 84*7fd79137SRobert Mustacchi REL_SEC_PREFIX ".debug_aranges", 85*7fd79137SRobert Mustacchi REL_SEC_PREFIX ".debug_pubnames", 86*7fd79137SRobert Mustacchi REL_SEC_PREFIX ".debug_str", 87*7fd79137SRobert Mustacchi REL_SEC_PREFIX ".debug_funcnames", /* sgi extension */ 88*7fd79137SRobert Mustacchi REL_SEC_PREFIX ".debug_typenames", /* sgi extension */ 89*7fd79137SRobert Mustacchi REL_SEC_PREFIX ".debug_varnames", /* sgi extension */ 90*7fd79137SRobert Mustacchi REL_SEC_PREFIX ".debug_weaknames", /* sgi extension */ 91*7fd79137SRobert Mustacchi REL_SEC_PREFIX ".debug_macinfo", 92*7fd79137SRobert Mustacchi REL_SEC_PREFIX ".debug_loc" 93*7fd79137SRobert Mustacchi }; 94*7fd79137SRobert Mustacchi 95*7fd79137SRobert Mustacchi /* names of sections. Ensure that it matches the defines 96*7fd79137SRobert Mustacchi in pro_section.h, in the same order 97*7fd79137SRobert Mustacchi Must match also _dwarf_rel_section_names above 98*7fd79137SRobert Mustacchi */ 99*7fd79137SRobert Mustacchi char *_dwarf_sectnames[] = { 100*7fd79137SRobert Mustacchi ".debug_info", 101*7fd79137SRobert Mustacchi ".debug_line", 102*7fd79137SRobert Mustacchi ".debug_abbrev", 103*7fd79137SRobert Mustacchi ".debug_frame", 104*7fd79137SRobert Mustacchi ".debug_aranges", 105*7fd79137SRobert Mustacchi ".debug_pubnames", 106*7fd79137SRobert Mustacchi ".debug_str", 107*7fd79137SRobert Mustacchi ".debug_funcnames", /* sgi extension */ 108*7fd79137SRobert Mustacchi ".debug_typenames", /* sgi extension */ 109*7fd79137SRobert Mustacchi ".debug_varnames", /* sgi extension */ 110*7fd79137SRobert Mustacchi ".debug_weaknames", /* sgi extension */ 111*7fd79137SRobert Mustacchi ".debug_macinfo", 112*7fd79137SRobert Mustacchi ".debug_loc" 113*7fd79137SRobert Mustacchi }; 114*7fd79137SRobert Mustacchi 115*7fd79137SRobert Mustacchi 116*7fd79137SRobert Mustacchi 117*7fd79137SRobert Mustacchi 118*7fd79137SRobert Mustacchi static Dwarf_Ubyte std_opcode_len[] = { 0, /* DW_LNS_copy */ 119*7fd79137SRobert Mustacchi 1, /* DW_LNS_advance_pc */ 120*7fd79137SRobert Mustacchi 1, /* DW_LNS_advance_line */ 121*7fd79137SRobert Mustacchi 1, /* DW_LNS_set_file */ 122*7fd79137SRobert Mustacchi 1, /* DW_LNS_set_column */ 123*7fd79137SRobert Mustacchi 0, /* DW_LNS_negate_stmt */ 124*7fd79137SRobert Mustacchi 0, /* DW_LNS_set_basic_block */ 125*7fd79137SRobert Mustacchi 0, /* DW_LNS_const_add_pc */ 126*7fd79137SRobert Mustacchi 1, /* DW_LNS_fixed_advance_pc */ 127*7fd79137SRobert Mustacchi }; 128*7fd79137SRobert Mustacchi 129*7fd79137SRobert Mustacchi /* struct to hold relocation entries. Its mantained as a linked 130*7fd79137SRobert Mustacchi list of relocation structs, and will then be written at as a 131*7fd79137SRobert Mustacchi whole into the relocation section. Whether its 32 bit or 132*7fd79137SRobert Mustacchi 64 bit will be obtained from Dwarf_Debug pointer. 133*7fd79137SRobert Mustacchi */ 134*7fd79137SRobert Mustacchi 135*7fd79137SRobert Mustacchi typedef struct Dwarf_P_Rel_s *Dwarf_P_Rel; 136*7fd79137SRobert Mustacchi struct Dwarf_P_Rel_s { 137*7fd79137SRobert Mustacchi Dwarf_P_Rel dr_next; 138*7fd79137SRobert Mustacchi void *dr_rel_datap; 139*7fd79137SRobert Mustacchi }; 140*7fd79137SRobert Mustacchi typedef struct Dwarf_P_Rel_Head_s *Dwarf_P_Rel_Head; 141*7fd79137SRobert Mustacchi struct Dwarf_P_Rel_Head_s { 142*7fd79137SRobert Mustacchi struct Dwarf_P_Rel_s *drh_head; 143*7fd79137SRobert Mustacchi struct Dwarf_P_Rel_s *drh_tail; 144*7fd79137SRobert Mustacchi }; 145*7fd79137SRobert Mustacchi 146*7fd79137SRobert Mustacchi static int _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, 147*7fd79137SRobert Mustacchi Dwarf_Error * error); 148*7fd79137SRobert Mustacchi static int _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, 149*7fd79137SRobert Mustacchi Dwarf_Error * error); 150*7fd79137SRobert Mustacchi static int _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, 151*7fd79137SRobert Mustacchi Dwarf_Error * error); 152*7fd79137SRobert Mustacchi static Dwarf_P_Abbrev _dwarf_pro_getabbrev(Dwarf_P_Die, Dwarf_P_Abbrev); 153*7fd79137SRobert Mustacchi static int _dwarf_pro_match_attr 154*7fd79137SRobert Mustacchi (Dwarf_P_Attribute, Dwarf_P_Abbrev, int no_attr); 155*7fd79137SRobert Mustacchi 156*7fd79137SRobert Mustacchi /* these macros used as return value for below functions */ 157*7fd79137SRobert Mustacchi #define OPC_INCS_ZERO -1 158*7fd79137SRobert Mustacchi #define OPC_OUT_OF_RANGE -2 159*7fd79137SRobert Mustacchi #define LINE_OUT_OF_RANGE -3 160*7fd79137SRobert Mustacchi static int _dwarf_pro_get_opc(Dwarf_Unsigned addr_adv, int line_adv); 161*7fd79137SRobert Mustacchi 162*7fd79137SRobert Mustacchi 163*7fd79137SRobert Mustacchi /* BEGIN_LEN_SIZE is the size of the 'length' field in total. 164*7fd79137SRobert Mustacchi Which may be 4,8, or 12 bytes! 165*7fd79137SRobert Mustacchi 4 is standard DWARF2. 166*7fd79137SRobert Mustacchi 8 is non-standard MIPS-IRIX 64-bit. 167*7fd79137SRobert Mustacchi 12 is standard DWARF3 for 64 bit offsets. 168*7fd79137SRobert Mustacchi Used in various routines: local variable names 169*7fd79137SRobert Mustacchi must match the names here. 170*7fd79137SRobert Mustacchi */ 171*7fd79137SRobert Mustacchi #define BEGIN_LEN_SIZE (uwordb_size + extension_size) 172*7fd79137SRobert Mustacchi 173*7fd79137SRobert Mustacchi /* 174*7fd79137SRobert Mustacchi Return TRUE if we need the section, FALSE otherwise 175*7fd79137SRobert Mustacchi 176*7fd79137SRobert Mustacchi If any of the 'line-data-related' calls were made 177*7fd79137SRobert Mustacchi including file or directory entries, 178*7fd79137SRobert Mustacchi produce .debug_line . 179*7fd79137SRobert Mustacchi 180*7fd79137SRobert Mustacchi */ 181*7fd79137SRobert Mustacchi static int 182*7fd79137SRobert Mustacchi dwarf_need_debug_line_section(Dwarf_P_Debug dbg) 183*7fd79137SRobert Mustacchi { 184*7fd79137SRobert Mustacchi if (dbg->de_lines == NULL && dbg->de_file_entries == NULL 185*7fd79137SRobert Mustacchi && dbg->de_inc_dirs == NULL) { 186*7fd79137SRobert Mustacchi return FALSE; 187*7fd79137SRobert Mustacchi } 188*7fd79137SRobert Mustacchi return TRUE; 189*7fd79137SRobert Mustacchi } 190*7fd79137SRobert Mustacchi 191*7fd79137SRobert Mustacchi /* 192*7fd79137SRobert Mustacchi Convert debug information to a format such that 193*7fd79137SRobert Mustacchi it can be written on disk. 194*7fd79137SRobert Mustacchi Called exactly once per execution. 195*7fd79137SRobert Mustacchi */ 196*7fd79137SRobert Mustacchi Dwarf_Signed 197*7fd79137SRobert Mustacchi dwarf_transform_to_disk_form(Dwarf_P_Debug dbg, Dwarf_Error * error) 198*7fd79137SRobert Mustacchi { 199*7fd79137SRobert Mustacchi /* 200*7fd79137SRobert Mustacchi Section data in written out in a number of buffers. Each 201*7fd79137SRobert Mustacchi _generate_*() function returns a cumulative count of buffers for 202*7fd79137SRobert Mustacchi all the sections. get_section_bytes() returns pointers to these 203*7fd79137SRobert Mustacchi buffers one at a time. */ 204*7fd79137SRobert Mustacchi int nbufs = 0; 205*7fd79137SRobert Mustacchi int sect = 0; 206*7fd79137SRobert Mustacchi int err = 0; 207*7fd79137SRobert Mustacchi Dwarf_Unsigned du = 0; 208*7fd79137SRobert Mustacchi 209*7fd79137SRobert Mustacchi if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) { 210*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_NOCOUNT); 211*7fd79137SRobert Mustacchi } 212*7fd79137SRobert Mustacchi 213*7fd79137SRobert Mustacchi /* Create dwarf section headers */ 214*7fd79137SRobert Mustacchi for (sect = 0; sect < NUM_DEBUG_SECTIONS; sect++) { 215*7fd79137SRobert Mustacchi long flags = 0; 216*7fd79137SRobert Mustacchi 217*7fd79137SRobert Mustacchi switch (sect) { 218*7fd79137SRobert Mustacchi 219*7fd79137SRobert Mustacchi case DEBUG_INFO: 220*7fd79137SRobert Mustacchi if (dbg->de_dies == NULL) 221*7fd79137SRobert Mustacchi continue; 222*7fd79137SRobert Mustacchi break; 223*7fd79137SRobert Mustacchi 224*7fd79137SRobert Mustacchi case DEBUG_LINE: 225*7fd79137SRobert Mustacchi if (dwarf_need_debug_line_section(dbg) == FALSE) { 226*7fd79137SRobert Mustacchi continue; 227*7fd79137SRobert Mustacchi } 228*7fd79137SRobert Mustacchi break; 229*7fd79137SRobert Mustacchi 230*7fd79137SRobert Mustacchi case DEBUG_ABBREV: 231*7fd79137SRobert Mustacchi if (dbg->de_dies == NULL) 232*7fd79137SRobert Mustacchi continue; 233*7fd79137SRobert Mustacchi break; 234*7fd79137SRobert Mustacchi 235*7fd79137SRobert Mustacchi case DEBUG_FRAME: 236*7fd79137SRobert Mustacchi if (dbg->de_frame_cies == NULL) 237*7fd79137SRobert Mustacchi continue; 238*7fd79137SRobert Mustacchi flags = SHF_MIPS_NOSTRIP; 239*7fd79137SRobert Mustacchi break; 240*7fd79137SRobert Mustacchi 241*7fd79137SRobert Mustacchi case DEBUG_ARANGES: 242*7fd79137SRobert Mustacchi if (dbg->de_arange == NULL) 243*7fd79137SRobert Mustacchi continue; 244*7fd79137SRobert Mustacchi break; 245*7fd79137SRobert Mustacchi 246*7fd79137SRobert Mustacchi case DEBUG_PUBNAMES: 247*7fd79137SRobert Mustacchi if (dbg->de_simple_name_headers[dwarf_snk_pubname]. 248*7fd79137SRobert Mustacchi sn_head == NULL) 249*7fd79137SRobert Mustacchi continue; 250*7fd79137SRobert Mustacchi break; 251*7fd79137SRobert Mustacchi 252*7fd79137SRobert Mustacchi case DEBUG_STR: 253*7fd79137SRobert Mustacchi if (dbg->de_strings == NULL) 254*7fd79137SRobert Mustacchi continue; 255*7fd79137SRobert Mustacchi break; 256*7fd79137SRobert Mustacchi 257*7fd79137SRobert Mustacchi case DEBUG_FUNCNAMES: 258*7fd79137SRobert Mustacchi if (dbg->de_simple_name_headers[dwarf_snk_funcname]. 259*7fd79137SRobert Mustacchi sn_head == NULL) 260*7fd79137SRobert Mustacchi continue; 261*7fd79137SRobert Mustacchi break; 262*7fd79137SRobert Mustacchi 263*7fd79137SRobert Mustacchi case DEBUG_TYPENAMES: 264*7fd79137SRobert Mustacchi if (dbg->de_simple_name_headers[dwarf_snk_typename]. 265*7fd79137SRobert Mustacchi sn_head == NULL) 266*7fd79137SRobert Mustacchi continue; 267*7fd79137SRobert Mustacchi break; 268*7fd79137SRobert Mustacchi 269*7fd79137SRobert Mustacchi case DEBUG_VARNAMES: 270*7fd79137SRobert Mustacchi if (dbg->de_simple_name_headers[dwarf_snk_varname]. 271*7fd79137SRobert Mustacchi sn_head == NULL) 272*7fd79137SRobert Mustacchi continue; 273*7fd79137SRobert Mustacchi break; 274*7fd79137SRobert Mustacchi 275*7fd79137SRobert Mustacchi case DEBUG_WEAKNAMES: 276*7fd79137SRobert Mustacchi if (dbg->de_simple_name_headers[dwarf_snk_weakname]. 277*7fd79137SRobert Mustacchi sn_head == NULL) 278*7fd79137SRobert Mustacchi continue; 279*7fd79137SRobert Mustacchi break; 280*7fd79137SRobert Mustacchi 281*7fd79137SRobert Mustacchi case DEBUG_MACINFO: 282*7fd79137SRobert Mustacchi if (dbg->de_first_macinfo == NULL) 283*7fd79137SRobert Mustacchi continue; 284*7fd79137SRobert Mustacchi break; 285*7fd79137SRobert Mustacchi case DEBUG_LOC: 286*7fd79137SRobert Mustacchi /* not handled yet */ 287*7fd79137SRobert Mustacchi continue; 288*7fd79137SRobert Mustacchi default: 289*7fd79137SRobert Mustacchi /* logic error: missing a case */ 290*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_NOCOUNT); 291*7fd79137SRobert Mustacchi } 292*7fd79137SRobert Mustacchi { 293*7fd79137SRobert Mustacchi int new_base_elf_sect; 294*7fd79137SRobert Mustacchi 295*7fd79137SRobert Mustacchi if (dbg->de_callback_func_b) { 296*7fd79137SRobert Mustacchi new_base_elf_sect = 297*7fd79137SRobert Mustacchi dbg->de_callback_func_b(_dwarf_sectnames[sect], 298*7fd79137SRobert Mustacchi /* rec size */ 1, 299*7fd79137SRobert Mustacchi SECTION_TYPE, 300*7fd79137SRobert Mustacchi flags, SHN_UNDEF, 0, &du, &err); 301*7fd79137SRobert Mustacchi 302*7fd79137SRobert Mustacchi } else { 303*7fd79137SRobert Mustacchi int name_idx = 0; 304*7fd79137SRobert Mustacchi new_base_elf_sect = dbg->de_callback_func( 305*7fd79137SRobert Mustacchi _dwarf_sectnames[sect], 306*7fd79137SRobert Mustacchi dbg->de_relocation_record_size, 307*7fd79137SRobert Mustacchi SECTION_TYPE, flags, 308*7fd79137SRobert Mustacchi SHN_UNDEF, 0, 309*7fd79137SRobert Mustacchi &name_idx, &err); 310*7fd79137SRobert Mustacchi du = name_idx; 311*7fd79137SRobert Mustacchi } 312*7fd79137SRobert Mustacchi if (new_base_elf_sect == -1) { 313*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, 314*7fd79137SRobert Mustacchi DW_DLV_NOCOUNT); 315*7fd79137SRobert Mustacchi } 316*7fd79137SRobert Mustacchi dbg->de_elf_sects[sect] = new_base_elf_sect; 317*7fd79137SRobert Mustacchi 318*7fd79137SRobert Mustacchi dbg->de_sect_name_idx[sect] = du; 319*7fd79137SRobert Mustacchi } 320*7fd79137SRobert Mustacchi } 321*7fd79137SRobert Mustacchi 322*7fd79137SRobert Mustacchi nbufs = 0; 323*7fd79137SRobert Mustacchi 324*7fd79137SRobert Mustacchi /* 325*7fd79137SRobert Mustacchi Changing the order in which the sections are generated may cause 326*7fd79137SRobert Mustacchi problems because of relocations. */ 327*7fd79137SRobert Mustacchi 328*7fd79137SRobert Mustacchi if (dwarf_need_debug_line_section(dbg) == TRUE) { 329*7fd79137SRobert Mustacchi nbufs = _dwarf_pro_generate_debugline(dbg, error); 330*7fd79137SRobert Mustacchi if (nbufs < 0) { 331*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGLINE_ERROR, 332*7fd79137SRobert Mustacchi DW_DLV_NOCOUNT); 333*7fd79137SRobert Mustacchi } 334*7fd79137SRobert Mustacchi } 335*7fd79137SRobert Mustacchi 336*7fd79137SRobert Mustacchi if (dbg->de_frame_cies) { 337*7fd79137SRobert Mustacchi nbufs = _dwarf_pro_generate_debugframe(dbg, error); 338*7fd79137SRobert Mustacchi if (nbufs < 0) { 339*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGFRAME_ERROR, 340*7fd79137SRobert Mustacchi DW_DLV_NOCOUNT); 341*7fd79137SRobert Mustacchi } 342*7fd79137SRobert Mustacchi } 343*7fd79137SRobert Mustacchi if (dbg->de_first_macinfo) { 344*7fd79137SRobert Mustacchi nbufs = _dwarf_pro_transform_macro_info_to_disk(dbg, error); 345*7fd79137SRobert Mustacchi if (nbufs < 0) { 346*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGMACINFO_ERROR, 347*7fd79137SRobert Mustacchi DW_DLV_NOCOUNT); 348*7fd79137SRobert Mustacchi } 349*7fd79137SRobert Mustacchi } 350*7fd79137SRobert Mustacchi 351*7fd79137SRobert Mustacchi if (dbg->de_dies) { 352*7fd79137SRobert Mustacchi nbufs = _dwarf_pro_generate_debuginfo(dbg, error); 353*7fd79137SRobert Mustacchi if (nbufs < 0) { 354*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, 355*7fd79137SRobert Mustacchi DW_DLV_NOCOUNT); 356*7fd79137SRobert Mustacchi } 357*7fd79137SRobert Mustacchi } 358*7fd79137SRobert Mustacchi 359*7fd79137SRobert Mustacchi if (dbg->de_arange) { 360*7fd79137SRobert Mustacchi nbufs = _dwarf_transform_arange_to_disk(dbg, error); 361*7fd79137SRobert Mustacchi if (nbufs < 0) { 362*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, 363*7fd79137SRobert Mustacchi DW_DLV_NOCOUNT); 364*7fd79137SRobert Mustacchi } 365*7fd79137SRobert Mustacchi } 366*7fd79137SRobert Mustacchi 367*7fd79137SRobert Mustacchi if (dbg->de_simple_name_headers[dwarf_snk_pubname].sn_head) { 368*7fd79137SRobert Mustacchi nbufs = _dwarf_transform_simplename_to_disk(dbg, 369*7fd79137SRobert Mustacchi dwarf_snk_pubname, 370*7fd79137SRobert Mustacchi DEBUG_PUBNAMES, 371*7fd79137SRobert Mustacchi error); 372*7fd79137SRobert Mustacchi 373*7fd79137SRobert Mustacchi 374*7fd79137SRobert Mustacchi if (nbufs < 0) { 375*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, 376*7fd79137SRobert Mustacchi DW_DLV_NOCOUNT); 377*7fd79137SRobert Mustacchi } 378*7fd79137SRobert Mustacchi } 379*7fd79137SRobert Mustacchi 380*7fd79137SRobert Mustacchi if (dbg->de_simple_name_headers[dwarf_snk_funcname].sn_head) { 381*7fd79137SRobert Mustacchi nbufs = _dwarf_transform_simplename_to_disk(dbg, 382*7fd79137SRobert Mustacchi dwarf_snk_funcname, 383*7fd79137SRobert Mustacchi DEBUG_FUNCNAMES, 384*7fd79137SRobert Mustacchi error); 385*7fd79137SRobert Mustacchi if (nbufs < 0) { 386*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, 387*7fd79137SRobert Mustacchi DW_DLV_NOCOUNT); 388*7fd79137SRobert Mustacchi } 389*7fd79137SRobert Mustacchi } 390*7fd79137SRobert Mustacchi 391*7fd79137SRobert Mustacchi if (dbg->de_simple_name_headers[dwarf_snk_typename].sn_head) { 392*7fd79137SRobert Mustacchi nbufs = _dwarf_transform_simplename_to_disk(dbg, 393*7fd79137SRobert Mustacchi dwarf_snk_typename, 394*7fd79137SRobert Mustacchi DEBUG_TYPENAMES, 395*7fd79137SRobert Mustacchi error); 396*7fd79137SRobert Mustacchi if (nbufs < 0) { 397*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, 398*7fd79137SRobert Mustacchi DW_DLV_NOCOUNT); 399*7fd79137SRobert Mustacchi } 400*7fd79137SRobert Mustacchi } 401*7fd79137SRobert Mustacchi 402*7fd79137SRobert Mustacchi if (dbg->de_simple_name_headers[dwarf_snk_varname].sn_head) { 403*7fd79137SRobert Mustacchi nbufs = _dwarf_transform_simplename_to_disk(dbg, 404*7fd79137SRobert Mustacchi dwarf_snk_varname, 405*7fd79137SRobert Mustacchi DEBUG_VARNAMES, 406*7fd79137SRobert Mustacchi error); 407*7fd79137SRobert Mustacchi 408*7fd79137SRobert Mustacchi if (nbufs < 0) { 409*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, 410*7fd79137SRobert Mustacchi DW_DLV_NOCOUNT); 411*7fd79137SRobert Mustacchi } 412*7fd79137SRobert Mustacchi } 413*7fd79137SRobert Mustacchi 414*7fd79137SRobert Mustacchi if (dbg->de_simple_name_headers[dwarf_snk_weakname].sn_head) { 415*7fd79137SRobert Mustacchi nbufs = _dwarf_transform_simplename_to_disk(dbg, 416*7fd79137SRobert Mustacchi dwarf_snk_weakname, DEBUG_WEAKNAMES, error); 417*7fd79137SRobert Mustacchi if (nbufs < 0) { 418*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, 419*7fd79137SRobert Mustacchi DW_DLV_NOCOUNT); 420*7fd79137SRobert Mustacchi } 421*7fd79137SRobert Mustacchi } 422*7fd79137SRobert Mustacchi 423*7fd79137SRobert Mustacchi { 424*7fd79137SRobert Mustacchi Dwarf_Signed new_secs = 0; 425*7fd79137SRobert Mustacchi int res = 0; 426*7fd79137SRobert Mustacchi 427*7fd79137SRobert Mustacchi res = dbg->de_transform_relocs_to_disk(dbg, &new_secs); 428*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 429*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR, 430*7fd79137SRobert Mustacchi DW_DLV_NOCOUNT); 431*7fd79137SRobert Mustacchi } 432*7fd79137SRobert Mustacchi nbufs += new_secs; 433*7fd79137SRobert Mustacchi } 434*7fd79137SRobert Mustacchi return nbufs; 435*7fd79137SRobert Mustacchi } 436*7fd79137SRobert Mustacchi 437*7fd79137SRobert Mustacchi 438*7fd79137SRobert Mustacchi /*--------------------------------------------------------------- 439*7fd79137SRobert Mustacchi Generate debug_line section 440*7fd79137SRobert Mustacchi ---------------------------------------------------------------*/ 441*7fd79137SRobert Mustacchi static int 442*7fd79137SRobert Mustacchi _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Error * error) 443*7fd79137SRobert Mustacchi { 444*7fd79137SRobert Mustacchi Dwarf_P_Inc_Dir curdir = 0; 445*7fd79137SRobert Mustacchi Dwarf_P_F_Entry curentry = 0; 446*7fd79137SRobert Mustacchi Dwarf_P_Line curline = 0; 447*7fd79137SRobert Mustacchi Dwarf_P_Line prevline = 0; 448*7fd79137SRobert Mustacchi 449*7fd79137SRobert Mustacchi /* all data named cur* are used to loop thru linked lists */ 450*7fd79137SRobert Mustacchi 451*7fd79137SRobert Mustacchi int sum_bytes = 0; 452*7fd79137SRobert Mustacchi int prolog_size = 0; 453*7fd79137SRobert Mustacchi unsigned char *data = 0; /* holds disk form data */ 454*7fd79137SRobert Mustacchi int elfsectno = 0; 455*7fd79137SRobert Mustacchi unsigned char *start_line_sec = 0; /* pointer to the buffer at 456*7fd79137SRobert Mustacchi section start */ 457*7fd79137SRobert Mustacchi /* temps for memcpy */ 458*7fd79137SRobert Mustacchi Dwarf_Unsigned du = 0; 459*7fd79137SRobert Mustacchi Dwarf_Ubyte db = 0; 460*7fd79137SRobert Mustacchi Dwarf_Half dh = 0; 461*7fd79137SRobert Mustacchi int res = 0; 462*7fd79137SRobert Mustacchi int uwordb_size = dbg->de_offset_size; 463*7fd79137SRobert Mustacchi int extension_size = dbg->de_64bit_extension ? 4 : 0; 464*7fd79137SRobert Mustacchi int upointer_size = dbg->de_pointer_size; 465*7fd79137SRobert Mustacchi char buff1[ENCODE_SPACE_NEEDED]; 466*7fd79137SRobert Mustacchi 467*7fd79137SRobert Mustacchi 468*7fd79137SRobert Mustacchi 469*7fd79137SRobert Mustacchi sum_bytes = 0; 470*7fd79137SRobert Mustacchi 471*7fd79137SRobert Mustacchi elfsectno = dbg->de_elf_sects[DEBUG_LINE]; 472*7fd79137SRobert Mustacchi 473*7fd79137SRobert Mustacchi /* include directories */ 474*7fd79137SRobert Mustacchi curdir = dbg->de_inc_dirs; 475*7fd79137SRobert Mustacchi while (curdir) { 476*7fd79137SRobert Mustacchi prolog_size += strlen(curdir->did_name) + 1; 477*7fd79137SRobert Mustacchi curdir = curdir->did_next; 478*7fd79137SRobert Mustacchi } 479*7fd79137SRobert Mustacchi prolog_size++; /* last null following last directory 480*7fd79137SRobert Mustacchi entry. */ 481*7fd79137SRobert Mustacchi 482*7fd79137SRobert Mustacchi /* file entries */ 483*7fd79137SRobert Mustacchi curentry = dbg->de_file_entries; 484*7fd79137SRobert Mustacchi while (curentry) { 485*7fd79137SRobert Mustacchi prolog_size += 486*7fd79137SRobert Mustacchi strlen(curentry->dfe_name) + 1 + curentry->dfe_nbytes; 487*7fd79137SRobert Mustacchi curentry = curentry->dfe_next; 488*7fd79137SRobert Mustacchi } 489*7fd79137SRobert Mustacchi prolog_size++; /* last null byte */ 490*7fd79137SRobert Mustacchi 491*7fd79137SRobert Mustacchi 492*7fd79137SRobert Mustacchi prolog_size += BEGIN_LEN_SIZE + sizeof_uhalf(dbg) + /* version # */ 493*7fd79137SRobert Mustacchi uwordb_size + /* header length */ 494*7fd79137SRobert Mustacchi sizeof_ubyte(dbg) + /* min_instr length */ 495*7fd79137SRobert Mustacchi sizeof_ubyte(dbg) + /* default is_stmt */ 496*7fd79137SRobert Mustacchi sizeof_ubyte(dbg) + /* linebase */ 497*7fd79137SRobert Mustacchi sizeof_ubyte(dbg) + /* linerange */ 498*7fd79137SRobert Mustacchi sizeof_ubyte(dbg); /* opcode base */ 499*7fd79137SRobert Mustacchi 500*7fd79137SRobert Mustacchi /* length of table specifying # of opnds */ 501*7fd79137SRobert Mustacchi prolog_size += sizeof(std_opcode_len); 502*7fd79137SRobert Mustacchi 503*7fd79137SRobert Mustacchi GET_CHUNK(dbg, elfsectno, data, prolog_size, error); 504*7fd79137SRobert Mustacchi start_line_sec = data; 505*7fd79137SRobert Mustacchi 506*7fd79137SRobert Mustacchi /* copy over the data */ 507*7fd79137SRobert Mustacchi /* total_length */ 508*7fd79137SRobert Mustacchi du = 0; 509*7fd79137SRobert Mustacchi if (extension_size) { 510*7fd79137SRobert Mustacchi Dwarf_Word x = DISTINGUISHED_VALUE; 511*7fd79137SRobert Mustacchi 512*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &x, 513*7fd79137SRobert Mustacchi sizeof(x), extension_size); 514*7fd79137SRobert Mustacchi data += extension_size; 515*7fd79137SRobert Mustacchi } 516*7fd79137SRobert Mustacchi 517*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, 518*7fd79137SRobert Mustacchi sizeof(du), uwordb_size); 519*7fd79137SRobert Mustacchi data += uwordb_size; 520*7fd79137SRobert Mustacchi 521*7fd79137SRobert Mustacchi dh = VERSION; 522*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dh, 523*7fd79137SRobert Mustacchi sizeof(dh), sizeof(Dwarf_Half)); 524*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Half); 525*7fd79137SRobert Mustacchi 526*7fd79137SRobert Mustacchi /* header length */ 527*7fd79137SRobert Mustacchi du = prolog_size - (BEGIN_LEN_SIZE + sizeof(Dwarf_Half) + 528*7fd79137SRobert Mustacchi uwordb_size); 529*7fd79137SRobert Mustacchi { 530*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, 531*7fd79137SRobert Mustacchi sizeof(du), uwordb_size); 532*7fd79137SRobert Mustacchi data += uwordb_size; 533*7fd79137SRobert Mustacchi } 534*7fd79137SRobert Mustacchi db = MIN_INST_LENGTH; 535*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 536*7fd79137SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte)); 537*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Ubyte); 538*7fd79137SRobert Mustacchi db = DEFAULT_IS_STMT; 539*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 540*7fd79137SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte)); 541*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Ubyte); 542*7fd79137SRobert Mustacchi db = (Dwarf_Ubyte) LINE_BASE; 543*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 544*7fd79137SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte)); 545*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Ubyte); 546*7fd79137SRobert Mustacchi db = LINE_RANGE; 547*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 548*7fd79137SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte)); 549*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Ubyte); 550*7fd79137SRobert Mustacchi db = OPCODE_BASE; 551*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 552*7fd79137SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte)); 553*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Ubyte); 554*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) std_opcode_len, 555*7fd79137SRobert Mustacchi sizeof(std_opcode_len), sizeof(std_opcode_len)); 556*7fd79137SRobert Mustacchi data += sizeof(std_opcode_len); 557*7fd79137SRobert Mustacchi 558*7fd79137SRobert Mustacchi /* copy over include directories */ 559*7fd79137SRobert Mustacchi curdir = dbg->de_inc_dirs; 560*7fd79137SRobert Mustacchi while (curdir) { 561*7fd79137SRobert Mustacchi strcpy((char *) data, curdir->did_name); 562*7fd79137SRobert Mustacchi data += strlen(curdir->did_name) + 1; 563*7fd79137SRobert Mustacchi curdir = curdir->did_next; 564*7fd79137SRobert Mustacchi } 565*7fd79137SRobert Mustacchi *data = '\0'; /* last null */ 566*7fd79137SRobert Mustacchi data++; 567*7fd79137SRobert Mustacchi 568*7fd79137SRobert Mustacchi /* copy file entries */ 569*7fd79137SRobert Mustacchi curentry = dbg->de_file_entries; 570*7fd79137SRobert Mustacchi while (curentry) { 571*7fd79137SRobert Mustacchi strcpy((char *) data, curentry->dfe_name); 572*7fd79137SRobert Mustacchi data += strlen(curentry->dfe_name) + 1; 573*7fd79137SRobert Mustacchi /* copies of leb numbers, no endian issues */ 574*7fd79137SRobert Mustacchi memcpy((void *) data, 575*7fd79137SRobert Mustacchi (const void *) curentry->dfe_args, curentry->dfe_nbytes); 576*7fd79137SRobert Mustacchi data += curentry->dfe_nbytes; 577*7fd79137SRobert Mustacchi curentry = curentry->dfe_next; 578*7fd79137SRobert Mustacchi } 579*7fd79137SRobert Mustacchi *data = '\0'; 580*7fd79137SRobert Mustacchi data++; 581*7fd79137SRobert Mustacchi 582*7fd79137SRobert Mustacchi sum_bytes += prolog_size; 583*7fd79137SRobert Mustacchi 584*7fd79137SRobert Mustacchi curline = dbg->de_lines; 585*7fd79137SRobert Mustacchi prevline = (Dwarf_P_Line) 586*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s)); 587*7fd79137SRobert Mustacchi if (prevline == NULL) { 588*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, -1); 589*7fd79137SRobert Mustacchi } 590*7fd79137SRobert Mustacchi _dwarf_pro_reg_init(prevline); 591*7fd79137SRobert Mustacchi /* generate opcodes for line numbers */ 592*7fd79137SRobert Mustacchi while (curline) { 593*7fd79137SRobert Mustacchi int nbytes; 594*7fd79137SRobert Mustacchi char *arg; 595*7fd79137SRobert Mustacchi int opc; 596*7fd79137SRobert Mustacchi int no_lns_copy; /* if lns copy opcode doesnt need to be 597*7fd79137SRobert Mustacchi generated, if special opcode or end 598*7fd79137SRobert Mustacchi sequence */ 599*7fd79137SRobert Mustacchi Dwarf_Unsigned addr_adv; 600*7fd79137SRobert Mustacchi int line_adv; /* supposed to be a reasonably small 601*7fd79137SRobert Mustacchi number, so the size should not be a 602*7fd79137SRobert Mustacchi problem. ? */ 603*7fd79137SRobert Mustacchi 604*7fd79137SRobert Mustacchi no_lns_copy = 0; 605*7fd79137SRobert Mustacchi if (curline->dpl_opc != 0) { 606*7fd79137SRobert Mustacchi int inst_bytes; /* no of bytes in extended opcode */ 607*7fd79137SRobert Mustacchi char *str; /* hold leb encoded inst_bytes */ 608*7fd79137SRobert Mustacchi int str_nbytes; /* no of bytes in str */ 609*7fd79137SRobert Mustacchi 610*7fd79137SRobert Mustacchi switch (curline->dpl_opc) { 611*7fd79137SRobert Mustacchi case DW_LNE_end_sequence: 612*7fd79137SRobert Mustacchi 613*7fd79137SRobert Mustacchi /* Advance pc to end of text section. */ 614*7fd79137SRobert Mustacchi addr_adv = curline->dpl_address - prevline->dpl_address; 615*7fd79137SRobert Mustacchi if (addr_adv > 0) { 616*7fd79137SRobert Mustacchi db = DW_LNS_advance_pc; 617*7fd79137SRobert Mustacchi res = 618*7fd79137SRobert Mustacchi _dwarf_pro_encode_leb128_nm(addr_adv / 619*7fd79137SRobert Mustacchi MIN_INST_LENGTH, 620*7fd79137SRobert Mustacchi &nbytes, buff1, 621*7fd79137SRobert Mustacchi sizeof(buff1)); 622*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 623*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); 624*7fd79137SRobert Mustacchi } 625*7fd79137SRobert Mustacchi GET_CHUNK(dbg, elfsectno, data, 626*7fd79137SRobert Mustacchi nbytes + sizeof(Dwarf_Ubyte), error); 627*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, 628*7fd79137SRobert Mustacchi (const void *) &db, sizeof(db), 629*7fd79137SRobert Mustacchi sizeof(Dwarf_Ubyte)); 630*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Ubyte); 631*7fd79137SRobert Mustacchi /* leb, no endianness issue */ 632*7fd79137SRobert Mustacchi memcpy((void *) data, (const void *) buff1, nbytes); 633*7fd79137SRobert Mustacchi data += nbytes + sizeof(Dwarf_Ubyte); 634*7fd79137SRobert Mustacchi sum_bytes += nbytes + sizeof(Dwarf_Ubyte); 635*7fd79137SRobert Mustacchi prevline->dpl_address = curline->dpl_address; 636*7fd79137SRobert Mustacchi } 637*7fd79137SRobert Mustacchi 638*7fd79137SRobert Mustacchi /* first null byte */ 639*7fd79137SRobert Mustacchi db = 0; 640*7fd79137SRobert Mustacchi GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), 641*7fd79137SRobert Mustacchi error); 642*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 643*7fd79137SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte)); 644*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Ubyte); 645*7fd79137SRobert Mustacchi sum_bytes += sizeof(Dwarf_Ubyte); 646*7fd79137SRobert Mustacchi 647*7fd79137SRobert Mustacchi /* write length of extended opcode */ 648*7fd79137SRobert Mustacchi inst_bytes = sizeof(Dwarf_Ubyte); 649*7fd79137SRobert Mustacchi res = 650*7fd79137SRobert Mustacchi _dwarf_pro_encode_leb128_nm(inst_bytes, &str_nbytes, 651*7fd79137SRobert Mustacchi buff1, sizeof(buff1)); 652*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 653*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); 654*7fd79137SRobert Mustacchi } 655*7fd79137SRobert Mustacchi GET_CHUNK(dbg, elfsectno, data, str_nbytes, error); 656*7fd79137SRobert Mustacchi memcpy((void *) data, (const void *) buff1, str_nbytes); 657*7fd79137SRobert Mustacchi data += str_nbytes; 658*7fd79137SRobert Mustacchi sum_bytes += str_nbytes; 659*7fd79137SRobert Mustacchi 660*7fd79137SRobert Mustacchi /* write extended opcode */ 661*7fd79137SRobert Mustacchi db = DW_LNE_end_sequence; 662*7fd79137SRobert Mustacchi GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), 663*7fd79137SRobert Mustacchi error); 664*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 665*7fd79137SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte)); 666*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Ubyte); 667*7fd79137SRobert Mustacchi sum_bytes += sizeof(Dwarf_Ubyte); 668*7fd79137SRobert Mustacchi /* reset value to original values */ 669*7fd79137SRobert Mustacchi _dwarf_pro_reg_init(prevline); 670*7fd79137SRobert Mustacchi no_lns_copy = 1; 671*7fd79137SRobert Mustacchi /* this is set only for end_sequence, so that a 672*7fd79137SRobert Mustacchi dw_lns_copy is not generated */ 673*7fd79137SRobert Mustacchi break; 674*7fd79137SRobert Mustacchi 675*7fd79137SRobert Mustacchi case DW_LNE_set_address: 676*7fd79137SRobert Mustacchi 677*7fd79137SRobert Mustacchi /* first null byte */ 678*7fd79137SRobert Mustacchi db = 0; 679*7fd79137SRobert Mustacchi GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), 680*7fd79137SRobert Mustacchi error); 681*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 682*7fd79137SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte)); 683*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Ubyte); 684*7fd79137SRobert Mustacchi sum_bytes += sizeof(Dwarf_Ubyte); 685*7fd79137SRobert Mustacchi 686*7fd79137SRobert Mustacchi /* write length of extended opcode */ 687*7fd79137SRobert Mustacchi inst_bytes = sizeof(Dwarf_Ubyte) + upointer_size; 688*7fd79137SRobert Mustacchi res = 689*7fd79137SRobert Mustacchi _dwarf_pro_encode_leb128_nm(inst_bytes, &str_nbytes, 690*7fd79137SRobert Mustacchi buff1, sizeof(buff1)); 691*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 692*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); 693*7fd79137SRobert Mustacchi } 694*7fd79137SRobert Mustacchi GET_CHUNK(dbg, elfsectno, data, str_nbytes, error); 695*7fd79137SRobert Mustacchi str = buff1; 696*7fd79137SRobert Mustacchi /* leb number, no endian issue */ 697*7fd79137SRobert Mustacchi memcpy((void *) data, (const void *) str, str_nbytes); 698*7fd79137SRobert Mustacchi data += str_nbytes; 699*7fd79137SRobert Mustacchi sum_bytes += str_nbytes; 700*7fd79137SRobert Mustacchi 701*7fd79137SRobert Mustacchi /* write extended opcode */ 702*7fd79137SRobert Mustacchi db = DW_LNE_set_address; 703*7fd79137SRobert Mustacchi GET_CHUNK(dbg, elfsectno, data, upointer_size + 704*7fd79137SRobert Mustacchi sizeof(Dwarf_Ubyte), error); 705*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 706*7fd79137SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte)); 707*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Ubyte); 708*7fd79137SRobert Mustacchi sum_bytes += sizeof(Dwarf_Ubyte); 709*7fd79137SRobert Mustacchi 710*7fd79137SRobert Mustacchi /* reloc for address */ 711*7fd79137SRobert Mustacchi res = dbg->de_reloc_name(dbg, DEBUG_LINE, 712*7fd79137SRobert Mustacchi sum_bytes, /* r_offset */ 713*7fd79137SRobert Mustacchi curline->dpl_r_symidx, 714*7fd79137SRobert Mustacchi dwarf_drt_data_reloc, 715*7fd79137SRobert Mustacchi uwordb_size); 716*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 717*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); 718*7fd79137SRobert Mustacchi } 719*7fd79137SRobert Mustacchi 720*7fd79137SRobert Mustacchi /* write offset (address) */ 721*7fd79137SRobert Mustacchi du = curline->dpl_address; 722*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, 723*7fd79137SRobert Mustacchi sizeof(du), upointer_size); 724*7fd79137SRobert Mustacchi data += upointer_size; 725*7fd79137SRobert Mustacchi sum_bytes += upointer_size; 726*7fd79137SRobert Mustacchi prevline->dpl_address = curline->dpl_address; 727*7fd79137SRobert Mustacchi no_lns_copy = 1; 728*7fd79137SRobert Mustacchi break; 729*7fd79137SRobert Mustacchi } 730*7fd79137SRobert Mustacchi } else { 731*7fd79137SRobert Mustacchi if (curline->dpl_file != prevline->dpl_file) { 732*7fd79137SRobert Mustacchi db = DW_LNS_set_file; 733*7fd79137SRobert Mustacchi res = 734*7fd79137SRobert Mustacchi _dwarf_pro_encode_leb128_nm(curline->dpl_file, 735*7fd79137SRobert Mustacchi &nbytes, buff1, 736*7fd79137SRobert Mustacchi sizeof(buff1)); 737*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 738*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); 739*7fd79137SRobert Mustacchi } 740*7fd79137SRobert Mustacchi arg = buff1; 741*7fd79137SRobert Mustacchi GET_CHUNK(dbg, elfsectno, data, 742*7fd79137SRobert Mustacchi nbytes + sizeof(Dwarf_Ubyte), error); 743*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 744*7fd79137SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte)); 745*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Ubyte); 746*7fd79137SRobert Mustacchi memcpy((void *) data, (const void *) arg, nbytes); 747*7fd79137SRobert Mustacchi data += nbytes; 748*7fd79137SRobert Mustacchi sum_bytes += nbytes + sizeof(Dwarf_Ubyte); 749*7fd79137SRobert Mustacchi prevline->dpl_file = curline->dpl_file; 750*7fd79137SRobert Mustacchi } 751*7fd79137SRobert Mustacchi if (curline->dpl_column != prevline->dpl_column) { 752*7fd79137SRobert Mustacchi db = DW_LNS_set_column; 753*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(curline->dpl_column, 754*7fd79137SRobert Mustacchi &nbytes, 755*7fd79137SRobert Mustacchi buff1, sizeof(buff1)); 756*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 757*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); 758*7fd79137SRobert Mustacchi } 759*7fd79137SRobert Mustacchi 760*7fd79137SRobert Mustacchi arg = buff1; 761*7fd79137SRobert Mustacchi GET_CHUNK(dbg, elfsectno, data, 762*7fd79137SRobert Mustacchi nbytes + sizeof(Dwarf_Ubyte), error); 763*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 764*7fd79137SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte)); 765*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Ubyte); 766*7fd79137SRobert Mustacchi memcpy((void *) data, (const void *) arg, nbytes); 767*7fd79137SRobert Mustacchi data += nbytes; 768*7fd79137SRobert Mustacchi sum_bytes += nbytes + sizeof(Dwarf_Ubyte); 769*7fd79137SRobert Mustacchi prevline->dpl_column = curline->dpl_column; 770*7fd79137SRobert Mustacchi } 771*7fd79137SRobert Mustacchi if (curline->dpl_is_stmt != prevline->dpl_is_stmt) { 772*7fd79137SRobert Mustacchi db = DW_LNS_negate_stmt; 773*7fd79137SRobert Mustacchi GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), 774*7fd79137SRobert Mustacchi error); 775*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 776*7fd79137SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte)); 777*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Ubyte); 778*7fd79137SRobert Mustacchi sum_bytes += sizeof(Dwarf_Ubyte); 779*7fd79137SRobert Mustacchi prevline->dpl_is_stmt = curline->dpl_is_stmt; 780*7fd79137SRobert Mustacchi } 781*7fd79137SRobert Mustacchi if (curline->dpl_basic_block == true && 782*7fd79137SRobert Mustacchi prevline->dpl_basic_block == false) { 783*7fd79137SRobert Mustacchi db = DW_LNS_set_basic_block; 784*7fd79137SRobert Mustacchi GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), 785*7fd79137SRobert Mustacchi error); 786*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 787*7fd79137SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte)); 788*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Ubyte); 789*7fd79137SRobert Mustacchi sum_bytes += sizeof(Dwarf_Ubyte); 790*7fd79137SRobert Mustacchi prevline->dpl_basic_block = curline->dpl_basic_block; 791*7fd79137SRobert Mustacchi } 792*7fd79137SRobert Mustacchi addr_adv = curline->dpl_address - prevline->dpl_address; 793*7fd79137SRobert Mustacchi 794*7fd79137SRobert Mustacchi line_adv = (int) (curline->dpl_line - prevline->dpl_line); 795*7fd79137SRobert Mustacchi if ((addr_adv % MIN_INST_LENGTH) != 0) { 796*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_ADDRESS, -1); 797*7fd79137SRobert Mustacchi } 798*7fd79137SRobert Mustacchi if ((opc = _dwarf_pro_get_opc(addr_adv, line_adv)) > 0) { 799*7fd79137SRobert Mustacchi no_lns_copy = 1; 800*7fd79137SRobert Mustacchi db = opc; 801*7fd79137SRobert Mustacchi GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), 802*7fd79137SRobert Mustacchi error); 803*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 804*7fd79137SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte)); 805*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Ubyte); 806*7fd79137SRobert Mustacchi sum_bytes += sizeof(Dwarf_Ubyte); 807*7fd79137SRobert Mustacchi prevline->dpl_basic_block = false; 808*7fd79137SRobert Mustacchi prevline->dpl_address = curline->dpl_address; 809*7fd79137SRobert Mustacchi prevline->dpl_line = curline->dpl_line; 810*7fd79137SRobert Mustacchi } else { 811*7fd79137SRobert Mustacchi if (addr_adv > 0) { 812*7fd79137SRobert Mustacchi db = DW_LNS_advance_pc; 813*7fd79137SRobert Mustacchi res = 814*7fd79137SRobert Mustacchi _dwarf_pro_encode_leb128_nm(addr_adv / 815*7fd79137SRobert Mustacchi MIN_INST_LENGTH, 816*7fd79137SRobert Mustacchi &nbytes, buff1, 817*7fd79137SRobert Mustacchi sizeof(buff1)); 818*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 819*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); 820*7fd79137SRobert Mustacchi } 821*7fd79137SRobert Mustacchi 822*7fd79137SRobert Mustacchi arg = buff1; 823*7fd79137SRobert Mustacchi GET_CHUNK(dbg, elfsectno, data, 824*7fd79137SRobert Mustacchi nbytes + sizeof(Dwarf_Ubyte), error); 825*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, 826*7fd79137SRobert Mustacchi (const void *) &db, 827*7fd79137SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte)); 828*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Ubyte); 829*7fd79137SRobert Mustacchi memcpy((void *) data, (const void *) arg, nbytes); 830*7fd79137SRobert Mustacchi data += nbytes + sizeof(Dwarf_Ubyte); 831*7fd79137SRobert Mustacchi sum_bytes += nbytes + sizeof(Dwarf_Ubyte); 832*7fd79137SRobert Mustacchi prevline->dpl_basic_block = false; 833*7fd79137SRobert Mustacchi prevline->dpl_address = curline->dpl_address; 834*7fd79137SRobert Mustacchi } 835*7fd79137SRobert Mustacchi if (line_adv != 0) { 836*7fd79137SRobert Mustacchi db = DW_LNS_advance_line; 837*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_signed_leb128_nm(line_adv, 838*7fd79137SRobert Mustacchi &nbytes, 839*7fd79137SRobert Mustacchi buff1, 840*7fd79137SRobert Mustacchi sizeof 841*7fd79137SRobert Mustacchi (buff1)); 842*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 843*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); 844*7fd79137SRobert Mustacchi } 845*7fd79137SRobert Mustacchi 846*7fd79137SRobert Mustacchi arg = buff1; 847*7fd79137SRobert Mustacchi GET_CHUNK(dbg, elfsectno, data, 848*7fd79137SRobert Mustacchi nbytes + sizeof(Dwarf_Ubyte), error); 849*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, 850*7fd79137SRobert Mustacchi (const void *) &db, sizeof(db), 851*7fd79137SRobert Mustacchi sizeof(Dwarf_Ubyte)); 852*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Ubyte); 853*7fd79137SRobert Mustacchi memcpy((void *) data, (const void *) arg, nbytes); 854*7fd79137SRobert Mustacchi data += nbytes + sizeof(Dwarf_Ubyte); 855*7fd79137SRobert Mustacchi sum_bytes += nbytes + sizeof(Dwarf_Ubyte); 856*7fd79137SRobert Mustacchi prevline->dpl_basic_block = false; 857*7fd79137SRobert Mustacchi prevline->dpl_line = curline->dpl_line; 858*7fd79137SRobert Mustacchi } 859*7fd79137SRobert Mustacchi } 860*7fd79137SRobert Mustacchi } /* ends else for opc != 0 */ 861*7fd79137SRobert Mustacchi if (no_lns_copy == 0) { /* if not a special or dw_lne_end_seq 862*7fd79137SRobert Mustacchi generate a matrix line */ 863*7fd79137SRobert Mustacchi db = DW_LNS_copy; 864*7fd79137SRobert Mustacchi GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), error); 865*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, 866*7fd79137SRobert Mustacchi (const void *) &db, 867*7fd79137SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte)); 868*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Ubyte); 869*7fd79137SRobert Mustacchi sum_bytes += sizeof(Dwarf_Ubyte); 870*7fd79137SRobert Mustacchi prevline->dpl_basic_block = false; 871*7fd79137SRobert Mustacchi } 872*7fd79137SRobert Mustacchi curline = curline->dpl_next; 873*7fd79137SRobert Mustacchi } 874*7fd79137SRobert Mustacchi 875*7fd79137SRobert Mustacchi /* write total length field */ 876*7fd79137SRobert Mustacchi du = sum_bytes - BEGIN_LEN_SIZE; 877*7fd79137SRobert Mustacchi { 878*7fd79137SRobert Mustacchi start_line_sec += extension_size; 879*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) start_line_sec, 880*7fd79137SRobert Mustacchi (const void *) &du, sizeof(du), uwordb_size); 881*7fd79137SRobert Mustacchi } 882*7fd79137SRobert Mustacchi 883*7fd79137SRobert Mustacchi return (int) dbg->de_n_debug_sect; 884*7fd79137SRobert Mustacchi } 885*7fd79137SRobert Mustacchi 886*7fd79137SRobert Mustacchi /*--------------------------------------------------------------- 887*7fd79137SRobert Mustacchi Generate debug_frame section 888*7fd79137SRobert Mustacchi ---------------------------------------------------------------*/ 889*7fd79137SRobert Mustacchi static int 890*7fd79137SRobert Mustacchi _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error) 891*7fd79137SRobert Mustacchi { 892*7fd79137SRobert Mustacchi int elfsectno = 0; 893*7fd79137SRobert Mustacchi int i = 0; 894*7fd79137SRobert Mustacchi int firsttime = 1; 895*7fd79137SRobert Mustacchi int pad = 0; /* Pad for padding to align cies and fdes */ 896*7fd79137SRobert Mustacchi Dwarf_P_Cie curcie = 0; 897*7fd79137SRobert Mustacchi Dwarf_P_Fde curfde = 0; 898*7fd79137SRobert Mustacchi unsigned char *data = 0; 899*7fd79137SRobert Mustacchi Dwarf_sfixed dsw = 0; 900*7fd79137SRobert Mustacchi Dwarf_Unsigned du = 0; 901*7fd79137SRobert Mustacchi Dwarf_Ubyte db = 0; 902*7fd79137SRobert Mustacchi long *cie_offs = 0; /* Holds byte offsets for links to fde's */ 903*7fd79137SRobert Mustacchi unsigned long cie_length = 0; 904*7fd79137SRobert Mustacchi int cie_no = 0; 905*7fd79137SRobert Mustacchi int uwordb_size = dbg->de_offset_size; 906*7fd79137SRobert Mustacchi int extension_size = dbg->de_64bit_extension ? 4 : 0; 907*7fd79137SRobert Mustacchi int upointer_size = dbg->de_pointer_size; 908*7fd79137SRobert Mustacchi Dwarf_Unsigned cur_off = 0; /* current offset of written data, held 909*7fd79137SRobert Mustacchi for relocation info */ 910*7fd79137SRobert Mustacchi 911*7fd79137SRobert Mustacchi elfsectno = dbg->de_elf_sects[DEBUG_FRAME]; 912*7fd79137SRobert Mustacchi 913*7fd79137SRobert Mustacchi curcie = dbg->de_frame_cies; 914*7fd79137SRobert Mustacchi cie_length = 0; 915*7fd79137SRobert Mustacchi cur_off = 0; 916*7fd79137SRobert Mustacchi cie_offs = (long *) 917*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(long) * dbg->de_n_cie); 918*7fd79137SRobert Mustacchi if (cie_offs == NULL) { 919*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1); 920*7fd79137SRobert Mustacchi } 921*7fd79137SRobert Mustacchi /* Generate cie number as we go along. This writes 922*7fd79137SRobert Mustacchi all CIEs first before any FDEs, which is rather 923*7fd79137SRobert Mustacchi different from the order a compiler might like (which 924*7fd79137SRobert Mustacchi might be each CIE followed by its FDEs then the next CIE, and 925*7fd79137SRobert Mustacchi so on). */ 926*7fd79137SRobert Mustacchi cie_no = 1; 927*7fd79137SRobert Mustacchi while (curcie) { 928*7fd79137SRobert Mustacchi char *code_al = 0; 929*7fd79137SRobert Mustacchi int c_bytes = 0; 930*7fd79137SRobert Mustacchi char *data_al = 0; 931*7fd79137SRobert Mustacchi int d_bytes = 0; 932*7fd79137SRobert Mustacchi int res = 0; 933*7fd79137SRobert Mustacchi char buff1[ENCODE_SPACE_NEEDED]; 934*7fd79137SRobert Mustacchi char buff2[ENCODE_SPACE_NEEDED]; 935*7fd79137SRobert Mustacchi char buff3[ENCODE_SPACE_NEEDED]; 936*7fd79137SRobert Mustacchi char *augmentation = 0; 937*7fd79137SRobert Mustacchi char *augmented_al = 0; 938*7fd79137SRobert Mustacchi long augmented_fields_length = 0; 939*7fd79137SRobert Mustacchi int a_bytes = 0; 940*7fd79137SRobert Mustacchi 941*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(curcie->cie_code_align, 942*7fd79137SRobert Mustacchi &c_bytes, 943*7fd79137SRobert Mustacchi buff1, sizeof(buff1)); 944*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 945*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1); 946*7fd79137SRobert Mustacchi } 947*7fd79137SRobert Mustacchi /* Before April 1999, the following was using an unsigned 948*7fd79137SRobert Mustacchi encode. That worked ok even though the decoder used the 949*7fd79137SRobert Mustacchi correct signed leb read, but doing the encode correctly 950*7fd79137SRobert Mustacchi (according to the dwarf spec) saves space in the output file 951*7fd79137SRobert Mustacchi and is completely compatible. 952*7fd79137SRobert Mustacchi 953*7fd79137SRobert Mustacchi Note the actual stored amount on MIPS was 10 bytes (!) to 954*7fd79137SRobert Mustacchi store the value -4. (hex)fc ffffffff ffffffff 01 The 955*7fd79137SRobert Mustacchi libdwarf consumer consumed all 10 bytes too! 956*7fd79137SRobert Mustacchi 957*7fd79137SRobert Mustacchi old version res = 958*7fd79137SRobert Mustacchi _dwarf_pro_encode_leb128_nm(curcie->cie_data_align, 959*7fd79137SRobert Mustacchi 960*7fd79137SRobert Mustacchi below is corrected signed version. */ 961*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_signed_leb128_nm(curcie->cie_data_align, 962*7fd79137SRobert Mustacchi &d_bytes, 963*7fd79137SRobert Mustacchi buff2, sizeof(buff2)); 964*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 965*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1); 966*7fd79137SRobert Mustacchi } 967*7fd79137SRobert Mustacchi code_al = buff1; 968*7fd79137SRobert Mustacchi data_al = buff2; 969*7fd79137SRobert Mustacchi 970*7fd79137SRobert Mustacchi /* get the correct offset */ 971*7fd79137SRobert Mustacchi if (firsttime) { 972*7fd79137SRobert Mustacchi cie_offs[cie_no - 1] = 0; 973*7fd79137SRobert Mustacchi firsttime = 0; 974*7fd79137SRobert Mustacchi } else { 975*7fd79137SRobert Mustacchi cie_offs[cie_no - 1] = cie_offs[cie_no - 2] + 976*7fd79137SRobert Mustacchi (long) cie_length + BEGIN_LEN_SIZE; 977*7fd79137SRobert Mustacchi } 978*7fd79137SRobert Mustacchi cie_no++; 979*7fd79137SRobert Mustacchi augmentation = curcie->cie_aug; 980*7fd79137SRobert Mustacchi if (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) { 981*7fd79137SRobert Mustacchi augmented_fields_length = 0; 982*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(augmented_fields_length, 983*7fd79137SRobert Mustacchi &a_bytes, buff3, 984*7fd79137SRobert Mustacchi sizeof(buff3)); 985*7fd79137SRobert Mustacchi augmented_al = buff3; 986*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 987*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1); 988*7fd79137SRobert Mustacchi } 989*7fd79137SRobert Mustacchi cie_length = uwordb_size + /* cie_id */ 990*7fd79137SRobert Mustacchi sizeof(Dwarf_Ubyte) + /* cie version */ 991*7fd79137SRobert Mustacchi strlen(curcie->cie_aug) + 1 + /* augmentation */ 992*7fd79137SRobert Mustacchi c_bytes + /* code alignment factor */ 993*7fd79137SRobert Mustacchi d_bytes + /* data alignment factor */ 994*7fd79137SRobert Mustacchi sizeof(Dwarf_Ubyte) + /* return reg address */ 995*7fd79137SRobert Mustacchi a_bytes + /* augmentation length */ 996*7fd79137SRobert Mustacchi curcie->cie_inst_bytes; 997*7fd79137SRobert Mustacchi } else { 998*7fd79137SRobert Mustacchi cie_length = uwordb_size + /* cie_id */ 999*7fd79137SRobert Mustacchi sizeof(Dwarf_Ubyte) + /* cie version */ 1000*7fd79137SRobert Mustacchi strlen(curcie->cie_aug) + 1 + /* augmentation */ 1001*7fd79137SRobert Mustacchi c_bytes + d_bytes + sizeof(Dwarf_Ubyte) + /* return 1002*7fd79137SRobert Mustacchi reg 1003*7fd79137SRobert Mustacchi address 1004*7fd79137SRobert Mustacchi */ 1005*7fd79137SRobert Mustacchi curcie->cie_inst_bytes; 1006*7fd79137SRobert Mustacchi } 1007*7fd79137SRobert Mustacchi pad = (int) PADDING(cie_length, upointer_size); 1008*7fd79137SRobert Mustacchi cie_length += pad; 1009*7fd79137SRobert Mustacchi GET_CHUNK(dbg, elfsectno, data, cie_length + 1010*7fd79137SRobert Mustacchi BEGIN_LEN_SIZE, error); 1011*7fd79137SRobert Mustacchi if (extension_size) { 1012*7fd79137SRobert Mustacchi Dwarf_Unsigned x = DISTINGUISHED_VALUE; 1013*7fd79137SRobert Mustacchi 1014*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, 1015*7fd79137SRobert Mustacchi (const void *) &x, 1016*7fd79137SRobert Mustacchi sizeof(x), extension_size); 1017*7fd79137SRobert Mustacchi data += extension_size; 1018*7fd79137SRobert Mustacchi 1019*7fd79137SRobert Mustacchi } 1020*7fd79137SRobert Mustacchi du = cie_length; 1021*7fd79137SRobert Mustacchi /* total length of cie */ 1022*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, 1023*7fd79137SRobert Mustacchi (const void *) &du, sizeof(du), uwordb_size); 1024*7fd79137SRobert Mustacchi data += uwordb_size; 1025*7fd79137SRobert Mustacchi 1026*7fd79137SRobert Mustacchi /* cie-id is a special value. */ 1027*7fd79137SRobert Mustacchi du = DW_CIE_ID; 1028*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du, 1029*7fd79137SRobert Mustacchi sizeof(du), uwordb_size); 1030*7fd79137SRobert Mustacchi data += uwordb_size; 1031*7fd79137SRobert Mustacchi 1032*7fd79137SRobert Mustacchi db = curcie->cie_version; 1033*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 1034*7fd79137SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte)); 1035*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Ubyte); 1036*7fd79137SRobert Mustacchi strcpy((char *) data, curcie->cie_aug); 1037*7fd79137SRobert Mustacchi data += strlen(curcie->cie_aug) + 1; 1038*7fd79137SRobert Mustacchi memcpy((void *) data, (const void *) code_al, c_bytes); 1039*7fd79137SRobert Mustacchi data += c_bytes; 1040*7fd79137SRobert Mustacchi memcpy((void *) data, (const void *) data_al, d_bytes); 1041*7fd79137SRobert Mustacchi data += d_bytes; 1042*7fd79137SRobert Mustacchi db = curcie->cie_ret_reg; 1043*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 1044*7fd79137SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte)); 1045*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Ubyte); 1046*7fd79137SRobert Mustacchi 1047*7fd79137SRobert Mustacchi if (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) { 1048*7fd79137SRobert Mustacchi memcpy((void *) data, (const void *) augmented_al, a_bytes); 1049*7fd79137SRobert Mustacchi data += a_bytes; 1050*7fd79137SRobert Mustacchi } 1051*7fd79137SRobert Mustacchi memcpy((void *) data, (const void *) curcie->cie_inst, 1052*7fd79137SRobert Mustacchi curcie->cie_inst_bytes); 1053*7fd79137SRobert Mustacchi data += curcie->cie_inst_bytes; 1054*7fd79137SRobert Mustacchi for (i = 0; i < pad; i++) { 1055*7fd79137SRobert Mustacchi *data = DW_CFA_nop; 1056*7fd79137SRobert Mustacchi data++; 1057*7fd79137SRobert Mustacchi } 1058*7fd79137SRobert Mustacchi curcie = curcie->cie_next; 1059*7fd79137SRobert Mustacchi } 1060*7fd79137SRobert Mustacchi /* calculate current offset */ 1061*7fd79137SRobert Mustacchi cur_off = cie_offs[cie_no - 2] + cie_length + BEGIN_LEN_SIZE; 1062*7fd79137SRobert Mustacchi 1063*7fd79137SRobert Mustacchi /* write out fde's */ 1064*7fd79137SRobert Mustacchi curfde = dbg->de_frame_fdes; 1065*7fd79137SRobert Mustacchi while (curfde) { 1066*7fd79137SRobert Mustacchi Dwarf_P_Frame_Pgm curinst = 0; 1067*7fd79137SRobert Mustacchi long fde_length = 0; 1068*7fd79137SRobert Mustacchi int pad = 0; 1069*7fd79137SRobert Mustacchi Dwarf_P_Cie cie_ptr = 0; 1070*7fd79137SRobert Mustacchi Dwarf_Word cie_index = 0; 1071*7fd79137SRobert Mustacchi Dwarf_Word index = 0; 1072*7fd79137SRobert Mustacchi int oet_length = 0; 1073*7fd79137SRobert Mustacchi int afl_length = 0; 1074*7fd79137SRobert Mustacchi int res = 0; 1075*7fd79137SRobert Mustacchi int v0_augmentation = 0; 1076*7fd79137SRobert Mustacchi #if 0 1077*7fd79137SRobert Mustacchi unsigned char *fde_start_point = 0; 1078*7fd79137SRobert Mustacchi #endif 1079*7fd79137SRobert Mustacchi char afl_buff[ENCODE_SPACE_NEEDED]; 1080*7fd79137SRobert Mustacchi 1081*7fd79137SRobert Mustacchi /* Find the CIE associated with this fde. */ 1082*7fd79137SRobert Mustacchi cie_ptr = dbg->de_frame_cies; 1083*7fd79137SRobert Mustacchi cie_index = curfde->fde_cie; 1084*7fd79137SRobert Mustacchi index = 1; /* The cie_index of the first cie is 1, 1085*7fd79137SRobert Mustacchi not 0. */ 1086*7fd79137SRobert Mustacchi while (cie_ptr && index < cie_index) { 1087*7fd79137SRobert Mustacchi cie_ptr = cie_ptr->cie_next; 1088*7fd79137SRobert Mustacchi index++; 1089*7fd79137SRobert Mustacchi } 1090*7fd79137SRobert Mustacchi if (cie_ptr == NULL) { 1091*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_NULL, -1); 1092*7fd79137SRobert Mustacchi } 1093*7fd79137SRobert Mustacchi 1094*7fd79137SRobert Mustacchi if (strcmp(cie_ptr->cie_aug, DW_CIE_AUGMENTER_STRING_V0) == 0) { 1095*7fd79137SRobert Mustacchi v0_augmentation = 1; 1096*7fd79137SRobert Mustacchi oet_length = sizeof(Dwarf_sfixed); 1097*7fd79137SRobert Mustacchi /* encode the length of augmented fields. */ 1098*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(oet_length, 1099*7fd79137SRobert Mustacchi &afl_length, afl_buff, 1100*7fd79137SRobert Mustacchi sizeof(afl_buff)); 1101*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 1102*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1); 1103*7fd79137SRobert Mustacchi } 1104*7fd79137SRobert Mustacchi 1105*7fd79137SRobert Mustacchi fde_length = curfde->fde_n_bytes + BEGIN_LEN_SIZE + /* cie 1106*7fd79137SRobert Mustacchi pointer 1107*7fd79137SRobert Mustacchi */ 1108*7fd79137SRobert Mustacchi upointer_size + /* initial loc */ 1109*7fd79137SRobert Mustacchi upointer_size + /* address range */ 1110*7fd79137SRobert Mustacchi afl_length + /* augmented field length */ 1111*7fd79137SRobert Mustacchi oet_length; /* exception_table offset */ 1112*7fd79137SRobert Mustacchi } else { 1113*7fd79137SRobert Mustacchi fde_length = curfde->fde_n_bytes + BEGIN_LEN_SIZE + /* cie 1114*7fd79137SRobert Mustacchi pointer 1115*7fd79137SRobert Mustacchi */ 1116*7fd79137SRobert Mustacchi upointer_size + /* initial loc */ 1117*7fd79137SRobert Mustacchi upointer_size; /* address range */ 1118*7fd79137SRobert Mustacchi } 1119*7fd79137SRobert Mustacchi 1120*7fd79137SRobert Mustacchi 1121*7fd79137SRobert Mustacchi if (curfde->fde_die) { 1122*7fd79137SRobert Mustacchi /* IRIX/MIPS extension: 1123*7fd79137SRobert Mustacchi Using fde offset, generate DW_AT_MIPS_fde attribute for the 1124*7fd79137SRobert Mustacchi die corresponding to this fde. */ 1125*7fd79137SRobert Mustacchi if(_dwarf_pro_add_AT_fde(dbg, curfde->fde_die, cur_off, 1126*7fd79137SRobert Mustacchi error) < 0) { 1127*7fd79137SRobert Mustacchi return -1; 1128*7fd79137SRobert Mustacchi } 1129*7fd79137SRobert Mustacchi } 1130*7fd79137SRobert Mustacchi 1131*7fd79137SRobert Mustacchi /* store relocation for cie pointer */ 1132*7fd79137SRobert Mustacchi res = dbg->de_reloc_name(dbg, DEBUG_FRAME, cur_off + 1133*7fd79137SRobert Mustacchi BEGIN_LEN_SIZE /* r_offset */, 1134*7fd79137SRobert Mustacchi dbg->de_sect_name_idx[DEBUG_FRAME], 1135*7fd79137SRobert Mustacchi dwarf_drt_data_reloc, uwordb_size); 1136*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 1137*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); 1138*7fd79137SRobert Mustacchi } 1139*7fd79137SRobert Mustacchi 1140*7fd79137SRobert Mustacchi /* store relocation information for initial location */ 1141*7fd79137SRobert Mustacchi res = dbg->de_reloc_name(dbg, DEBUG_FRAME, 1142*7fd79137SRobert Mustacchi cur_off + BEGIN_LEN_SIZE + 1143*7fd79137SRobert Mustacchi upointer_size /* r_offset */, 1144*7fd79137SRobert Mustacchi curfde->fde_r_symidx, 1145*7fd79137SRobert Mustacchi dwarf_drt_data_reloc, upointer_size); 1146*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 1147*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); 1148*7fd79137SRobert Mustacchi } 1149*7fd79137SRobert Mustacchi /* Store the relocation information for the 1150*7fd79137SRobert Mustacchi offset_into_exception_info field, if the offset is valid (0 1151*7fd79137SRobert Mustacchi is a valid offset). */ 1152*7fd79137SRobert Mustacchi if (v0_augmentation && 1153*7fd79137SRobert Mustacchi curfde->fde_offset_into_exception_tables >= 0) { 1154*7fd79137SRobert Mustacchi 1155*7fd79137SRobert Mustacchi res = dbg->de_reloc_name(dbg, DEBUG_FRAME, 1156*7fd79137SRobert Mustacchi /* r_offset, where in cie this 1157*7fd79137SRobert Mustacchi field starts */ 1158*7fd79137SRobert Mustacchi cur_off + BEGIN_LEN_SIZE + 1159*7fd79137SRobert Mustacchi uwordb_size + 2 * upointer_size + 1160*7fd79137SRobert Mustacchi afl_length, 1161*7fd79137SRobert Mustacchi curfde->fde_exception_table_symbol, 1162*7fd79137SRobert Mustacchi dwarf_drt_segment_rel, 1163*7fd79137SRobert Mustacchi sizeof(Dwarf_sfixed)); 1164*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 1165*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1); 1166*7fd79137SRobert Mustacchi } 1167*7fd79137SRobert Mustacchi } 1168*7fd79137SRobert Mustacchi 1169*7fd79137SRobert Mustacchi /* adjust for padding */ 1170*7fd79137SRobert Mustacchi pad = (int) PADDING(fde_length, upointer_size); 1171*7fd79137SRobert Mustacchi fde_length += pad; 1172*7fd79137SRobert Mustacchi 1173*7fd79137SRobert Mustacchi 1174*7fd79137SRobert Mustacchi /* write out fde */ 1175*7fd79137SRobert Mustacchi GET_CHUNK(dbg, elfsectno, data, fde_length + BEGIN_LEN_SIZE, 1176*7fd79137SRobert Mustacchi error); 1177*7fd79137SRobert Mustacchi #if 0 1178*7fd79137SRobert Mustacchi fde_start_point = data; 1179*7fd79137SRobert Mustacchi #endif 1180*7fd79137SRobert Mustacchi du = fde_length; 1181*7fd79137SRobert Mustacchi { 1182*7fd79137SRobert Mustacchi if (extension_size) { 1183*7fd79137SRobert Mustacchi Dwarf_Word x = DISTINGUISHED_VALUE; 1184*7fd79137SRobert Mustacchi 1185*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, 1186*7fd79137SRobert Mustacchi (const void *) &x, 1187*7fd79137SRobert Mustacchi sizeof(x), extension_size); 1188*7fd79137SRobert Mustacchi data += extension_size; 1189*7fd79137SRobert Mustacchi } 1190*7fd79137SRobert Mustacchi /* length */ 1191*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, 1192*7fd79137SRobert Mustacchi (const void *) &du, 1193*7fd79137SRobert Mustacchi sizeof(du), uwordb_size); 1194*7fd79137SRobert Mustacchi data += uwordb_size; 1195*7fd79137SRobert Mustacchi 1196*7fd79137SRobert Mustacchi /* offset to cie */ 1197*7fd79137SRobert Mustacchi du = cie_offs[curfde->fde_cie - 1]; 1198*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, 1199*7fd79137SRobert Mustacchi (const void *) &du, 1200*7fd79137SRobert Mustacchi sizeof(du), uwordb_size); 1201*7fd79137SRobert Mustacchi data += uwordb_size; 1202*7fd79137SRobert Mustacchi 1203*7fd79137SRobert Mustacchi du = curfde->fde_initloc; 1204*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, 1205*7fd79137SRobert Mustacchi (const void *) &du, 1206*7fd79137SRobert Mustacchi sizeof(du), upointer_size); 1207*7fd79137SRobert Mustacchi data += upointer_size; 1208*7fd79137SRobert Mustacchi 1209*7fd79137SRobert Mustacchi if (dbg->de_reloc_pair && 1210*7fd79137SRobert Mustacchi curfde->fde_end_symbol != 0 && 1211*7fd79137SRobert Mustacchi curfde->fde_addr_range == 0) { 1212*7fd79137SRobert Mustacchi /* symbolic reloc, need reloc for length What if we 1213*7fd79137SRobert Mustacchi really know the length? If so, should use the other 1214*7fd79137SRobert Mustacchi part of 'if'. */ 1215*7fd79137SRobert Mustacchi Dwarf_Unsigned val; 1216*7fd79137SRobert Mustacchi 1217*7fd79137SRobert Mustacchi res = dbg->de_reloc_pair(dbg, 1218*7fd79137SRobert Mustacchi /* DEBUG_ARANGES, */ 1219*7fd79137SRobert Mustacchi DEBUG_FRAME, cur_off + 2 * uwordb_size + upointer_size, /* r_offset 1220*7fd79137SRobert Mustacchi */ 1221*7fd79137SRobert Mustacchi curfde->fde_r_symidx, 1222*7fd79137SRobert Mustacchi curfde->fde_end_symbol, 1223*7fd79137SRobert Mustacchi dwarf_drt_first_of_length_pair, 1224*7fd79137SRobert Mustacchi upointer_size); 1225*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 1226*7fd79137SRobert Mustacchi { 1227*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 1228*7fd79137SRobert Mustacchi return (0); 1229*7fd79137SRobert Mustacchi } 1230*7fd79137SRobert Mustacchi } 1231*7fd79137SRobert Mustacchi 1232*7fd79137SRobert Mustacchi /* arrange pre-calc so assem text can do .word end - 1233*7fd79137SRobert Mustacchi begin + val (gets val from stream) */ 1234*7fd79137SRobert Mustacchi val = curfde->fde_end_symbol_offset - 1235*7fd79137SRobert Mustacchi curfde->fde_initloc; 1236*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, data, 1237*7fd79137SRobert Mustacchi (const void *) &val, 1238*7fd79137SRobert Mustacchi sizeof(val), upointer_size); 1239*7fd79137SRobert Mustacchi data += upointer_size; 1240*7fd79137SRobert Mustacchi } else { 1241*7fd79137SRobert Mustacchi 1242*7fd79137SRobert Mustacchi du = curfde->fde_addr_range; 1243*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, 1244*7fd79137SRobert Mustacchi (const void *) &du, 1245*7fd79137SRobert Mustacchi sizeof(du), upointer_size); 1246*7fd79137SRobert Mustacchi data += upointer_size; 1247*7fd79137SRobert Mustacchi } 1248*7fd79137SRobert Mustacchi } 1249*7fd79137SRobert Mustacchi 1250*7fd79137SRobert Mustacchi if (v0_augmentation) { 1251*7fd79137SRobert Mustacchi /* write the encoded augmented field length. */ 1252*7fd79137SRobert Mustacchi memcpy((void *) data, (const void *) afl_buff, afl_length); 1253*7fd79137SRobert Mustacchi data += afl_length; 1254*7fd79137SRobert Mustacchi /* write the offset_into_exception_tables field. */ 1255*7fd79137SRobert Mustacchi dsw = 1256*7fd79137SRobert Mustacchi (Dwarf_sfixed) curfde->fde_offset_into_exception_tables; 1257*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dsw, 1258*7fd79137SRobert Mustacchi sizeof(dsw), sizeof(Dwarf_sfixed)); 1259*7fd79137SRobert Mustacchi data += sizeof(Dwarf_sfixed); 1260*7fd79137SRobert Mustacchi } 1261*7fd79137SRobert Mustacchi 1262*7fd79137SRobert Mustacchi curinst = curfde->fde_inst; 1263*7fd79137SRobert Mustacchi if(curfde->fde_block) { 1264*7fd79137SRobert Mustacchi unsigned long size = curfde->fde_inst_block_size; 1265*7fd79137SRobert Mustacchi memcpy((void *) data, (const void *) curfde->fde_block, size); 1266*7fd79137SRobert Mustacchi data += size; 1267*7fd79137SRobert Mustacchi } else { 1268*7fd79137SRobert Mustacchi while (curinst) { 1269*7fd79137SRobert Mustacchi db = curinst->dfp_opcode; 1270*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 1271*7fd79137SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte)); 1272*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Ubyte); 1273*7fd79137SRobert Mustacchi #if 0 1274*7fd79137SRobert Mustacchi if (curinst->dfp_sym_index) { 1275*7fd79137SRobert Mustacchi int res = dbg->de_reloc_name(dbg, 1276*7fd79137SRobert Mustacchi DEBUG_FRAME, 1277*7fd79137SRobert Mustacchi /* r_offset = */ 1278*7fd79137SRobert Mustacchi (data - fde_start_point) + cur_off + uwordb_size, 1279*7fd79137SRobert Mustacchi curinst->dfp_sym_index, 1280*7fd79137SRobert Mustacchi dwarf_drt_data_reloc, 1281*7fd79137SRobert Mustacchi upointer_size); 1282*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 1283*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 1284*7fd79137SRobert Mustacchi return (0); 1285*7fd79137SRobert Mustacchi } 1286*7fd79137SRobert Mustacchi } 1287*7fd79137SRobert Mustacchi #endif 1288*7fd79137SRobert Mustacchi memcpy((void *) data, 1289*7fd79137SRobert Mustacchi (const void *) curinst->dfp_args, 1290*7fd79137SRobert Mustacchi curinst->dfp_nbytes); 1291*7fd79137SRobert Mustacchi data += curinst->dfp_nbytes; 1292*7fd79137SRobert Mustacchi curinst = curinst->dfp_next; 1293*7fd79137SRobert Mustacchi } 1294*7fd79137SRobert Mustacchi } 1295*7fd79137SRobert Mustacchi /* padding */ 1296*7fd79137SRobert Mustacchi for (i = 0; i < pad; i++) { 1297*7fd79137SRobert Mustacchi *data = DW_CFA_nop; 1298*7fd79137SRobert Mustacchi data++; 1299*7fd79137SRobert Mustacchi } 1300*7fd79137SRobert Mustacchi cur_off += fde_length + uwordb_size; 1301*7fd79137SRobert Mustacchi curfde = curfde->fde_next; 1302*7fd79137SRobert Mustacchi } 1303*7fd79137SRobert Mustacchi 1304*7fd79137SRobert Mustacchi 1305*7fd79137SRobert Mustacchi return (int) dbg->de_n_debug_sect; 1306*7fd79137SRobert Mustacchi } 1307*7fd79137SRobert Mustacchi 1308*7fd79137SRobert Mustacchi /* 1309*7fd79137SRobert Mustacchi These functions remember all the markers we see along 1310*7fd79137SRobert Mustacchi with the right offset in the .debug_info section so that 1311*7fd79137SRobert Mustacchi we can dump them all back to the user with the section info. 1312*7fd79137SRobert Mustacchi */ 1313*7fd79137SRobert Mustacchi 1314*7fd79137SRobert Mustacchi static int 1315*7fd79137SRobert Mustacchi marker_init(Dwarf_P_Debug dbg, 1316*7fd79137SRobert Mustacchi unsigned count) 1317*7fd79137SRobert Mustacchi { 1318*7fd79137SRobert Mustacchi dbg->de_marker_n_alloc = count; 1319*7fd79137SRobert Mustacchi dbg->de_markers = NULL; 1320*7fd79137SRobert Mustacchi if (count > 0) { 1321*7fd79137SRobert Mustacchi dbg->de_markers = _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Marker_s) * 1322*7fd79137SRobert Mustacchi dbg->de_marker_n_alloc); 1323*7fd79137SRobert Mustacchi if (dbg->de_markers == NULL) { 1324*7fd79137SRobert Mustacchi dbg->de_marker_n_alloc = 0; 1325*7fd79137SRobert Mustacchi return -1; 1326*7fd79137SRobert Mustacchi } 1327*7fd79137SRobert Mustacchi } 1328*7fd79137SRobert Mustacchi return 0; 1329*7fd79137SRobert Mustacchi } 1330*7fd79137SRobert Mustacchi 1331*7fd79137SRobert Mustacchi static int 1332*7fd79137SRobert Mustacchi marker_add(Dwarf_P_Debug dbg, 1333*7fd79137SRobert Mustacchi Dwarf_Unsigned offset, 1334*7fd79137SRobert Mustacchi Dwarf_Unsigned marker) 1335*7fd79137SRobert Mustacchi { 1336*7fd79137SRobert Mustacchi if (dbg->de_marker_n_alloc >= (dbg->de_marker_n_used + 1)) { 1337*7fd79137SRobert Mustacchi unsigned n = dbg->de_marker_n_used++; 1338*7fd79137SRobert Mustacchi dbg->de_markers[n].ma_offset = offset; 1339*7fd79137SRobert Mustacchi dbg->de_markers[n].ma_marker = marker; 1340*7fd79137SRobert Mustacchi return 0; 1341*7fd79137SRobert Mustacchi } 1342*7fd79137SRobert Mustacchi 1343*7fd79137SRobert Mustacchi return -1; 1344*7fd79137SRobert Mustacchi } 1345*7fd79137SRobert Mustacchi 1346*7fd79137SRobert Mustacchi Dwarf_Signed 1347*7fd79137SRobert Mustacchi dwarf_get_die_markers(Dwarf_P_Debug dbg, 1348*7fd79137SRobert Mustacchi Dwarf_P_Marker * marker_list, /* pointer to a pointer */ 1349*7fd79137SRobert Mustacchi Dwarf_Unsigned * marker_count, 1350*7fd79137SRobert Mustacchi Dwarf_Error * error) 1351*7fd79137SRobert Mustacchi { 1352*7fd79137SRobert Mustacchi if (marker_list == NULL || marker_count == NULL) { 1353*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_BADADDR); 1354*7fd79137SRobert Mustacchi } 1355*7fd79137SRobert Mustacchi if (dbg->de_marker_n_used != dbg->de_marker_n_alloc) { 1356*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_MAF, DW_DLV_BADADDR); 1357*7fd79137SRobert Mustacchi } 1358*7fd79137SRobert Mustacchi 1359*7fd79137SRobert Mustacchi *marker_list = dbg->de_markers; 1360*7fd79137SRobert Mustacchi *marker_count = dbg->de_marker_n_used; 1361*7fd79137SRobert Mustacchi return DW_DLV_OK; 1362*7fd79137SRobert Mustacchi } 1363*7fd79137SRobert Mustacchi 1364*7fd79137SRobert Mustacchi /* These functions provide the offsets of DW_FORM_string 1365*7fd79137SRobert Mustacchi attributes in the section section_index. These information 1366*7fd79137SRobert Mustacchi will enable a producer app that is generating assembly 1367*7fd79137SRobert Mustacchi text output to easily emit those attributes in ascii form 1368*7fd79137SRobert Mustacchi without having to decode the byte stream. 1369*7fd79137SRobert Mustacchi */ 1370*7fd79137SRobert Mustacchi static int 1371*7fd79137SRobert Mustacchi string_attr_init (Dwarf_P_Debug dbg, 1372*7fd79137SRobert Mustacchi Dwarf_Signed section_index, 1373*7fd79137SRobert Mustacchi unsigned count) 1374*7fd79137SRobert Mustacchi { 1375*7fd79137SRobert Mustacchi Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[section_index]; 1376*7fd79137SRobert Mustacchi 1377*7fd79137SRobert Mustacchi sect_sa->sect_sa_n_alloc = count; 1378*7fd79137SRobert Mustacchi sect_sa->sect_sa_list = NULL; 1379*7fd79137SRobert Mustacchi if (count > 0) { 1380*7fd79137SRobert Mustacchi sect_sa->sect_sa_section_number = section_index; 1381*7fd79137SRobert Mustacchi sect_sa->sect_sa_list = _dwarf_p_get_alloc(dbg, 1382*7fd79137SRobert Mustacchi sizeof(struct Dwarf_P_String_Attr_s) 1383*7fd79137SRobert Mustacchi * sect_sa->sect_sa_n_alloc); 1384*7fd79137SRobert Mustacchi if (sect_sa->sect_sa_list == NULL) { 1385*7fd79137SRobert Mustacchi sect_sa->sect_sa_n_alloc = 0; 1386*7fd79137SRobert Mustacchi return -1; 1387*7fd79137SRobert Mustacchi } 1388*7fd79137SRobert Mustacchi } 1389*7fd79137SRobert Mustacchi return 0; 1390*7fd79137SRobert Mustacchi } 1391*7fd79137SRobert Mustacchi 1392*7fd79137SRobert Mustacchi static int 1393*7fd79137SRobert Mustacchi string_attr_add (Dwarf_P_Debug dbg, 1394*7fd79137SRobert Mustacchi Dwarf_Signed section_index, 1395*7fd79137SRobert Mustacchi Dwarf_Unsigned offset, 1396*7fd79137SRobert Mustacchi Dwarf_P_Attribute attr) 1397*7fd79137SRobert Mustacchi { 1398*7fd79137SRobert Mustacchi Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[section_index]; 1399*7fd79137SRobert Mustacchi if (sect_sa->sect_sa_n_alloc >= (sect_sa->sect_sa_n_used + 1)) { 1400*7fd79137SRobert Mustacchi unsigned n = sect_sa->sect_sa_n_used++; 1401*7fd79137SRobert Mustacchi sect_sa->sect_sa_list[n].sa_offset = offset; 1402*7fd79137SRobert Mustacchi sect_sa->sect_sa_list[n].sa_nbytes = attr->ar_nbytes; 1403*7fd79137SRobert Mustacchi return 0; 1404*7fd79137SRobert Mustacchi } 1405*7fd79137SRobert Mustacchi 1406*7fd79137SRobert Mustacchi return -1; 1407*7fd79137SRobert Mustacchi } 1408*7fd79137SRobert Mustacchi 1409*7fd79137SRobert Mustacchi int 1410*7fd79137SRobert Mustacchi dwarf_get_string_attributes_count(Dwarf_P_Debug dbg, 1411*7fd79137SRobert Mustacchi Dwarf_Unsigned * 1412*7fd79137SRobert Mustacchi count_of_sa_sections, 1413*7fd79137SRobert Mustacchi int *drd_buffer_version, 1414*7fd79137SRobert Mustacchi Dwarf_Error *error) 1415*7fd79137SRobert Mustacchi { 1416*7fd79137SRobert Mustacchi int i; 1417*7fd79137SRobert Mustacchi unsigned int count = 0; 1418*7fd79137SRobert Mustacchi 1419*7fd79137SRobert Mustacchi for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) { 1420*7fd79137SRobert Mustacchi if (dbg->de_sect_string_attr[i].sect_sa_n_used > 0) { 1421*7fd79137SRobert Mustacchi ++count; 1422*7fd79137SRobert Mustacchi } 1423*7fd79137SRobert Mustacchi } 1424*7fd79137SRobert Mustacchi *count_of_sa_sections = (Dwarf_Unsigned) count; 1425*7fd79137SRobert Mustacchi *drd_buffer_version = DWARF_DRD_BUFFER_VERSION; 1426*7fd79137SRobert Mustacchi 1427*7fd79137SRobert Mustacchi return DW_DLV_OK; 1428*7fd79137SRobert Mustacchi } 1429*7fd79137SRobert Mustacchi 1430*7fd79137SRobert Mustacchi int 1431*7fd79137SRobert Mustacchi dwarf_get_string_attributes_info(Dwarf_P_Debug dbg, 1432*7fd79137SRobert Mustacchi Dwarf_Signed *elf_section_index, 1433*7fd79137SRobert Mustacchi Dwarf_Unsigned *sect_sa_buffer_count, 1434*7fd79137SRobert Mustacchi Dwarf_P_String_Attr *sect_sa_buffer, 1435*7fd79137SRobert Mustacchi Dwarf_Error *error) 1436*7fd79137SRobert Mustacchi { 1437*7fd79137SRobert Mustacchi int i; 1438*7fd79137SRobert Mustacchi int next = dbg->de_sect_sa_next_to_return; 1439*7fd79137SRobert Mustacchi 1440*7fd79137SRobert Mustacchi for (i = next; i < NUM_DEBUG_SECTIONS; ++i) { 1441*7fd79137SRobert Mustacchi Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[i]; 1442*7fd79137SRobert Mustacchi if (sect_sa->sect_sa_n_used > 0) { 1443*7fd79137SRobert Mustacchi dbg->de_sect_sa_next_to_return = i + 1; 1444*7fd79137SRobert Mustacchi *elf_section_index = sect_sa->sect_sa_section_number; 1445*7fd79137SRobert Mustacchi *sect_sa_buffer_count = sect_sa->sect_sa_n_used; 1446*7fd79137SRobert Mustacchi *sect_sa_buffer = sect_sa->sect_sa_list; 1447*7fd79137SRobert Mustacchi return DW_DLV_OK; 1448*7fd79137SRobert Mustacchi } 1449*7fd79137SRobert Mustacchi } 1450*7fd79137SRobert Mustacchi return DW_DLV_NO_ENTRY; 1451*7fd79137SRobert Mustacchi } 1452*7fd79137SRobert Mustacchi 1453*7fd79137SRobert Mustacchi 1454*7fd79137SRobert Mustacchi 1455*7fd79137SRobert Mustacchi /*--------------------------------------------------------------- 1456*7fd79137SRobert Mustacchi Generate debug_info and debug_abbrev sections 1457*7fd79137SRobert Mustacchi ---------------------------------------------------------------*/ 1458*7fd79137SRobert Mustacchi static int 1459*7fd79137SRobert Mustacchi _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, Dwarf_Error * error) 1460*7fd79137SRobert Mustacchi { 1461*7fd79137SRobert Mustacchi int elfsectno_of_debug_info = 0; 1462*7fd79137SRobert Mustacchi int abbrevsectno = 0; 1463*7fd79137SRobert Mustacchi unsigned char *data = 0; 1464*7fd79137SRobert Mustacchi int cu_header_size = 0; 1465*7fd79137SRobert Mustacchi Dwarf_P_Abbrev curabbrev = 0; 1466*7fd79137SRobert Mustacchi Dwarf_P_Abbrev abbrev_head = 0; 1467*7fd79137SRobert Mustacchi Dwarf_P_Abbrev abbrev_tail = 0; 1468*7fd79137SRobert Mustacchi Dwarf_P_Die curdie = 0; 1469*7fd79137SRobert Mustacchi Dwarf_P_Die first_child = 0; 1470*7fd79137SRobert Mustacchi Dwarf_Word dw = 0; 1471*7fd79137SRobert Mustacchi Dwarf_Unsigned du = 0; 1472*7fd79137SRobert Mustacchi Dwarf_Half dh = 0; 1473*7fd79137SRobert Mustacchi Dwarf_Ubyte db = 0; 1474*7fd79137SRobert Mustacchi Dwarf_Half version = 0; /* Need 2 byte quantity. */ 1475*7fd79137SRobert Mustacchi Dwarf_Unsigned die_off = 0; /* Offset of die in debug_info. */ 1476*7fd79137SRobert Mustacchi int n_abbrevs = 0; 1477*7fd79137SRobert Mustacchi int res = 0; 1478*7fd79137SRobert Mustacchi unsigned marker_count = 0; 1479*7fd79137SRobert Mustacchi unsigned string_attr_count = 0; 1480*7fd79137SRobert Mustacchi unsigned string_attr_offset = 0; 1481*7fd79137SRobert Mustacchi 1482*7fd79137SRobert Mustacchi Dwarf_Small *start_info_sec = 0; 1483*7fd79137SRobert Mustacchi 1484*7fd79137SRobert Mustacchi int uwordb_size = dbg->de_offset_size; 1485*7fd79137SRobert Mustacchi int extension_size = dbg->de_64bit_extension ? 4 : 0; 1486*7fd79137SRobert Mustacchi 1487*7fd79137SRobert Mustacchi abbrev_head = abbrev_tail = NULL; 1488*7fd79137SRobert Mustacchi elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO]; 1489*7fd79137SRobert Mustacchi 1490*7fd79137SRobert Mustacchi /* write cu header */ 1491*7fd79137SRobert Mustacchi cu_header_size = BEGIN_LEN_SIZE + sizeof(Dwarf_Half) + /* version 1492*7fd79137SRobert Mustacchi stamp 1493*7fd79137SRobert Mustacchi */ 1494*7fd79137SRobert Mustacchi uwordb_size + /* offset into abbrev table */ 1495*7fd79137SRobert Mustacchi sizeof(Dwarf_Ubyte); /* size of target address */ 1496*7fd79137SRobert Mustacchi GET_CHUNK(dbg, elfsectno_of_debug_info, data, cu_header_size, 1497*7fd79137SRobert Mustacchi error); 1498*7fd79137SRobert Mustacchi start_info_sec = data; 1499*7fd79137SRobert Mustacchi if (extension_size) { 1500*7fd79137SRobert Mustacchi du = DISTINGUISHED_VALUE; 1501*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, 1502*7fd79137SRobert Mustacchi (const void *) &du, sizeof(du), extension_size); 1503*7fd79137SRobert Mustacchi data += extension_size; 1504*7fd79137SRobert Mustacchi } 1505*7fd79137SRobert Mustacchi du = 0; /* length of debug_info, not counting 1506*7fd79137SRobert Mustacchi this field itself (unknown at this 1507*7fd79137SRobert Mustacchi point). */ 1508*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, 1509*7fd79137SRobert Mustacchi (const void *) &du, sizeof(du), uwordb_size); 1510*7fd79137SRobert Mustacchi data += uwordb_size; 1511*7fd79137SRobert Mustacchi 1512*7fd79137SRobert Mustacchi version = CURRENT_VERSION_STAMP; /* assume this length will not 1513*7fd79137SRobert Mustacchi change */ 1514*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &version, 1515*7fd79137SRobert Mustacchi sizeof(version), sizeof(Dwarf_Half)); 1516*7fd79137SRobert Mustacchi data += sizeof(Dwarf_Half); 1517*7fd79137SRobert Mustacchi 1518*7fd79137SRobert Mustacchi du = 0; /* offset into abbrev table, not yet 1519*7fd79137SRobert Mustacchi known. */ 1520*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, 1521*7fd79137SRobert Mustacchi (const void *) &du, sizeof(du), uwordb_size); 1522*7fd79137SRobert Mustacchi data += uwordb_size; 1523*7fd79137SRobert Mustacchi 1524*7fd79137SRobert Mustacchi 1525*7fd79137SRobert Mustacchi db = dbg->de_pointer_size; 1526*7fd79137SRobert Mustacchi 1527*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 1528*7fd79137SRobert Mustacchi sizeof(db), 1); 1529*7fd79137SRobert Mustacchi 1530*7fd79137SRobert Mustacchi /* We have filled the chunk we got with GET_CHUNK. At this point we 1531*7fd79137SRobert Mustacchi no longer dare use "data" or "start_info_sec" as a pointer any 1532*7fd79137SRobert Mustacchi longer except to refer to that first small chunk for the cu 1533*7fd79137SRobert Mustacchi header. */ 1534*7fd79137SRobert Mustacchi 1535*7fd79137SRobert Mustacchi curdie = dbg->de_dies; 1536*7fd79137SRobert Mustacchi 1537*7fd79137SRobert Mustacchi /* create AT_macro_info if appropriate */ 1538*7fd79137SRobert Mustacchi if (dbg->de_first_macinfo != NULL) { 1539*7fd79137SRobert Mustacchi if (_dwarf_pro_add_AT_macro_info(dbg, curdie, 0, error) < 0) 1540*7fd79137SRobert Mustacchi return -1; 1541*7fd79137SRobert Mustacchi } 1542*7fd79137SRobert Mustacchi 1543*7fd79137SRobert Mustacchi /* create AT_stmt_list attribute if necessary */ 1544*7fd79137SRobert Mustacchi if (dwarf_need_debug_line_section(dbg) == TRUE) 1545*7fd79137SRobert Mustacchi if (_dwarf_pro_add_AT_stmt_list(dbg, curdie, error) < 0) 1546*7fd79137SRobert Mustacchi return -1; 1547*7fd79137SRobert Mustacchi 1548*7fd79137SRobert Mustacchi die_off = cu_header_size; 1549*7fd79137SRobert Mustacchi 1550*7fd79137SRobert Mustacchi /* 1551*7fd79137SRobert Mustacchi Relocation for abbrev offset in cu header store relocation 1552*7fd79137SRobert Mustacchi record in linked list */ 1553*7fd79137SRobert Mustacchi res = dbg->de_reloc_name(dbg, DEBUG_INFO, BEGIN_LEN_SIZE + 1554*7fd79137SRobert Mustacchi sizeof(Dwarf_Half), 1555*7fd79137SRobert Mustacchi /* r_offset */ 1556*7fd79137SRobert Mustacchi dbg->de_sect_name_idx[DEBUG_ABBREV], 1557*7fd79137SRobert Mustacchi dwarf_drt_data_reloc, uwordb_size); 1558*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 1559*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1); 1560*7fd79137SRobert Mustacchi } 1561*7fd79137SRobert Mustacchi 1562*7fd79137SRobert Mustacchi /* pass 0: only top level dies, add at_sibling attribute to those 1563*7fd79137SRobert Mustacchi dies with children */ 1564*7fd79137SRobert Mustacchi first_child = curdie->di_child; 1565*7fd79137SRobert Mustacchi while (first_child && first_child->di_right) { 1566*7fd79137SRobert Mustacchi if (first_child->di_child) 1567*7fd79137SRobert Mustacchi dwarf_add_AT_reference(dbg, 1568*7fd79137SRobert Mustacchi first_child, 1569*7fd79137SRobert Mustacchi DW_AT_sibling, 1570*7fd79137SRobert Mustacchi first_child->di_right, error); 1571*7fd79137SRobert Mustacchi first_child = first_child->di_right; 1572*7fd79137SRobert Mustacchi } 1573*7fd79137SRobert Mustacchi 1574*7fd79137SRobert Mustacchi /* pass 1: create abbrev info, get die offsets, calc relocations */ 1575*7fd79137SRobert Mustacchi marker_count = 0; 1576*7fd79137SRobert Mustacchi string_attr_count = 0; 1577*7fd79137SRobert Mustacchi while (curdie != NULL) { 1578*7fd79137SRobert Mustacchi int nbytes = 0; 1579*7fd79137SRobert Mustacchi Dwarf_P_Attribute curattr; 1580*7fd79137SRobert Mustacchi Dwarf_P_Attribute new_first_attr; 1581*7fd79137SRobert Mustacchi Dwarf_P_Attribute new_last_attr; 1582*7fd79137SRobert Mustacchi char *space = 0; 1583*7fd79137SRobert Mustacchi int res = 0; 1584*7fd79137SRobert Mustacchi char buff1[ENCODE_SPACE_NEEDED]; 1585*7fd79137SRobert Mustacchi int i = 0; 1586*7fd79137SRobert Mustacchi 1587*7fd79137SRobert Mustacchi curdie->di_offset = die_off; 1588*7fd79137SRobert Mustacchi 1589*7fd79137SRobert Mustacchi if (curdie->di_marker != 0) 1590*7fd79137SRobert Mustacchi marker_count++; 1591*7fd79137SRobert Mustacchi 1592*7fd79137SRobert Mustacchi curabbrev = _dwarf_pro_getabbrev(curdie, abbrev_head); 1593*7fd79137SRobert Mustacchi if (curabbrev == NULL) { 1594*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); 1595*7fd79137SRobert Mustacchi } 1596*7fd79137SRobert Mustacchi if (abbrev_head == NULL) { 1597*7fd79137SRobert Mustacchi n_abbrevs = 1; 1598*7fd79137SRobert Mustacchi curabbrev->abb_idx = n_abbrevs; 1599*7fd79137SRobert Mustacchi abbrev_tail = abbrev_head = curabbrev; 1600*7fd79137SRobert Mustacchi } else { 1601*7fd79137SRobert Mustacchi /* check if its a new abbreviation, if yes, add to tail */ 1602*7fd79137SRobert Mustacchi if (curabbrev->abb_idx == 0) { 1603*7fd79137SRobert Mustacchi n_abbrevs++; 1604*7fd79137SRobert Mustacchi curabbrev->abb_idx = n_abbrevs; 1605*7fd79137SRobert Mustacchi abbrev_tail->abb_next = curabbrev; 1606*7fd79137SRobert Mustacchi abbrev_tail = curabbrev; 1607*7fd79137SRobert Mustacchi } 1608*7fd79137SRobert Mustacchi } 1609*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_idx, 1610*7fd79137SRobert Mustacchi &nbytes, 1611*7fd79137SRobert Mustacchi buff1, sizeof(buff1)); 1612*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 1613*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); 1614*7fd79137SRobert Mustacchi } 1615*7fd79137SRobert Mustacchi space = _dwarf_p_get_alloc(dbg, nbytes); 1616*7fd79137SRobert Mustacchi if (space == NULL) { 1617*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); 1618*7fd79137SRobert Mustacchi } 1619*7fd79137SRobert Mustacchi memcpy(space, buff1, nbytes); 1620*7fd79137SRobert Mustacchi curdie->di_abbrev = space; 1621*7fd79137SRobert Mustacchi curdie->di_abbrev_nbytes = nbytes; 1622*7fd79137SRobert Mustacchi die_off += nbytes; 1623*7fd79137SRobert Mustacchi 1624*7fd79137SRobert Mustacchi /* Resorting the attributes!! */ 1625*7fd79137SRobert Mustacchi new_first_attr = new_last_attr = NULL; 1626*7fd79137SRobert Mustacchi curattr = curdie->di_attrs; 1627*7fd79137SRobert Mustacchi for (i = 0; i < (int)curabbrev->abb_n_attr; i++) { 1628*7fd79137SRobert Mustacchi Dwarf_P_Attribute ca; 1629*7fd79137SRobert Mustacchi Dwarf_P_Attribute cl; 1630*7fd79137SRobert Mustacchi 1631*7fd79137SRobert Mustacchi /* The following should always find an attribute! */ 1632*7fd79137SRobert Mustacchi for (ca = cl = curattr; 1633*7fd79137SRobert Mustacchi ca && curabbrev->abb_attrs[i] != ca->ar_attribute; 1634*7fd79137SRobert Mustacchi cl = ca, ca = ca->ar_next) 1635*7fd79137SRobert Mustacchi { 1636*7fd79137SRobert Mustacchi } 1637*7fd79137SRobert Mustacchi 1638*7fd79137SRobert Mustacchi if (!ca) { 1639*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg,DW_DLE_ABBREV_ALLOC, -1); 1640*7fd79137SRobert Mustacchi } 1641*7fd79137SRobert Mustacchi 1642*7fd79137SRobert Mustacchi /* Remove the attribute from the old list. */ 1643*7fd79137SRobert Mustacchi if (ca == curattr) { 1644*7fd79137SRobert Mustacchi curattr = ca->ar_next; 1645*7fd79137SRobert Mustacchi } else { 1646*7fd79137SRobert Mustacchi cl->ar_next = ca->ar_next; 1647*7fd79137SRobert Mustacchi } 1648*7fd79137SRobert Mustacchi 1649*7fd79137SRobert Mustacchi ca->ar_next = NULL; 1650*7fd79137SRobert Mustacchi 1651*7fd79137SRobert Mustacchi /* Add the attribute to the new list. */ 1652*7fd79137SRobert Mustacchi if (new_first_attr == NULL) { 1653*7fd79137SRobert Mustacchi new_first_attr = new_last_attr = ca; 1654*7fd79137SRobert Mustacchi } else { 1655*7fd79137SRobert Mustacchi new_last_attr->ar_next = ca; 1656*7fd79137SRobert Mustacchi new_last_attr = ca; 1657*7fd79137SRobert Mustacchi } 1658*7fd79137SRobert Mustacchi } 1659*7fd79137SRobert Mustacchi 1660*7fd79137SRobert Mustacchi curdie->di_attrs = new_first_attr; 1661*7fd79137SRobert Mustacchi 1662*7fd79137SRobert Mustacchi curattr = curdie->di_attrs; 1663*7fd79137SRobert Mustacchi 1664*7fd79137SRobert Mustacchi while (curattr) { 1665*7fd79137SRobert Mustacchi if (curattr->ar_rel_type != R_MIPS_NONE) { 1666*7fd79137SRobert Mustacchi switch (curattr->ar_attribute) { 1667*7fd79137SRobert Mustacchi case DW_AT_stmt_list: 1668*7fd79137SRobert Mustacchi curattr->ar_rel_symidx = 1669*7fd79137SRobert Mustacchi dbg->de_sect_name_idx[DEBUG_LINE]; 1670*7fd79137SRobert Mustacchi break; 1671*7fd79137SRobert Mustacchi case DW_AT_MIPS_fde: 1672*7fd79137SRobert Mustacchi curattr->ar_rel_symidx = 1673*7fd79137SRobert Mustacchi dbg->de_sect_name_idx[DEBUG_FRAME]; 1674*7fd79137SRobert Mustacchi break; 1675*7fd79137SRobert Mustacchi case DW_AT_macro_info: 1676*7fd79137SRobert Mustacchi curattr->ar_rel_symidx = 1677*7fd79137SRobert Mustacchi dbg->de_sect_name_idx[DEBUG_MACINFO]; 1678*7fd79137SRobert Mustacchi break; 1679*7fd79137SRobert Mustacchi default: 1680*7fd79137SRobert Mustacchi break; 1681*7fd79137SRobert Mustacchi } 1682*7fd79137SRobert Mustacchi res = dbg->de_reloc_name(dbg, DEBUG_INFO, die_off + curattr->ar_rel_offset, /* r_offset 1683*7fd79137SRobert Mustacchi */ 1684*7fd79137SRobert Mustacchi curattr->ar_rel_symidx, 1685*7fd79137SRobert Mustacchi dwarf_drt_data_reloc, 1686*7fd79137SRobert Mustacchi curattr->ar_reloc_len); 1687*7fd79137SRobert Mustacchi 1688*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 1689*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1); 1690*7fd79137SRobert Mustacchi } 1691*7fd79137SRobert Mustacchi 1692*7fd79137SRobert Mustacchi } 1693*7fd79137SRobert Mustacchi if (curattr->ar_attribute_form == DW_FORM_string) { 1694*7fd79137SRobert Mustacchi string_attr_count++; 1695*7fd79137SRobert Mustacchi } 1696*7fd79137SRobert Mustacchi die_off += curattr->ar_nbytes; 1697*7fd79137SRobert Mustacchi curattr = curattr->ar_next; 1698*7fd79137SRobert Mustacchi } 1699*7fd79137SRobert Mustacchi 1700*7fd79137SRobert Mustacchi /* depth first search */ 1701*7fd79137SRobert Mustacchi if (curdie->di_child) 1702*7fd79137SRobert Mustacchi curdie = curdie->di_child; 1703*7fd79137SRobert Mustacchi else { 1704*7fd79137SRobert Mustacchi while (curdie != NULL && curdie->di_right == NULL) { 1705*7fd79137SRobert Mustacchi curdie = curdie->di_parent; 1706*7fd79137SRobert Mustacchi die_off++; /* since we are writing a null die at 1707*7fd79137SRobert Mustacchi the end of each sibling chain */ 1708*7fd79137SRobert Mustacchi } 1709*7fd79137SRobert Mustacchi if (curdie != NULL) 1710*7fd79137SRobert Mustacchi curdie = curdie->di_right; 1711*7fd79137SRobert Mustacchi } 1712*7fd79137SRobert Mustacchi 1713*7fd79137SRobert Mustacchi } /* end while (curdie != NULL) */ 1714*7fd79137SRobert Mustacchi 1715*7fd79137SRobert Mustacchi res = marker_init(dbg, marker_count); 1716*7fd79137SRobert Mustacchi if (res == -1) { 1717*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1); 1718*7fd79137SRobert Mustacchi } 1719*7fd79137SRobert Mustacchi res = string_attr_init(dbg, DEBUG_INFO, string_attr_count); 1720*7fd79137SRobert Mustacchi if (res == -1) { 1721*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1); 1722*7fd79137SRobert Mustacchi } 1723*7fd79137SRobert Mustacchi 1724*7fd79137SRobert Mustacchi /* Pass 2: Write out the die information Here 'data' is a 1725*7fd79137SRobert Mustacchi temporary, one block for each GET_CHUNK. 'data' is overused. */ 1726*7fd79137SRobert Mustacchi curdie = dbg->de_dies; 1727*7fd79137SRobert Mustacchi while (curdie != NULL) { 1728*7fd79137SRobert Mustacchi Dwarf_P_Attribute curattr; 1729*7fd79137SRobert Mustacchi 1730*7fd79137SRobert Mustacchi if (curdie->di_marker != 0) { 1731*7fd79137SRobert Mustacchi res = marker_add(dbg, curdie->di_offset, curdie->di_marker); 1732*7fd79137SRobert Mustacchi if (res == -1) { 1733*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1); 1734*7fd79137SRobert Mustacchi } 1735*7fd79137SRobert Mustacchi } 1736*7fd79137SRobert Mustacchi 1737*7fd79137SRobert Mustacchi /* index to abbreviation table */ 1738*7fd79137SRobert Mustacchi GET_CHUNK(dbg, elfsectno_of_debug_info, 1739*7fd79137SRobert Mustacchi data, curdie->di_abbrev_nbytes, error); 1740*7fd79137SRobert Mustacchi 1741*7fd79137SRobert Mustacchi memcpy((void *) data, 1742*7fd79137SRobert Mustacchi (const void *) curdie->di_abbrev, 1743*7fd79137SRobert Mustacchi curdie->di_abbrev_nbytes); 1744*7fd79137SRobert Mustacchi 1745*7fd79137SRobert Mustacchi /* Attribute values - need to fill in all form attributes */ 1746*7fd79137SRobert Mustacchi curattr = curdie->di_attrs; 1747*7fd79137SRobert Mustacchi string_attr_offset = curdie->di_offset + curdie->di_abbrev_nbytes; 1748*7fd79137SRobert Mustacchi 1749*7fd79137SRobert Mustacchi while (curattr) { 1750*7fd79137SRobert Mustacchi GET_CHUNK(dbg, elfsectno_of_debug_info, data, 1751*7fd79137SRobert Mustacchi (unsigned long) curattr->ar_nbytes, error); 1752*7fd79137SRobert Mustacchi switch (curattr->ar_attribute_form) { 1753*7fd79137SRobert Mustacchi case DW_FORM_ref1: 1754*7fd79137SRobert Mustacchi { 1755*7fd79137SRobert Mustacchi if (curattr->ar_ref_die->di_offset > 1756*7fd79137SRobert Mustacchi (unsigned) 0xff) { 1757*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1); 1758*7fd79137SRobert Mustacchi } 1759*7fd79137SRobert Mustacchi db = curattr->ar_ref_die->di_offset; 1760*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, 1761*7fd79137SRobert Mustacchi (const void *) &db, 1762*7fd79137SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte)); 1763*7fd79137SRobert Mustacchi break; 1764*7fd79137SRobert Mustacchi } 1765*7fd79137SRobert Mustacchi case DW_FORM_ref2: 1766*7fd79137SRobert Mustacchi { 1767*7fd79137SRobert Mustacchi if (curattr->ar_ref_die->di_offset > 1768*7fd79137SRobert Mustacchi (unsigned) 0xffff) { 1769*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1); 1770*7fd79137SRobert Mustacchi } 1771*7fd79137SRobert Mustacchi dh = curattr->ar_ref_die->di_offset; 1772*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, 1773*7fd79137SRobert Mustacchi (const void *) &dh, 1774*7fd79137SRobert Mustacchi sizeof(dh), sizeof(Dwarf_Half)); 1775*7fd79137SRobert Mustacchi break; 1776*7fd79137SRobert Mustacchi } 1777*7fd79137SRobert Mustacchi case DW_FORM_ref_addr: 1778*7fd79137SRobert Mustacchi { 1779*7fd79137SRobert Mustacchi /* curattr->ar_ref_die == NULL! 1780*7fd79137SRobert Mustacchi * 1781*7fd79137SRobert Mustacchi * ref_addr doesn't take a CU-offset. 1782*7fd79137SRobert Mustacchi * This is different than other refs. 1783*7fd79137SRobert Mustacchi * This value will be set by the user of the 1784*7fd79137SRobert Mustacchi * producer library using a relocation. 1785*7fd79137SRobert Mustacchi * No need to set a value here. 1786*7fd79137SRobert Mustacchi */ 1787*7fd79137SRobert Mustacchi #if 0 1788*7fd79137SRobert Mustacchi du = curattr->ar_ref_die->di_offset; 1789*7fd79137SRobert Mustacchi { 1790*7fd79137SRobert Mustacchi /* ref to offset of die */ 1791*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, 1792*7fd79137SRobert Mustacchi (const void *) &du, 1793*7fd79137SRobert Mustacchi sizeof(du), uwordb_size); 1794*7fd79137SRobert Mustacchi } 1795*7fd79137SRobert Mustacchi #endif 1796*7fd79137SRobert Mustacchi break; 1797*7fd79137SRobert Mustacchi 1798*7fd79137SRobert Mustacchi } 1799*7fd79137SRobert Mustacchi case DW_FORM_ref4: 1800*7fd79137SRobert Mustacchi { 1801*7fd79137SRobert Mustacchi if (curattr->ar_ref_die->di_offset > 1802*7fd79137SRobert Mustacchi (unsigned) 0xffffffff) { 1803*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1); 1804*7fd79137SRobert Mustacchi } 1805*7fd79137SRobert Mustacchi dw = (Dwarf_Word) curattr->ar_ref_die->di_offset; 1806*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, 1807*7fd79137SRobert Mustacchi (const void *) &dw, 1808*7fd79137SRobert Mustacchi sizeof(dw), sizeof(Dwarf_ufixed)); 1809*7fd79137SRobert Mustacchi break; 1810*7fd79137SRobert Mustacchi } 1811*7fd79137SRobert Mustacchi case DW_FORM_ref8: 1812*7fd79137SRobert Mustacchi du = curattr->ar_ref_die->di_offset; 1813*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, 1814*7fd79137SRobert Mustacchi (const void *) &du, 1815*7fd79137SRobert Mustacchi sizeof(du), sizeof(Dwarf_Unsigned)); 1816*7fd79137SRobert Mustacchi break; 1817*7fd79137SRobert Mustacchi case DW_FORM_ref_udata: 1818*7fd79137SRobert Mustacchi { /* unsigned leb128 offset */ 1819*7fd79137SRobert Mustacchi 1820*7fd79137SRobert Mustacchi int nbytes; 1821*7fd79137SRobert Mustacchi char buff1[ENCODE_SPACE_NEEDED]; 1822*7fd79137SRobert Mustacchi 1823*7fd79137SRobert Mustacchi res = 1824*7fd79137SRobert Mustacchi _dwarf_pro_encode_leb128_nm(curattr-> 1825*7fd79137SRobert Mustacchi ar_ref_die-> 1826*7fd79137SRobert Mustacchi di_offset, &nbytes, 1827*7fd79137SRobert Mustacchi buff1, 1828*7fd79137SRobert Mustacchi sizeof(buff1)); 1829*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 1830*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); 1831*7fd79137SRobert Mustacchi } 1832*7fd79137SRobert Mustacchi 1833*7fd79137SRobert Mustacchi memcpy(data, buff1, nbytes); 1834*7fd79137SRobert Mustacchi break; 1835*7fd79137SRobert Mustacchi } 1836*7fd79137SRobert Mustacchi default: 1837*7fd79137SRobert Mustacchi memcpy((void *) data, 1838*7fd79137SRobert Mustacchi (const void *) curattr->ar_data, 1839*7fd79137SRobert Mustacchi curattr->ar_nbytes); 1840*7fd79137SRobert Mustacchi break; 1841*7fd79137SRobert Mustacchi } 1842*7fd79137SRobert Mustacchi if (curattr->ar_attribute_form == DW_FORM_string) { 1843*7fd79137SRobert Mustacchi string_attr_add(dbg, DEBUG_INFO, string_attr_offset, curattr); 1844*7fd79137SRobert Mustacchi } 1845*7fd79137SRobert Mustacchi string_attr_offset += curattr->ar_nbytes; 1846*7fd79137SRobert Mustacchi curattr = curattr->ar_next; 1847*7fd79137SRobert Mustacchi } 1848*7fd79137SRobert Mustacchi 1849*7fd79137SRobert Mustacchi /* depth first search */ 1850*7fd79137SRobert Mustacchi if (curdie->di_child) 1851*7fd79137SRobert Mustacchi curdie = curdie->di_child; 1852*7fd79137SRobert Mustacchi else { 1853*7fd79137SRobert Mustacchi while (curdie != NULL && curdie->di_right == NULL) { 1854*7fd79137SRobert Mustacchi GET_CHUNK(dbg, elfsectno_of_debug_info, data, 1, error); 1855*7fd79137SRobert Mustacchi *data = '\0'; 1856*7fd79137SRobert Mustacchi curdie = curdie->di_parent; 1857*7fd79137SRobert Mustacchi } 1858*7fd79137SRobert Mustacchi if (curdie != NULL) 1859*7fd79137SRobert Mustacchi curdie = curdie->di_right; 1860*7fd79137SRobert Mustacchi } 1861*7fd79137SRobert Mustacchi } /* end while (curdir != NULL) */ 1862*7fd79137SRobert Mustacchi 1863*7fd79137SRobert Mustacchi /* Write out debug_info size */ 1864*7fd79137SRobert Mustacchi /* Dont include length field or extension bytes */ 1865*7fd79137SRobert Mustacchi du = die_off - BEGIN_LEN_SIZE; 1866*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) (start_info_sec + extension_size), 1867*7fd79137SRobert Mustacchi (const void *) &du, sizeof(du), uwordb_size); 1868*7fd79137SRobert Mustacchi 1869*7fd79137SRobert Mustacchi 1870*7fd79137SRobert Mustacchi data = 0; /* Emphasise not usable now */ 1871*7fd79137SRobert Mustacchi 1872*7fd79137SRobert Mustacchi /* Write out debug_abbrev section */ 1873*7fd79137SRobert Mustacchi abbrevsectno = dbg->de_elf_sects[DEBUG_ABBREV]; 1874*7fd79137SRobert Mustacchi 1875*7fd79137SRobert Mustacchi curabbrev = abbrev_head; 1876*7fd79137SRobert Mustacchi while (curabbrev) { 1877*7fd79137SRobert Mustacchi char *val; 1878*7fd79137SRobert Mustacchi int nbytes; 1879*7fd79137SRobert Mustacchi int idx; 1880*7fd79137SRobert Mustacchi int res; 1881*7fd79137SRobert Mustacchi char buff1[ENCODE_SPACE_NEEDED]; 1882*7fd79137SRobert Mustacchi 1883*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_idx, &nbytes, 1884*7fd79137SRobert Mustacchi buff1, sizeof(buff1)); 1885*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 1886*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); 1887*7fd79137SRobert Mustacchi } 1888*7fd79137SRobert Mustacchi 1889*7fd79137SRobert Mustacchi GET_CHUNK(dbg, abbrevsectno, data, nbytes, error); 1890*7fd79137SRobert Mustacchi val = buff1; 1891*7fd79137SRobert Mustacchi memcpy((void *) data, (const void *) val, nbytes); 1892*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_tag, &nbytes, 1893*7fd79137SRobert Mustacchi buff1, sizeof(buff1)); 1894*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 1895*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); 1896*7fd79137SRobert Mustacchi } 1897*7fd79137SRobert Mustacchi val = buff1; 1898*7fd79137SRobert Mustacchi GET_CHUNK(dbg, abbrevsectno, data, nbytes, error); 1899*7fd79137SRobert Mustacchi memcpy((void *) data, (const void *) val, nbytes); 1900*7fd79137SRobert Mustacchi db = curabbrev->abb_children; 1901*7fd79137SRobert Mustacchi GET_CHUNK(dbg, abbrevsectno, data, sizeof(Dwarf_Ubyte), error); 1902*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db, 1903*7fd79137SRobert Mustacchi sizeof(db), sizeof(Dwarf_Ubyte)); 1904*7fd79137SRobert Mustacchi 1905*7fd79137SRobert Mustacchi /* add attributes and forms */ 1906*7fd79137SRobert Mustacchi for (idx = 0; idx < curabbrev->abb_n_attr; idx++) { 1907*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_attrs[idx], 1908*7fd79137SRobert Mustacchi &nbytes, 1909*7fd79137SRobert Mustacchi buff1, sizeof(buff1)); 1910*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 1911*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); 1912*7fd79137SRobert Mustacchi } 1913*7fd79137SRobert Mustacchi val = buff1; 1914*7fd79137SRobert Mustacchi GET_CHUNK(dbg, abbrevsectno, data, nbytes, error); 1915*7fd79137SRobert Mustacchi memcpy((void *) data, (const void *) val, nbytes); 1916*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_forms[idx], 1917*7fd79137SRobert Mustacchi &nbytes, 1918*7fd79137SRobert Mustacchi buff1, sizeof(buff1)); 1919*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 1920*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1); 1921*7fd79137SRobert Mustacchi } 1922*7fd79137SRobert Mustacchi val = buff1; 1923*7fd79137SRobert Mustacchi GET_CHUNK(dbg, abbrevsectno, data, nbytes, error); 1924*7fd79137SRobert Mustacchi memcpy((void *) data, (const void *) val, nbytes); 1925*7fd79137SRobert Mustacchi } 1926*7fd79137SRobert Mustacchi GET_CHUNK(dbg, abbrevsectno, data, 2, error); /* two zeros, 1927*7fd79137SRobert Mustacchi for last 1928*7fd79137SRobert Mustacchi entry, see 1929*7fd79137SRobert Mustacchi dwarf2 sec 1930*7fd79137SRobert Mustacchi 7.5.3 */ 1931*7fd79137SRobert Mustacchi *data = 0; 1932*7fd79137SRobert Mustacchi data++; 1933*7fd79137SRobert Mustacchi *data = 0; 1934*7fd79137SRobert Mustacchi 1935*7fd79137SRobert Mustacchi curabbrev = curabbrev->abb_next; 1936*7fd79137SRobert Mustacchi } 1937*7fd79137SRobert Mustacchi 1938*7fd79137SRobert Mustacchi GET_CHUNK(dbg, abbrevsectno, data, 1, error); /* one zero, 1939*7fd79137SRobert Mustacchi for end of 1940*7fd79137SRobert Mustacchi cu, see 1941*7fd79137SRobert Mustacchi dwarf2 sec 1942*7fd79137SRobert Mustacchi 7.5.3 */ 1943*7fd79137SRobert Mustacchi *data = 0; 1944*7fd79137SRobert Mustacchi 1945*7fd79137SRobert Mustacchi 1946*7fd79137SRobert Mustacchi return (int) dbg->de_n_debug_sect; 1947*7fd79137SRobert Mustacchi } 1948*7fd79137SRobert Mustacchi 1949*7fd79137SRobert Mustacchi 1950*7fd79137SRobert Mustacchi /*--------------------------------------------------------------------- 1951*7fd79137SRobert Mustacchi Get a buffer of section data. 1952*7fd79137SRobert Mustacchi section_idx is the elf-section number that this data applies to. 1953*7fd79137SRobert Mustacchi length shows length of returned data 1954*7fd79137SRobert Mustacchi ----------------------------------------------------------------------*/ 1955*7fd79137SRobert Mustacchi /*ARGSUSED*/ /* pretend all args used */ 1956*7fd79137SRobert Mustacchi Dwarf_Ptr 1957*7fd79137SRobert Mustacchi dwarf_get_section_bytes(Dwarf_P_Debug dbg, 1958*7fd79137SRobert Mustacchi Dwarf_Signed dwarf_section, 1959*7fd79137SRobert Mustacchi Dwarf_Signed * section_idx, 1960*7fd79137SRobert Mustacchi Dwarf_Unsigned * length, Dwarf_Error * error) 1961*7fd79137SRobert Mustacchi { 1962*7fd79137SRobert Mustacchi Dwarf_Ptr buf; 1963*7fd79137SRobert Mustacchi 1964*7fd79137SRobert Mustacchi if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) { 1965*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, NULL); 1966*7fd79137SRobert Mustacchi } 1967*7fd79137SRobert Mustacchi 1968*7fd79137SRobert Mustacchi if (dbg->de_debug_sects == 0) { 1969*7fd79137SRobert Mustacchi /* no more data !! */ 1970*7fd79137SRobert Mustacchi return NULL; 1971*7fd79137SRobert Mustacchi } 1972*7fd79137SRobert Mustacchi if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) { 1973*7fd79137SRobert Mustacchi /* no data ever entered !! */ 1974*7fd79137SRobert Mustacchi return NULL; 1975*7fd79137SRobert Mustacchi } 1976*7fd79137SRobert Mustacchi *section_idx = dbg->de_debug_sects->ds_elf_sect_no; 1977*7fd79137SRobert Mustacchi *length = dbg->de_debug_sects->ds_nbytes; 1978*7fd79137SRobert Mustacchi 1979*7fd79137SRobert Mustacchi buf = (Dwarf_Ptr *) dbg->de_debug_sects->ds_data; 1980*7fd79137SRobert Mustacchi 1981*7fd79137SRobert Mustacchi dbg->de_debug_sects = dbg->de_debug_sects->ds_next; 1982*7fd79137SRobert Mustacchi 1983*7fd79137SRobert Mustacchi /* We may want to call the section stuff more than once: see 1984*7fd79137SRobert Mustacchi dwarf_reset_section_bytes() do not do: dbg->de_n_debug_sect--; */ 1985*7fd79137SRobert Mustacchi 1986*7fd79137SRobert Mustacchi return buf; 1987*7fd79137SRobert Mustacchi } 1988*7fd79137SRobert Mustacchi 1989*7fd79137SRobert Mustacchi /* 1990*7fd79137SRobert Mustacchi No errors possible. 1991*7fd79137SRobert Mustacchi */ 1992*7fd79137SRobert Mustacchi void 1993*7fd79137SRobert Mustacchi dwarf_reset_section_bytes(Dwarf_P_Debug dbg) 1994*7fd79137SRobert Mustacchi { 1995*7fd79137SRobert Mustacchi dbg->de_debug_sects = dbg->de_first_debug_sect; 1996*7fd79137SRobert Mustacchi /* No need to reset; commented out decrement. dbg->de_n_debug_sect 1997*7fd79137SRobert Mustacchi = ???; */ 1998*7fd79137SRobert Mustacchi dbg->de_reloc_next_to_return = 0; 1999*7fd79137SRobert Mustacchi dbg->de_sect_sa_next_to_return = 0; 2000*7fd79137SRobert Mustacchi } 2001*7fd79137SRobert Mustacchi 2002*7fd79137SRobert Mustacchi /* 2003*7fd79137SRobert Mustacchi Storage handler. Gets either a new chunk of memory, or 2004*7fd79137SRobert Mustacchi a pointer in existing memory, from the linked list attached 2005*7fd79137SRobert Mustacchi to dbg at de_debug_sects, depending on size of nbytes 2006*7fd79137SRobert Mustacchi 2007*7fd79137SRobert Mustacchi Assume dbg not null, checked in top level routine 2008*7fd79137SRobert Mustacchi 2009*7fd79137SRobert Mustacchi Returns a pointer to the allocated buffer space for the 2010*7fd79137SRobert Mustacchi lib to fill in, predincrements next-to-use count so the 2011*7fd79137SRobert Mustacchi space requested is already counted 'used' 2012*7fd79137SRobert Mustacchi when this returns (ie, reserved). 2013*7fd79137SRobert Mustacchi 2014*7fd79137SRobert Mustacchi */ 2015*7fd79137SRobert Mustacchi Dwarf_Small * 2016*7fd79137SRobert Mustacchi _dwarf_pro_buffer(Dwarf_P_Debug dbg, 2017*7fd79137SRobert Mustacchi int elfsectno, unsigned long nbytes) 2018*7fd79137SRobert Mustacchi { 2019*7fd79137SRobert Mustacchi Dwarf_P_Section_Data cursect; 2020*7fd79137SRobert Mustacchi 2021*7fd79137SRobert Mustacchi 2022*7fd79137SRobert Mustacchi cursect = dbg->de_current_active_section; 2023*7fd79137SRobert Mustacchi /* By using MAGIC_SECT_NO we allow the following MAGIC_SECT_NO must 2024*7fd79137SRobert Mustacchi not match any legit section number. test to have just two 2025*7fd79137SRobert Mustacchi clauses (no NULL pointer test) See dwarf_producer_init(). */ 2026*7fd79137SRobert Mustacchi if ((cursect->ds_elf_sect_no != elfsectno) || 2027*7fd79137SRobert Mustacchi ((cursect->ds_nbytes + nbytes) > cursect->ds_orig_alloc) 2028*7fd79137SRobert Mustacchi ) { 2029*7fd79137SRobert Mustacchi 2030*7fd79137SRobert Mustacchi /* Either the elf section has changed or there is not enough 2031*7fd79137SRobert Mustacchi space in the current section. 2032*7fd79137SRobert Mustacchi 2033*7fd79137SRobert Mustacchi Create a new Dwarf_P_Section_Data_s for the chunk. and have 2034*7fd79137SRobert Mustacchi space 'on the end' for the buffer itself so we just do one 2035*7fd79137SRobert Mustacchi malloc (not two). 2036*7fd79137SRobert Mustacchi 2037*7fd79137SRobert Mustacchi */ 2038*7fd79137SRobert Mustacchi unsigned long space = nbytes; 2039*7fd79137SRobert Mustacchi 2040*7fd79137SRobert Mustacchi if (nbytes < CHUNK_SIZE) 2041*7fd79137SRobert Mustacchi space = CHUNK_SIZE; 2042*7fd79137SRobert Mustacchi 2043*7fd79137SRobert Mustacchi cursect = (Dwarf_P_Section_Data) 2044*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, 2045*7fd79137SRobert Mustacchi sizeof(struct Dwarf_P_Section_Data_s) 2046*7fd79137SRobert Mustacchi + space); 2047*7fd79137SRobert Mustacchi 2048*7fd79137SRobert Mustacchi 2049*7fd79137SRobert Mustacchi if (cursect == NULL) 2050*7fd79137SRobert Mustacchi return (NULL); 2051*7fd79137SRobert Mustacchi 2052*7fd79137SRobert Mustacchi /* _dwarf_p_get_alloc zeroes the space... */ 2053*7fd79137SRobert Mustacchi 2054*7fd79137SRobert Mustacchi cursect->ds_data = (char *) cursect + 2055*7fd79137SRobert Mustacchi sizeof(struct Dwarf_P_Section_Data_s); 2056*7fd79137SRobert Mustacchi cursect->ds_orig_alloc = space; 2057*7fd79137SRobert Mustacchi cursect->ds_elf_sect_no = elfsectno; 2058*7fd79137SRobert Mustacchi cursect->ds_nbytes = nbytes; /* reserve this number of bytes 2059*7fd79137SRobert Mustacchi of space for caller to fill 2060*7fd79137SRobert Mustacchi in */ 2061*7fd79137SRobert Mustacchi 2062*7fd79137SRobert Mustacchi /* Now link on the end of the list, and mark this one as the 2063*7fd79137SRobert Mustacchi current one */ 2064*7fd79137SRobert Mustacchi 2065*7fd79137SRobert Mustacchi if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) { 2066*7fd79137SRobert Mustacchi /* the only entry is the special one for 'no entry' so 2067*7fd79137SRobert Mustacchi delete that phony one while adding this initial real 2068*7fd79137SRobert Mustacchi one. */ 2069*7fd79137SRobert Mustacchi dbg->de_debug_sects = cursect; 2070*7fd79137SRobert Mustacchi dbg->de_current_active_section = cursect; 2071*7fd79137SRobert Mustacchi dbg->de_first_debug_sect = cursect; 2072*7fd79137SRobert Mustacchi } else { 2073*7fd79137SRobert Mustacchi dbg->de_current_active_section->ds_next = cursect; 2074*7fd79137SRobert Mustacchi dbg->de_current_active_section = cursect; 2075*7fd79137SRobert Mustacchi } 2076*7fd79137SRobert Mustacchi dbg->de_n_debug_sect++; 2077*7fd79137SRobert Mustacchi 2078*7fd79137SRobert Mustacchi return ((Dwarf_Small *) cursect->ds_data); 2079*7fd79137SRobert Mustacchi } 2080*7fd79137SRobert Mustacchi 2081*7fd79137SRobert Mustacchi /* There is enough space in the current buffer */ 2082*7fd79137SRobert Mustacchi { 2083*7fd79137SRobert Mustacchi Dwarf_Small *space_for_caller = (Dwarf_Small *) 2084*7fd79137SRobert Mustacchi (cursect->ds_data + cursect->ds_nbytes); 2085*7fd79137SRobert Mustacchi 2086*7fd79137SRobert Mustacchi cursect->ds_nbytes += nbytes; 2087*7fd79137SRobert Mustacchi return space_for_caller; 2088*7fd79137SRobert Mustacchi } 2089*7fd79137SRobert Mustacchi } 2090*7fd79137SRobert Mustacchi 2091*7fd79137SRobert Mustacchi 2092*7fd79137SRobert Mustacchi /*------------------------------------------------------------ 2093*7fd79137SRobert Mustacchi Given address advance and line advance, it gives 2094*7fd79137SRobert Mustacchi either special opcode, or a number < 0 2095*7fd79137SRobert Mustacchi ------------------------------------------------------------*/ 2096*7fd79137SRobert Mustacchi static int 2097*7fd79137SRobert Mustacchi _dwarf_pro_get_opc(Dwarf_Unsigned addr_adv, int line_adv) 2098*7fd79137SRobert Mustacchi { 2099*7fd79137SRobert Mustacchi int opc; 2100*7fd79137SRobert Mustacchi 2101*7fd79137SRobert Mustacchi addr_adv = addr_adv / MIN_INST_LENGTH; 2102*7fd79137SRobert Mustacchi if (line_adv == 0 && addr_adv == 0) 2103*7fd79137SRobert Mustacchi return OPC_INCS_ZERO; 2104*7fd79137SRobert Mustacchi if (line_adv >= LINE_BASE && line_adv < LINE_BASE + LINE_RANGE) { 2105*7fd79137SRobert Mustacchi opc = 2106*7fd79137SRobert Mustacchi (line_adv - LINE_BASE) + (addr_adv * LINE_RANGE) + 2107*7fd79137SRobert Mustacchi OPCODE_BASE; 2108*7fd79137SRobert Mustacchi if (opc > 255) 2109*7fd79137SRobert Mustacchi return OPC_OUT_OF_RANGE; 2110*7fd79137SRobert Mustacchi return opc; 2111*7fd79137SRobert Mustacchi } else 2112*7fd79137SRobert Mustacchi return LINE_OUT_OF_RANGE; 2113*7fd79137SRobert Mustacchi } 2114*7fd79137SRobert Mustacchi 2115*7fd79137SRobert Mustacchi /*----------------------------------------------------------------------- 2116*7fd79137SRobert Mustacchi Handles abbreviations. It takes a die, searches through 2117*7fd79137SRobert Mustacchi current list of abbreviations for matching one. If it 2118*7fd79137SRobert Mustacchi finds one, it returns a pointer to it, and if it doesnt, 2119*7fd79137SRobert Mustacchi it returns a new one. Upto the user of this function to 2120*7fd79137SRobert Mustacchi link it up to the abbreviation head. If its a new one, 2121*7fd79137SRobert Mustacchi abb_idx has 0. 2122*7fd79137SRobert Mustacchi -----------------------------------------------------------------------*/ 2123*7fd79137SRobert Mustacchi static Dwarf_P_Abbrev 2124*7fd79137SRobert Mustacchi _dwarf_pro_getabbrev(Dwarf_P_Die die, Dwarf_P_Abbrev head) 2125*7fd79137SRobert Mustacchi { 2126*7fd79137SRobert Mustacchi Dwarf_P_Abbrev curabbrev; 2127*7fd79137SRobert Mustacchi Dwarf_P_Attribute curattr; 2128*7fd79137SRobert Mustacchi int res1; 2129*7fd79137SRobert Mustacchi int nattrs; 2130*7fd79137SRobert Mustacchi int match; 2131*7fd79137SRobert Mustacchi Dwarf_ufixed *forms = 0; 2132*7fd79137SRobert Mustacchi Dwarf_ufixed *attrs = 0; 2133*7fd79137SRobert Mustacchi 2134*7fd79137SRobert Mustacchi curabbrev = head; 2135*7fd79137SRobert Mustacchi while (curabbrev) { 2136*7fd79137SRobert Mustacchi if ((die->di_tag == curabbrev->abb_tag) && 2137*7fd79137SRobert Mustacchi ((die->di_child != NULL && 2138*7fd79137SRobert Mustacchi curabbrev->abb_children == DW_CHILDREN_yes) || 2139*7fd79137SRobert Mustacchi (die->di_child == NULL && 2140*7fd79137SRobert Mustacchi curabbrev->abb_children == DW_CHILDREN_no)) && 2141*7fd79137SRobert Mustacchi (die->di_n_attr == curabbrev->abb_n_attr)) { 2142*7fd79137SRobert Mustacchi 2143*7fd79137SRobert Mustacchi /* There is a chance of a match. */ 2144*7fd79137SRobert Mustacchi curattr = die->di_attrs; 2145*7fd79137SRobert Mustacchi match = 1; /* Assume match found. */ 2146*7fd79137SRobert Mustacchi while (match && curattr) { 2147*7fd79137SRobert Mustacchi res1 = _dwarf_pro_match_attr(curattr, 2148*7fd79137SRobert Mustacchi curabbrev, 2149*7fd79137SRobert Mustacchi (int) curabbrev-> 2150*7fd79137SRobert Mustacchi abb_n_attr); 2151*7fd79137SRobert Mustacchi if (res1 == 0) 2152*7fd79137SRobert Mustacchi match = 0; 2153*7fd79137SRobert Mustacchi curattr = curattr->ar_next; 2154*7fd79137SRobert Mustacchi } 2155*7fd79137SRobert Mustacchi if (match == 1) 2156*7fd79137SRobert Mustacchi return curabbrev; 2157*7fd79137SRobert Mustacchi } 2158*7fd79137SRobert Mustacchi curabbrev = curabbrev->abb_next; 2159*7fd79137SRobert Mustacchi } 2160*7fd79137SRobert Mustacchi 2161*7fd79137SRobert Mustacchi /* no match, create new abbreviation */ 2162*7fd79137SRobert Mustacchi if (die->di_n_attr != 0) { 2163*7fd79137SRobert Mustacchi forms = (Dwarf_ufixed *) 2164*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(die->di_dbg, 2165*7fd79137SRobert Mustacchi sizeof(Dwarf_ufixed) * die->di_n_attr); 2166*7fd79137SRobert Mustacchi if (forms == NULL) 2167*7fd79137SRobert Mustacchi return NULL; 2168*7fd79137SRobert Mustacchi attrs = (Dwarf_ufixed *) 2169*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(die->di_dbg, 2170*7fd79137SRobert Mustacchi sizeof(Dwarf_ufixed) * die->di_n_attr); 2171*7fd79137SRobert Mustacchi if (attrs == NULL) 2172*7fd79137SRobert Mustacchi return NULL; 2173*7fd79137SRobert Mustacchi } 2174*7fd79137SRobert Mustacchi nattrs = 0; 2175*7fd79137SRobert Mustacchi curattr = die->di_attrs; 2176*7fd79137SRobert Mustacchi while (curattr) { 2177*7fd79137SRobert Mustacchi attrs[nattrs] = curattr->ar_attribute; 2178*7fd79137SRobert Mustacchi forms[nattrs] = curattr->ar_attribute_form; 2179*7fd79137SRobert Mustacchi nattrs++; 2180*7fd79137SRobert Mustacchi curattr = curattr->ar_next; 2181*7fd79137SRobert Mustacchi } 2182*7fd79137SRobert Mustacchi 2183*7fd79137SRobert Mustacchi curabbrev = (Dwarf_P_Abbrev) 2184*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(die->di_dbg, sizeof(struct Dwarf_P_Abbrev_s)); 2185*7fd79137SRobert Mustacchi if (curabbrev == NULL) 2186*7fd79137SRobert Mustacchi return NULL; 2187*7fd79137SRobert Mustacchi 2188*7fd79137SRobert Mustacchi if (die->di_child == NULL) 2189*7fd79137SRobert Mustacchi curabbrev->abb_children = DW_CHILDREN_no; 2190*7fd79137SRobert Mustacchi else 2191*7fd79137SRobert Mustacchi curabbrev->abb_children = DW_CHILDREN_yes; 2192*7fd79137SRobert Mustacchi curabbrev->abb_tag = die->di_tag; 2193*7fd79137SRobert Mustacchi curabbrev->abb_attrs = attrs; 2194*7fd79137SRobert Mustacchi curabbrev->abb_forms = forms; 2195*7fd79137SRobert Mustacchi curabbrev->abb_n_attr = die->di_n_attr; 2196*7fd79137SRobert Mustacchi curabbrev->abb_idx = 0; 2197*7fd79137SRobert Mustacchi curabbrev->abb_next = NULL; 2198*7fd79137SRobert Mustacchi 2199*7fd79137SRobert Mustacchi return curabbrev; 2200*7fd79137SRobert Mustacchi } 2201*7fd79137SRobert Mustacchi 2202*7fd79137SRobert Mustacchi /*------------------------------------------------------------------ 2203*7fd79137SRobert Mustacchi Tries to see if given attribute and form combination 2204*7fd79137SRobert Mustacchi exists in the given abbreviation 2205*7fd79137SRobert Mustacchi -------------------------------------------------------------------*/ 2206*7fd79137SRobert Mustacchi static int 2207*7fd79137SRobert Mustacchi _dwarf_pro_match_attr(Dwarf_P_Attribute attr, 2208*7fd79137SRobert Mustacchi Dwarf_P_Abbrev abbrev, int no_attr) 2209*7fd79137SRobert Mustacchi { 2210*7fd79137SRobert Mustacchi int i; 2211*7fd79137SRobert Mustacchi int found = 0; 2212*7fd79137SRobert Mustacchi 2213*7fd79137SRobert Mustacchi for (i = 0; i < no_attr; i++) { 2214*7fd79137SRobert Mustacchi if (attr->ar_attribute == abbrev->abb_attrs[i] && 2215*7fd79137SRobert Mustacchi attr->ar_attribute_form == abbrev->abb_forms[i]) { 2216*7fd79137SRobert Mustacchi found = 1; 2217*7fd79137SRobert Mustacchi break; 2218*7fd79137SRobert Mustacchi } 2219*7fd79137SRobert Mustacchi } 2220*7fd79137SRobert Mustacchi return found; 2221*7fd79137SRobert Mustacchi } 2222