1 /* 2 3 Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. 4 5 This program is free software; you can redistribute it and/or modify it 6 under the terms of version 2.1 of the GNU Lesser General Public License 7 as published by the Free Software Foundation. 8 9 This program is distributed in the hope that it would be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 13 Further, this software is distributed without any warranty that it is 14 free of the rightful claim of any third person regarding infringement 15 or the like. Any license provided herein, whether implied or 16 otherwise, applies only to this software file. Patent licenses, if 17 any, provided herein do not apply to combinations of this program with 18 other software, or any other product whatsoever. 19 20 You should have received a copy of the GNU Lesser General Public 21 License along with this program; if not, write the Free Software 22 Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 23 USA. 24 25 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 26 Mountain View, CA 94043, or: 27 28 http://www.sgi.com 29 30 For further information regarding this notice, see: 31 32 http://oss.sgi.com/projects/GenInfo/NoticeExplan 33 34 */ 35 36 37 38 #include "config.h" 39 #include "libdwarfdefs.h" 40 #include <stdio.h> 41 #include <string.h> 42 #include "pro_incl.h" 43 #include "pro_section.h" /* for MAGIC_SECT_NO */ 44 #include "pro_reloc_symbolic.h" 45 #include "pro_reloc_stream.h" 46 47 48 static void common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags); 49 50 void *_dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len); 51 52 /*-------------------------------------------------------------------- 53 This function sets up a new dwarf producing region. 54 flags: Indicates type of access method, one of DW_DLC* macros 55 func(): Used to create a new object file, a call back function 56 errhand(): Error Handler provided by user 57 errarg: Argument to errhand() 58 error: returned error value 59 --------------------------------------------------------------------*/ 60 /* We want the following to have an elf section number that matches 61 'nothing' */ 62 static struct Dwarf_P_Section_Data_s init_sect = { 63 MAGIC_SECT_NO, 0, 0, 0, 0 64 }; 65 66 Dwarf_P_Debug 67 dwarf_producer_init_b(Dwarf_Unsigned flags, 68 Dwarf_Callback_Func_b func, 69 Dwarf_Handler errhand, 70 Dwarf_Ptr errarg, Dwarf_Error * error) 71 { 72 Dwarf_P_Debug dbg; 73 dbg = (Dwarf_P_Debug) _dwarf_p_get_alloc(NULL, 74 sizeof(struct 75 Dwarf_P_Debug_s)); 76 if (dbg == NULL) { 77 DWARF_P_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, 78 (Dwarf_P_Debug) DW_DLV_BADADDR); 79 } 80 memset((void *) dbg,0, sizeof(struct Dwarf_P_Debug_s)); 81 /* For the time being */ 82 if (func == NULL) { 83 DWARF_P_DBG_ERROR(dbg, DW_DLE_NO_CALLBACK_FUNC, 84 (Dwarf_P_Debug) DW_DLV_BADADDR); 85 } 86 dbg->de_func_b = func; 87 dbg->de_errhand = errhand; 88 dbg->de_errarg = errarg; 89 common_init(dbg, flags); 90 return dbg; 91 92 } 93 94 Dwarf_P_Debug 95 dwarf_producer_init(Dwarf_Unsigned flags, 96 Dwarf_Callback_Func func, 97 Dwarf_Handler errhand, 98 Dwarf_Ptr errarg, Dwarf_Error * error) 99 { 100 101 Dwarf_P_Debug dbg; 102 103 104 105 dbg = (Dwarf_P_Debug) _dwarf_p_get_alloc(NULL, 106 sizeof(struct 107 Dwarf_P_Debug_s)); 108 if (dbg == NULL) { 109 DWARF_P_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, 110 (Dwarf_P_Debug) DW_DLV_BADADDR); 111 } 112 memset((void *) dbg,0, sizeof(struct Dwarf_P_Debug_s)); 113 /* For the time being */ 114 if (func == NULL) { 115 DWARF_P_DBG_ERROR(dbg, DW_DLE_NO_CALLBACK_FUNC, 116 (Dwarf_P_Debug) DW_DLV_BADADDR); 117 } 118 dbg->de_func = func; 119 dbg->de_errhand = errhand; 120 dbg->de_errarg = errarg; 121 common_init(dbg, flags); 122 return dbg; 123 } 124 static void 125 common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags) 126 { 127 unsigned int k; 128 129 130 dbg->de_version_magic_number = PRO_VERSION_MAGIC; 131 dbg->de_n_debug_sect = 0; 132 dbg->de_debug_sects = &init_sect; 133 dbg->de_current_active_section = &init_sect; 134 dbg->de_flags = flags; 135 136 /* Now, with flags set, can use 64bit tests */ 137 138 139 140 #if defined(HAVE_DWARF2_99_EXTENSION) 141 /* Revised 64 bit output, using distingushed values. Per 1999 142 dwarf2 revision This produces 64bit extension with ia64 objects. 143 144 Some might want library run time selection of offset size. Not 145 provided here at present. */ 146 dbg->de_64bit_extension = (IS_64BIT(dbg) ? 1 : 0); 147 dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4); 148 dbg->de_offset_size = (IS_64BIT(dbg) ? 8 : 4); 149 dbg->de_ptr_reloc = 150 IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg); 151 /* Non-MIPS, dwarf lengths and offsets are 32 bits even for 64bit 152 pointer environments. */ 153 /* Get_REL??_isa here supports 64bit-offset dwarf. For 64bit, we 154 emit the extension bytes. */ 155 156 dbg->de_offset_reloc = IS_64BIT(dbg) ? Get_REL64_isa(dbg) 157 : Get_REL32_isa(dbg); 158 #elif defined(HAVE_OLD_DWARF2_32BIT_OFFSET) 159 /* This is cygnus 32bit offset, as specified in pure dwarf2 v2.0.0 */ 160 dbg->de_64bit_extension = 0; 161 dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4); 162 dbg->de_offset_size = (IS_64BIT(dbg) ? 4 : 4); 163 dbg->de_ptr_reloc = 164 IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg); 165 /* non-MIPS, dwarf lengths and offsets are 32 bits even for 64bit 166 pointer environments. */ 167 /* Get_REL32_isa here supports 64-bit-pointer dwarf with pure 168 dwarf2 v2.0.0 32bit offsets, as emitted by cygnus tools. And 169 pure 32 bit offset dwarf for 32bit pointer apps. */ 170 171 dbg->de_offset_reloc = Get_REL32_isa(dbg); 172 #else 173 /* MIPS-SGI 32 or 64, where offsets and lengths are both 64 bit for 174 64bit pointer objects and both 32 bit for 32bit pointer 175 objects. And a dwarf-reader must check elf info to tell which 176 applies. */ 177 dbg->de_64bit_extension = 0; 178 dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4); 179 dbg->de_offset_size = (IS_64BIT(dbg) ? 8 : 4); 180 dbg->de_ptr_reloc = 181 IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg); 182 dbg->de_offset_reloc = dbg->de_ptr_reloc; 183 #endif 184 dbg->de_exc_reloc = Get_REL_SEGREL_isa(dbg); 185 186 dbg->de_is_64bit = IS_64BIT(dbg); 187 188 189 if (flags & DW_DLC_SYMBOLIC_RELOCATIONS) { 190 dbg->de_relocation_record_size = 191 sizeof(struct Dwarf_Relocation_Data_s); 192 } else { 193 #if HAVE_ELF64_GETEHDR 194 dbg->de_relocation_record_size = 195 IS_64BIT(dbg) ? sizeof(Elf64_Rel) : sizeof(Elf32_Rel); 196 #else 197 dbg->de_relocation_record_size = sizeof(Elf32_Rel); 198 #endif 199 } 200 201 if (dbg->de_offset_size == 8) { 202 dbg->de_ar_data_attribute_form = DW_FORM_data8; 203 dbg->de_ar_ref_attr_form = DW_FORM_ref8; 204 } else { 205 dbg->de_ar_data_attribute_form = DW_FORM_data4; 206 dbg->de_ar_ref_attr_form = DW_FORM_ref4; 207 } 208 209 if (flags & DW_DLC_SYMBOLIC_RELOCATIONS) { 210 dbg->de_reloc_name = _dwarf_pro_reloc_name_symbolic; 211 dbg->de_reloc_pair = _dwarf_pro_reloc_length_symbolic; 212 dbg->de_transform_relocs_to_disk = 213 _dwarf_symbolic_relocs_to_disk; 214 } else { 215 if (IS_64BIT(dbg)) { 216 dbg->de_reloc_name = _dwarf_pro_reloc_name_stream64; 217 } else { 218 dbg->de_reloc_name = _dwarf_pro_reloc_name_stream32; 219 } 220 dbg->de_reloc_pair = 0; 221 dbg->de_transform_relocs_to_disk = _dwarf_stream_relocs_to_disk; 222 } 223 for (k = 0; k < NUM_DEBUG_SECTIONS; ++k) { 224 225 Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[k]; 226 227 prel->pr_slots_per_block_to_alloc = DEFAULT_SLOTS_PER_BLOCK; 228 } 229 /* First assume host, target same endianness */ 230 dbg->de_same_endian = 1; 231 dbg->de_copy_word = memcpy; 232 #ifdef WORDS_BIGENDIAN 233 /* host is big endian, so what endian is target? */ 234 if (flags & DW_DLC_TARGET_LITTLEENDIAN) { 235 dbg->de_same_endian = 0; 236 dbg->de_copy_word = _dwarf_memcpy_swap_bytes; 237 } 238 #else /* little endian */ 239 /* host is little endian, so what endian is target? */ 240 if (flags & DW_DLC_TARGET_BIGENDIAN) { 241 dbg->de_same_endian = 0; 242 dbg->de_copy_word = _dwarf_memcpy_swap_bytes; 243 } 244 #endif /* !WORDS_BIGENDIAN */ 245 246 247 return; 248 249 } 250