1*7fd79137SRobert Mustacchi /* 2*7fd79137SRobert Mustacchi 3*7fd79137SRobert Mustacchi Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. 4*7fd79137SRobert Mustacchi Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. 5*7fd79137SRobert Mustacchi Portions Copyright 2008-2010 David Anderson, 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 39*7fd79137SRobert Mustacchi 40*7fd79137SRobert Mustacchi #include "config.h" 41*7fd79137SRobert Mustacchi #include "libdwarfdefs.h" 42*7fd79137SRobert Mustacchi #include <stdio.h> 43*7fd79137SRobert Mustacchi #include <string.h> 44*7fd79137SRobert Mustacchi #include "pro_incl.h" 45*7fd79137SRobert Mustacchi #include "pro_section.h" /* for MAGIC_SECT_NO */ 46*7fd79137SRobert Mustacchi #include "pro_reloc_symbolic.h" 47*7fd79137SRobert Mustacchi #include "pro_reloc_stream.h" 48*7fd79137SRobert Mustacchi 49*7fd79137SRobert Mustacchi 50*7fd79137SRobert Mustacchi static void common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags); 51*7fd79137SRobert Mustacchi 52*7fd79137SRobert Mustacchi void *_dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len); 53*7fd79137SRobert Mustacchi 54*7fd79137SRobert Mustacchi /*-------------------------------------------------------------------- 55*7fd79137SRobert Mustacchi This function sets up a new dwarf producing region. 56*7fd79137SRobert Mustacchi flags: Indicates type of access method, one of DW_DLC* macros 57*7fd79137SRobert Mustacchi func(): Used to create a new object file, a call back function 58*7fd79137SRobert Mustacchi errhand(): Error Handler provided by user 59*7fd79137SRobert Mustacchi errarg: Argument to errhand() 60*7fd79137SRobert Mustacchi error: returned error value 61*7fd79137SRobert Mustacchi --------------------------------------------------------------------*/ 62*7fd79137SRobert Mustacchi /* We want the following to have an elf section number that matches 63*7fd79137SRobert Mustacchi 'nothing' */ 64*7fd79137SRobert Mustacchi static struct Dwarf_P_Section_Data_s init_sect = { 65*7fd79137SRobert Mustacchi MAGIC_SECT_NO, 0, 0, 0, 0 66*7fd79137SRobert Mustacchi }; 67*7fd79137SRobert Mustacchi 68*7fd79137SRobert Mustacchi Dwarf_P_Debug 69*7fd79137SRobert Mustacchi dwarf_producer_init_b(Dwarf_Unsigned flags, 70*7fd79137SRobert Mustacchi Dwarf_Callback_Func_b func, 71*7fd79137SRobert Mustacchi Dwarf_Handler errhand, 72*7fd79137SRobert Mustacchi Dwarf_Ptr errarg, Dwarf_Error * error) 73*7fd79137SRobert Mustacchi { 74*7fd79137SRobert Mustacchi Dwarf_P_Debug dbg; 75*7fd79137SRobert Mustacchi dbg = (Dwarf_P_Debug) _dwarf_p_get_alloc(NULL, 76*7fd79137SRobert Mustacchi sizeof(struct 77*7fd79137SRobert Mustacchi Dwarf_P_Debug_s)); 78*7fd79137SRobert Mustacchi if (dbg == NULL) { 79*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, 80*7fd79137SRobert Mustacchi (Dwarf_P_Debug) DW_DLV_BADADDR); 81*7fd79137SRobert Mustacchi } 82*7fd79137SRobert Mustacchi memset((void *) dbg, 0, sizeof(struct Dwarf_P_Debug_s)); 83*7fd79137SRobert Mustacchi /* For the time being */ 84*7fd79137SRobert Mustacchi if (func == NULL) { 85*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_NO_CALLBACK_FUNC, 86*7fd79137SRobert Mustacchi (Dwarf_P_Debug) DW_DLV_BADADDR); 87*7fd79137SRobert Mustacchi } 88*7fd79137SRobert Mustacchi dbg->de_callback_func_b = func; 89*7fd79137SRobert Mustacchi dbg->de_errhand = errhand; 90*7fd79137SRobert Mustacchi dbg->de_errarg = errarg; 91*7fd79137SRobert Mustacchi common_init(dbg, flags); 92*7fd79137SRobert Mustacchi return dbg; 93*7fd79137SRobert Mustacchi 94*7fd79137SRobert Mustacchi } 95*7fd79137SRobert Mustacchi 96*7fd79137SRobert Mustacchi Dwarf_P_Debug 97*7fd79137SRobert Mustacchi dwarf_producer_init(Dwarf_Unsigned flags, 98*7fd79137SRobert Mustacchi Dwarf_Callback_Func func, 99*7fd79137SRobert Mustacchi Dwarf_Handler errhand, 100*7fd79137SRobert Mustacchi Dwarf_Ptr errarg, Dwarf_Error * error) 101*7fd79137SRobert Mustacchi { 102*7fd79137SRobert Mustacchi 103*7fd79137SRobert Mustacchi Dwarf_P_Debug dbg; 104*7fd79137SRobert Mustacchi 105*7fd79137SRobert Mustacchi 106*7fd79137SRobert Mustacchi 107*7fd79137SRobert Mustacchi dbg = (Dwarf_P_Debug) _dwarf_p_get_alloc(NULL, 108*7fd79137SRobert Mustacchi sizeof(struct 109*7fd79137SRobert Mustacchi Dwarf_P_Debug_s)); 110*7fd79137SRobert Mustacchi if (dbg == NULL) { 111*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, 112*7fd79137SRobert Mustacchi (Dwarf_P_Debug) DW_DLV_BADADDR); 113*7fd79137SRobert Mustacchi } 114*7fd79137SRobert Mustacchi memset((void *) dbg, 0, sizeof(struct Dwarf_P_Debug_s)); 115*7fd79137SRobert Mustacchi /* For the time being */ 116*7fd79137SRobert Mustacchi if (func == NULL) { 117*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_NO_CALLBACK_FUNC, 118*7fd79137SRobert Mustacchi (Dwarf_P_Debug) DW_DLV_BADADDR); 119*7fd79137SRobert Mustacchi } 120*7fd79137SRobert Mustacchi dbg->de_callback_func = func; 121*7fd79137SRobert Mustacchi dbg->de_errhand = errhand; 122*7fd79137SRobert Mustacchi dbg->de_errarg = errarg; 123*7fd79137SRobert Mustacchi common_init(dbg, flags); 124*7fd79137SRobert Mustacchi return dbg; 125*7fd79137SRobert Mustacchi } 126*7fd79137SRobert Mustacchi static void 127*7fd79137SRobert Mustacchi common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags) 128*7fd79137SRobert Mustacchi { 129*7fd79137SRobert Mustacchi unsigned int k; 130*7fd79137SRobert Mustacchi 131*7fd79137SRobert Mustacchi 132*7fd79137SRobert Mustacchi dbg->de_version_magic_number = PRO_VERSION_MAGIC; 133*7fd79137SRobert Mustacchi dbg->de_n_debug_sect = 0; 134*7fd79137SRobert Mustacchi dbg->de_debug_sects = &init_sect; 135*7fd79137SRobert Mustacchi dbg->de_current_active_section = &init_sect; 136*7fd79137SRobert Mustacchi dbg->de_flags = flags; 137*7fd79137SRobert Mustacchi 138*7fd79137SRobert Mustacchi /* Now, with flags set, can use 64bit tests */ 139*7fd79137SRobert Mustacchi 140*7fd79137SRobert Mustacchi 141*7fd79137SRobert Mustacchi 142*7fd79137SRobert Mustacchi #if defined(HAVE_STRICT_DWARF2_32BIT_OFFSET) 143*7fd79137SRobert Mustacchi /* This is cygnus 32bit offset, as specified in pure dwarf2 v2.0.0. 144*7fd79137SRobert Mustacchi It is consistent with normal DWARF2/3 generation of always 145*7fd79137SRobert Mustacchi generating 32 bit offsets. */ 146*7fd79137SRobert Mustacchi dbg->de_64bit_extension = 0; 147*7fd79137SRobert Mustacchi dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4); 148*7fd79137SRobert Mustacchi dbg->de_offset_size = (IS_64BIT(dbg) ? 4 : 4); 149*7fd79137SRobert Mustacchi dbg->de_ptr_reloc = 150*7fd79137SRobert Mustacchi IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg); 151*7fd79137SRobert Mustacchi /* non-MIPS, dwarf lengths and offsets are 32 bits even for 64bit 152*7fd79137SRobert Mustacchi pointer environments. */ 153*7fd79137SRobert Mustacchi /* Get_REL32_isa here supports 64-bit-pointer dwarf with pure 154*7fd79137SRobert Mustacchi dwarf2 v2.0.0 32bit offsets, as emitted by cygnus tools. And 155*7fd79137SRobert Mustacchi pure 32 bit offset dwarf for 32bit pointer apps. */ 156*7fd79137SRobert Mustacchi 157*7fd79137SRobert Mustacchi dbg->de_offset_reloc = Get_REL32_isa(dbg); 158*7fd79137SRobert Mustacchi #elif defined(HAVE_SGI_IRIX_OFFSETS) 159*7fd79137SRobert Mustacchi /* MIPS-SGI-IRIX 32 or 64, where offsets and lengths are both 64 bit for 160*7fd79137SRobert Mustacchi 64bit pointer objects and both 32 bit for 32bit pointer objects. 161*7fd79137SRobert Mustacchi And a dwarf-reader must check elf info to tell which applies. */ 162*7fd79137SRobert Mustacchi dbg->de_64bit_extension = 0; 163*7fd79137SRobert Mustacchi dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4); 164*7fd79137SRobert Mustacchi dbg->de_offset_size = (IS_64BIT(dbg) ? 8 : 4); 165*7fd79137SRobert Mustacchi dbg->de_ptr_reloc = 166*7fd79137SRobert Mustacchi IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg); 167*7fd79137SRobert Mustacchi dbg->de_offset_reloc = dbg->de_ptr_reloc; 168*7fd79137SRobert Mustacchi #else /* HAVE_DWARF2_99_EXTENSION or default. */ 169*7fd79137SRobert Mustacchi /* Revised 64 bit output, using distingushed values. Per 1999 170*7fd79137SRobert Mustacchi dwarf3. This allows run-time selection of offset size. */ 171*7fd79137SRobert Mustacchi dbg->de_64bit_extension = (IS_64BIT(dbg) ? 1 : 0); 172*7fd79137SRobert Mustacchi dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4); 173*7fd79137SRobert Mustacchi if( flags & DW_DLC_OFFSET_SIZE_64 && (dbg->de_pointer_size == 8)) { 174*7fd79137SRobert Mustacchi /* When it's 64 bit address, a 64bit offset is sensible. 175*7fd79137SRobert Mustacchi Arguably a 32 bit address with 64 bit offset could be 176*7fd79137SRobert Mustacchi sensible, but who would want that? */ 177*7fd79137SRobert Mustacchi dbg->de_offset_size = 8; 178*7fd79137SRobert Mustacchi dbg->de_64bit_extension = 1; 179*7fd79137SRobert Mustacchi } else { 180*7fd79137SRobert Mustacchi dbg->de_offset_size = 4; 181*7fd79137SRobert Mustacchi dbg->de_64bit_extension = 0; 182*7fd79137SRobert Mustacchi } 183*7fd79137SRobert Mustacchi dbg->de_ptr_reloc = 184*7fd79137SRobert Mustacchi IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg); 185*7fd79137SRobert Mustacchi /* Non-MIPS, dwarf lengths and offsets are 32 bits even for 64bit 186*7fd79137SRobert Mustacchi pointer environments. */ 187*7fd79137SRobert Mustacchi /* Get_REL??_isa here supports 64bit-offset dwarf. For 64bit, we 188*7fd79137SRobert Mustacchi emit the extension bytes. */ 189*7fd79137SRobert Mustacchi 190*7fd79137SRobert Mustacchi dbg->de_offset_reloc = IS_64BIT(dbg) ? Get_REL64_isa(dbg) 191*7fd79137SRobert Mustacchi : Get_REL32_isa(dbg); 192*7fd79137SRobert Mustacchi #endif /* HAVE_DWARF2_99_EXTENSION etc. */ 193*7fd79137SRobert Mustacchi 194*7fd79137SRobert Mustacchi dbg->de_exc_reloc = Get_REL_SEGREL_isa(dbg); 195*7fd79137SRobert Mustacchi 196*7fd79137SRobert Mustacchi dbg->de_is_64bit = IS_64BIT(dbg); 197*7fd79137SRobert Mustacchi 198*7fd79137SRobert Mustacchi 199*7fd79137SRobert Mustacchi if (flags & DW_DLC_SYMBOLIC_RELOCATIONS) { 200*7fd79137SRobert Mustacchi dbg->de_relocation_record_size = 201*7fd79137SRobert Mustacchi sizeof(struct Dwarf_Relocation_Data_s); 202*7fd79137SRobert Mustacchi } else { 203*7fd79137SRobert Mustacchi 204*7fd79137SRobert Mustacchi #if HAVE_ELF64_GETEHDR 205*7fd79137SRobert Mustacchi dbg->de_relocation_record_size = 206*7fd79137SRobert Mustacchi IS_64BIT(dbg)? sizeof(REL64) : sizeof(REL32); 207*7fd79137SRobert Mustacchi #else 208*7fd79137SRobert Mustacchi dbg->de_relocation_record_size = sizeof(REL32); 209*7fd79137SRobert Mustacchi #endif 210*7fd79137SRobert Mustacchi 211*7fd79137SRobert Mustacchi } 212*7fd79137SRobert Mustacchi 213*7fd79137SRobert Mustacchi if (dbg->de_offset_size == 8) { 214*7fd79137SRobert Mustacchi dbg->de_ar_data_attribute_form = DW_FORM_data8; 215*7fd79137SRobert Mustacchi dbg->de_ar_ref_attr_form = DW_FORM_ref8; 216*7fd79137SRobert Mustacchi } else { 217*7fd79137SRobert Mustacchi dbg->de_ar_data_attribute_form = DW_FORM_data4; 218*7fd79137SRobert Mustacchi dbg->de_ar_ref_attr_form = DW_FORM_ref4; 219*7fd79137SRobert Mustacchi } 220*7fd79137SRobert Mustacchi 221*7fd79137SRobert Mustacchi if (flags & DW_DLC_SYMBOLIC_RELOCATIONS) { 222*7fd79137SRobert Mustacchi dbg->de_reloc_name = _dwarf_pro_reloc_name_symbolic; 223*7fd79137SRobert Mustacchi dbg->de_reloc_pair = _dwarf_pro_reloc_length_symbolic; 224*7fd79137SRobert Mustacchi dbg->de_transform_relocs_to_disk = 225*7fd79137SRobert Mustacchi _dwarf_symbolic_relocs_to_disk; 226*7fd79137SRobert Mustacchi } else { 227*7fd79137SRobert Mustacchi if (IS_64BIT(dbg)) { 228*7fd79137SRobert Mustacchi dbg->de_reloc_name = _dwarf_pro_reloc_name_stream64; 229*7fd79137SRobert Mustacchi } else { 230*7fd79137SRobert Mustacchi dbg->de_reloc_name = _dwarf_pro_reloc_name_stream32; 231*7fd79137SRobert Mustacchi } 232*7fd79137SRobert Mustacchi dbg->de_reloc_pair = 0; 233*7fd79137SRobert Mustacchi dbg->de_transform_relocs_to_disk = _dwarf_stream_relocs_to_disk; 234*7fd79137SRobert Mustacchi } 235*7fd79137SRobert Mustacchi for (k = 0; k < NUM_DEBUG_SECTIONS; ++k) { 236*7fd79137SRobert Mustacchi 237*7fd79137SRobert Mustacchi Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[k]; 238*7fd79137SRobert Mustacchi 239*7fd79137SRobert Mustacchi prel->pr_slots_per_block_to_alloc = DEFAULT_SLOTS_PER_BLOCK; 240*7fd79137SRobert Mustacchi } 241*7fd79137SRobert Mustacchi /* First assume host, target same endianness */ 242*7fd79137SRobert Mustacchi dbg->de_same_endian = 1; 243*7fd79137SRobert Mustacchi dbg->de_copy_word = memcpy; 244*7fd79137SRobert Mustacchi #ifdef WORDS_BIGENDIAN 245*7fd79137SRobert Mustacchi /* host is big endian, so what endian is target? */ 246*7fd79137SRobert Mustacchi if (flags & DW_DLC_TARGET_LITTLEENDIAN) { 247*7fd79137SRobert Mustacchi dbg->de_same_endian = 0; 248*7fd79137SRobert Mustacchi dbg->de_copy_word = _dwarf_memcpy_swap_bytes; 249*7fd79137SRobert Mustacchi } 250*7fd79137SRobert Mustacchi #else /* little endian */ 251*7fd79137SRobert Mustacchi /* host is little endian, so what endian is target? */ 252*7fd79137SRobert Mustacchi if (flags & DW_DLC_TARGET_BIGENDIAN) { 253*7fd79137SRobert Mustacchi dbg->de_same_endian = 0; 254*7fd79137SRobert Mustacchi dbg->de_copy_word = _dwarf_memcpy_swap_bytes; 255*7fd79137SRobert Mustacchi } 256*7fd79137SRobert Mustacchi #endif /* !WORDS_BIGENDIAN */ 257*7fd79137SRobert Mustacchi 258*7fd79137SRobert Mustacchi 259*7fd79137SRobert Mustacchi return; 260*7fd79137SRobert Mustacchi 261*7fd79137SRobert Mustacchi } 262