1*7fd79137SRobert Mustacchi /* 2*7fd79137SRobert Mustacchi 3*7fd79137SRobert Mustacchi Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. 4*7fd79137SRobert Mustacchi 5*7fd79137SRobert Mustacchi This program is free software; you can redistribute it and/or modify it 6*7fd79137SRobert Mustacchi under the terms of version 2.1 of the GNU Lesser General Public License 7*7fd79137SRobert Mustacchi as published by the Free Software Foundation. 8*7fd79137SRobert Mustacchi 9*7fd79137SRobert Mustacchi This program is distributed in the hope that it would be useful, but 10*7fd79137SRobert Mustacchi WITHOUT ANY WARRANTY; without even the implied warranty of 11*7fd79137SRobert Mustacchi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12*7fd79137SRobert Mustacchi 13*7fd79137SRobert Mustacchi Further, this software is distributed without any warranty that it is 14*7fd79137SRobert Mustacchi free of the rightful claim of any third person regarding infringement 15*7fd79137SRobert Mustacchi or the like. Any license provided herein, whether implied or 16*7fd79137SRobert Mustacchi otherwise, applies only to this software file. Patent licenses, if 17*7fd79137SRobert Mustacchi any, provided herein do not apply to combinations of this program with 18*7fd79137SRobert Mustacchi other software, or any other product whatsoever. 19*7fd79137SRobert Mustacchi 20*7fd79137SRobert Mustacchi You should have received a copy of the GNU Lesser General Public 21*7fd79137SRobert Mustacchi License along with this program; if not, write the Free Software 22*7fd79137SRobert Mustacchi Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, 23*7fd79137SRobert Mustacchi USA. 24*7fd79137SRobert Mustacchi 25*7fd79137SRobert Mustacchi Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, 26*7fd79137SRobert Mustacchi Mountain View, CA 94043, or: 27*7fd79137SRobert Mustacchi 28*7fd79137SRobert Mustacchi http://www.sgi.com 29*7fd79137SRobert Mustacchi 30*7fd79137SRobert Mustacchi For further information regarding this notice, see: 31*7fd79137SRobert Mustacchi 32*7fd79137SRobert Mustacchi http://oss.sgi.com/projects/GenInfo/NoticeExplan 33*7fd79137SRobert Mustacchi 34*7fd79137SRobert Mustacchi */ 35*7fd79137SRobert Mustacchi 36*7fd79137SRobert Mustacchi 37*7fd79137SRobert Mustacchi 38*7fd79137SRobert Mustacchi #include "config.h" 39*7fd79137SRobert Mustacchi #include "libdwarfdefs.h" 40*7fd79137SRobert Mustacchi #include <stdio.h> 41*7fd79137SRobert Mustacchi #include <string.h> 42*7fd79137SRobert Mustacchi #ifdef HAVE_ELFACCESS_H 43*7fd79137SRobert Mustacchi #include <elfaccess.h> 44*7fd79137SRobert Mustacchi #endif 45*7fd79137SRobert Mustacchi #include "pro_incl.h" 46*7fd79137SRobert Mustacchi #include "pro_arange.h" 47*7fd79137SRobert Mustacchi #include "pro_section.h" 48*7fd79137SRobert Mustacchi #include "pro_reloc.h" 49*7fd79137SRobert Mustacchi 50*7fd79137SRobert Mustacchi 51*7fd79137SRobert Mustacchi 52*7fd79137SRobert Mustacchi /* 53*7fd79137SRobert Mustacchi This function adds another address range 54*7fd79137SRobert Mustacchi to the list of address ranges for the 55*7fd79137SRobert Mustacchi given Dwarf_P_Debug. It returns 0 on error, 56*7fd79137SRobert Mustacchi and 1 otherwise. 57*7fd79137SRobert Mustacchi */ 58*7fd79137SRobert Mustacchi Dwarf_Unsigned 59*7fd79137SRobert Mustacchi dwarf_add_arange(Dwarf_P_Debug dbg, 60*7fd79137SRobert Mustacchi Dwarf_Addr begin_address, 61*7fd79137SRobert Mustacchi Dwarf_Unsigned length, 62*7fd79137SRobert Mustacchi Dwarf_Signed symbol_index, Dwarf_Error * error) 63*7fd79137SRobert Mustacchi { 64*7fd79137SRobert Mustacchi return dwarf_add_arange_b(dbg, begin_address, length, symbol_index, 65*7fd79137SRobert Mustacchi /* end_symbol_index */ 0, 66*7fd79137SRobert Mustacchi /* offset_from_end_sym */ 0, 67*7fd79137SRobert Mustacchi error); 68*7fd79137SRobert Mustacchi } 69*7fd79137SRobert Mustacchi 70*7fd79137SRobert Mustacchi /* 71*7fd79137SRobert Mustacchi This function adds another address range 72*7fd79137SRobert Mustacchi to the list of address ranges for the 73*7fd79137SRobert Mustacchi given Dwarf_P_Debug. It returns 0 on error, 74*7fd79137SRobert Mustacchi and 1 otherwise. 75*7fd79137SRobert Mustacchi */ 76*7fd79137SRobert Mustacchi Dwarf_Unsigned 77*7fd79137SRobert Mustacchi dwarf_add_arange_b(Dwarf_P_Debug dbg, 78*7fd79137SRobert Mustacchi Dwarf_Addr begin_address, 79*7fd79137SRobert Mustacchi Dwarf_Unsigned length, 80*7fd79137SRobert Mustacchi Dwarf_Unsigned symbol_index, 81*7fd79137SRobert Mustacchi Dwarf_Unsigned end_symbol_index, 82*7fd79137SRobert Mustacchi Dwarf_Addr offset_from_end_sym, Dwarf_Error * error) 83*7fd79137SRobert Mustacchi { 84*7fd79137SRobert Mustacchi Dwarf_P_Arange arange; 85*7fd79137SRobert Mustacchi 86*7fd79137SRobert Mustacchi if (dbg == NULL) { 87*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 88*7fd79137SRobert Mustacchi return (0); 89*7fd79137SRobert Mustacchi } 90*7fd79137SRobert Mustacchi 91*7fd79137SRobert Mustacchi arange = (Dwarf_P_Arange) 92*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Arange_s)); 93*7fd79137SRobert Mustacchi if (arange == NULL) { 94*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 95*7fd79137SRobert Mustacchi return (0); 96*7fd79137SRobert Mustacchi } 97*7fd79137SRobert Mustacchi 98*7fd79137SRobert Mustacchi arange->ag_begin_address = begin_address; 99*7fd79137SRobert Mustacchi arange->ag_length = length; 100*7fd79137SRobert Mustacchi arange->ag_symbol_index = symbol_index; 101*7fd79137SRobert Mustacchi arange->ag_end_symbol_index = end_symbol_index; 102*7fd79137SRobert Mustacchi arange->ag_end_symbol_offset = offset_from_end_sym; 103*7fd79137SRobert Mustacchi 104*7fd79137SRobert Mustacchi if (dbg->de_arange == NULL) 105*7fd79137SRobert Mustacchi dbg->de_arange = dbg->de_last_arange = arange; 106*7fd79137SRobert Mustacchi else { 107*7fd79137SRobert Mustacchi dbg->de_last_arange->ag_next = arange; 108*7fd79137SRobert Mustacchi dbg->de_last_arange = arange; 109*7fd79137SRobert Mustacchi } 110*7fd79137SRobert Mustacchi dbg->de_arange_count++; 111*7fd79137SRobert Mustacchi 112*7fd79137SRobert Mustacchi return (1); 113*7fd79137SRobert Mustacchi } 114*7fd79137SRobert Mustacchi 115*7fd79137SRobert Mustacchi 116*7fd79137SRobert Mustacchi int 117*7fd79137SRobert Mustacchi _dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, Dwarf_Error * error) 118*7fd79137SRobert Mustacchi { 119*7fd79137SRobert Mustacchi /* Total num of bytes in .debug_aranges section. */ 120*7fd79137SRobert Mustacchi Dwarf_Unsigned arange_num_bytes; 121*7fd79137SRobert Mustacchi 122*7fd79137SRobert Mustacchi /* 123*7fd79137SRobert Mustacchi Adjustment to align the start of the actual address ranges on a 124*7fd79137SRobert Mustacchi boundary aligned with twice the address size. */ 125*7fd79137SRobert Mustacchi Dwarf_Small remainder; 126*7fd79137SRobert Mustacchi 127*7fd79137SRobert Mustacchi /* Total number of bytes excluding the length field. */ 128*7fd79137SRobert Mustacchi Dwarf_Unsigned adjusted_length; 129*7fd79137SRobert Mustacchi 130*7fd79137SRobert Mustacchi /* Points to first byte of .debug_aranges buffer. */ 131*7fd79137SRobert Mustacchi Dwarf_Small *arange; 132*7fd79137SRobert Mustacchi 133*7fd79137SRobert Mustacchi /* Fills in the .debug_aranges buffer. */ 134*7fd79137SRobert Mustacchi Dwarf_Small *arange_ptr; 135*7fd79137SRobert Mustacchi 136*7fd79137SRobert Mustacchi /* Scans the list of address ranges provided by user. */ 137*7fd79137SRobert Mustacchi Dwarf_P_Arange given_arange; 138*7fd79137SRobert Mustacchi 139*7fd79137SRobert Mustacchi /* Used to fill in 0. */ 140*7fd79137SRobert Mustacchi const Dwarf_Signed big_zero = 0; 141*7fd79137SRobert Mustacchi 142*7fd79137SRobert Mustacchi int extension_word_size = dbg->de_64bit_extension ? 4 : 0; 143*7fd79137SRobert Mustacchi int uword_size = dbg->de_offset_size; 144*7fd79137SRobert Mustacchi int upointer_size = dbg->de_pointer_size; 145*7fd79137SRobert Mustacchi int res; 146*7fd79137SRobert Mustacchi 147*7fd79137SRobert Mustacchi 148*7fd79137SRobert Mustacchi /* ***** BEGIN CODE ***** */ 149*7fd79137SRobert Mustacchi 150*7fd79137SRobert Mustacchi /* Size of the .debug_aranges section header. */ 151*7fd79137SRobert Mustacchi arange_num_bytes = extension_word_size + uword_size + /* Size 152*7fd79137SRobert Mustacchi of 153*7fd79137SRobert Mustacchi length 154*7fd79137SRobert Mustacchi field. 155*7fd79137SRobert Mustacchi */ 156*7fd79137SRobert Mustacchi sizeof(Dwarf_Half) + /* Size of version field. */ 157*7fd79137SRobert Mustacchi uword_size + /* Size of .debug_info offset. */ 158*7fd79137SRobert Mustacchi sizeof(Dwarf_Small) + /* Size of address size field. */ 159*7fd79137SRobert Mustacchi sizeof(Dwarf_Small); /* Size of segment size field. */ 160*7fd79137SRobert Mustacchi 161*7fd79137SRobert Mustacchi /* 162*7fd79137SRobert Mustacchi Adjust the size so that the set of aranges begins on a boundary 163*7fd79137SRobert Mustacchi that aligned with twice the address size. This is a Libdwarf 164*7fd79137SRobert Mustacchi requirement. */ 165*7fd79137SRobert Mustacchi remainder = arange_num_bytes % (2 * upointer_size); 166*7fd79137SRobert Mustacchi if (remainder != 0) 167*7fd79137SRobert Mustacchi arange_num_bytes += (2 * upointer_size) - remainder; 168*7fd79137SRobert Mustacchi 169*7fd79137SRobert Mustacchi 170*7fd79137SRobert Mustacchi /* Add the bytes for the actual address ranges. */ 171*7fd79137SRobert Mustacchi arange_num_bytes += upointer_size * 2 * (dbg->de_arange_count + 1); 172*7fd79137SRobert Mustacchi 173*7fd79137SRobert Mustacchi GET_CHUNK(dbg, dbg->de_elf_sects[DEBUG_ARANGES], 174*7fd79137SRobert Mustacchi arange, (unsigned long) arange_num_bytes, error); 175*7fd79137SRobert Mustacchi arange_ptr = arange; 176*7fd79137SRobert Mustacchi if (arange == NULL) { 177*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 178*7fd79137SRobert Mustacchi return (0); 179*7fd79137SRobert Mustacchi } 180*7fd79137SRobert Mustacchi if (extension_word_size) { 181*7fd79137SRobert Mustacchi Dwarf_Word x = DISTINGUISHED_VALUE; 182*7fd79137SRobert Mustacchi 183*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) arange_ptr, 184*7fd79137SRobert Mustacchi (const void *) &x, 185*7fd79137SRobert Mustacchi sizeof(x), extension_word_size); 186*7fd79137SRobert Mustacchi arange_ptr += extension_word_size; 187*7fd79137SRobert Mustacchi } 188*7fd79137SRobert Mustacchi 189*7fd79137SRobert Mustacchi /* Write the total length of .debug_aranges section. */ 190*7fd79137SRobert Mustacchi adjusted_length = arange_num_bytes - uword_size 191*7fd79137SRobert Mustacchi - extension_word_size; 192*7fd79137SRobert Mustacchi { 193*7fd79137SRobert Mustacchi Dwarf_Unsigned du = adjusted_length; 194*7fd79137SRobert Mustacchi 195*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) arange_ptr, 196*7fd79137SRobert Mustacchi (const void *) &du, sizeof(du), uword_size); 197*7fd79137SRobert Mustacchi arange_ptr += uword_size; 198*7fd79137SRobert Mustacchi } 199*7fd79137SRobert Mustacchi 200*7fd79137SRobert Mustacchi /* Write the version as 2 bytes. */ 201*7fd79137SRobert Mustacchi { 202*7fd79137SRobert Mustacchi Dwarf_Half verstamp = CURRENT_VERSION_STAMP; 203*7fd79137SRobert Mustacchi 204*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) arange_ptr, 205*7fd79137SRobert Mustacchi (const void *) &verstamp, 206*7fd79137SRobert Mustacchi sizeof(verstamp), sizeof(Dwarf_Half)); 207*7fd79137SRobert Mustacchi arange_ptr += sizeof(Dwarf_Half); 208*7fd79137SRobert Mustacchi } 209*7fd79137SRobert Mustacchi 210*7fd79137SRobert Mustacchi 211*7fd79137SRobert Mustacchi /* Write the .debug_info offset. This is always 0. */ 212*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) arange_ptr, 213*7fd79137SRobert Mustacchi (const void *) &big_zero, 214*7fd79137SRobert Mustacchi sizeof(big_zero), uword_size); 215*7fd79137SRobert Mustacchi arange_ptr += uword_size; 216*7fd79137SRobert Mustacchi 217*7fd79137SRobert Mustacchi { 218*7fd79137SRobert Mustacchi unsigned long count = dbg->de_arange_count + 1; 219*7fd79137SRobert Mustacchi int res; 220*7fd79137SRobert Mustacchi 221*7fd79137SRobert Mustacchi if (dbg->de_reloc_pair) { 222*7fd79137SRobert Mustacchi count = (3 * dbg->de_arange_count) + 1; 223*7fd79137SRobert Mustacchi } 224*7fd79137SRobert Mustacchi /* the following is a small optimization: not needed for 225*7fd79137SRobert Mustacchi correctness */ 226*7fd79137SRobert Mustacchi res = _dwarf_pro_pre_alloc_n_reloc_slots(dbg, 227*7fd79137SRobert Mustacchi DEBUG_ARANGES, count); 228*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 229*7fd79137SRobert Mustacchi { 230*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 231*7fd79137SRobert Mustacchi return (0); 232*7fd79137SRobert Mustacchi } 233*7fd79137SRobert Mustacchi } 234*7fd79137SRobert Mustacchi } 235*7fd79137SRobert Mustacchi 236*7fd79137SRobert Mustacchi /* reloc for .debug_info */ 237*7fd79137SRobert Mustacchi res = dbg->de_reloc_name(dbg, 238*7fd79137SRobert Mustacchi DEBUG_ARANGES, 239*7fd79137SRobert Mustacchi extension_word_size + 240*7fd79137SRobert Mustacchi uword_size + sizeof(Dwarf_Half), 241*7fd79137SRobert Mustacchi dbg->de_sect_name_idx[DEBUG_INFO], 242*7fd79137SRobert Mustacchi dwarf_drt_data_reloc, uword_size); 243*7fd79137SRobert Mustacchi 244*7fd79137SRobert Mustacchi /* Write the size of addresses. */ 245*7fd79137SRobert Mustacchi *arange_ptr = dbg->de_pointer_size; 246*7fd79137SRobert Mustacchi arange_ptr++; 247*7fd79137SRobert Mustacchi 248*7fd79137SRobert Mustacchi /* 249*7fd79137SRobert Mustacchi Write the size of segment addresses. This is zero for MIPS 250*7fd79137SRobert Mustacchi architectures. */ 251*7fd79137SRobert Mustacchi *arange_ptr = 0; 252*7fd79137SRobert Mustacchi arange_ptr++; 253*7fd79137SRobert Mustacchi 254*7fd79137SRobert Mustacchi /* 255*7fd79137SRobert Mustacchi Skip over the padding to align the start of the actual address 256*7fd79137SRobert Mustacchi ranges to twice the address size. */ 257*7fd79137SRobert Mustacchi if (remainder != 0) 258*7fd79137SRobert Mustacchi arange_ptr += (2 * upointer_size) - remainder; 259*7fd79137SRobert Mustacchi 260*7fd79137SRobert Mustacchi 261*7fd79137SRobert Mustacchi 262*7fd79137SRobert Mustacchi 263*7fd79137SRobert Mustacchi 264*7fd79137SRobert Mustacchi /* The arange address, length are pointer-size fields of the target 265*7fd79137SRobert Mustacchi machine. */ 266*7fd79137SRobert Mustacchi for (given_arange = dbg->de_arange; given_arange != NULL; 267*7fd79137SRobert Mustacchi given_arange = given_arange->ag_next) { 268*7fd79137SRobert Mustacchi 269*7fd79137SRobert Mustacchi /* Write relocation record for beginning of address range. */ 270*7fd79137SRobert Mustacchi res = dbg->de_reloc_name(dbg, DEBUG_ARANGES, arange_ptr - arange, /* r_offset 271*7fd79137SRobert Mustacchi */ 272*7fd79137SRobert Mustacchi (long) given_arange->ag_symbol_index, 273*7fd79137SRobert Mustacchi dwarf_drt_data_reloc, upointer_size); 274*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 275*7fd79137SRobert Mustacchi { 276*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 277*7fd79137SRobert Mustacchi return (0); 278*7fd79137SRobert Mustacchi } 279*7fd79137SRobert Mustacchi } 280*7fd79137SRobert Mustacchi 281*7fd79137SRobert Mustacchi /* Copy beginning address of range. */ 282*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) arange_ptr, 283*7fd79137SRobert Mustacchi (const void *) &given_arange->ag_begin_address, 284*7fd79137SRobert Mustacchi sizeof(given_arange->ag_begin_address), 285*7fd79137SRobert Mustacchi upointer_size); 286*7fd79137SRobert Mustacchi arange_ptr += upointer_size; 287*7fd79137SRobert Mustacchi 288*7fd79137SRobert Mustacchi if (dbg->de_reloc_pair && 289*7fd79137SRobert Mustacchi given_arange->ag_end_symbol_index != 0 && 290*7fd79137SRobert Mustacchi given_arange->ag_length == 0) { 291*7fd79137SRobert Mustacchi /* symbolic reloc, need reloc for length What if we really 292*7fd79137SRobert Mustacchi know the length? If so, should use the other part of 293*7fd79137SRobert Mustacchi 'if'. */ 294*7fd79137SRobert Mustacchi Dwarf_Unsigned val; 295*7fd79137SRobert Mustacchi 296*7fd79137SRobert Mustacchi res = dbg->de_reloc_pair(dbg, DEBUG_ARANGES, arange_ptr - arange, /* r_offset 297*7fd79137SRobert Mustacchi */ 298*7fd79137SRobert Mustacchi given_arange->ag_symbol_index, 299*7fd79137SRobert Mustacchi given_arange->ag_end_symbol_index, 300*7fd79137SRobert Mustacchi dwarf_drt_first_of_length_pair, 301*7fd79137SRobert Mustacchi upointer_size); 302*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 303*7fd79137SRobert Mustacchi { 304*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 305*7fd79137SRobert Mustacchi return (0); 306*7fd79137SRobert Mustacchi } 307*7fd79137SRobert Mustacchi } 308*7fd79137SRobert Mustacchi 309*7fd79137SRobert Mustacchi /* arrange pre-calc so assem text can do .word end - begin 310*7fd79137SRobert Mustacchi + val (gets val from stream) */ 311*7fd79137SRobert Mustacchi val = given_arange->ag_end_symbol_offset - 312*7fd79137SRobert Mustacchi given_arange->ag_begin_address; 313*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) arange_ptr, 314*7fd79137SRobert Mustacchi (const void *) &val, 315*7fd79137SRobert Mustacchi sizeof(val), upointer_size); 316*7fd79137SRobert Mustacchi arange_ptr += upointer_size; 317*7fd79137SRobert Mustacchi 318*7fd79137SRobert Mustacchi } else { 319*7fd79137SRobert Mustacchi /* plain old length to copy, no relocation at all */ 320*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) arange_ptr, 321*7fd79137SRobert Mustacchi (const void *) &given_arange->ag_length, 322*7fd79137SRobert Mustacchi sizeof(given_arange->ag_length), 323*7fd79137SRobert Mustacchi upointer_size); 324*7fd79137SRobert Mustacchi arange_ptr += upointer_size; 325*7fd79137SRobert Mustacchi } 326*7fd79137SRobert Mustacchi } 327*7fd79137SRobert Mustacchi 328*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) arange_ptr, 329*7fd79137SRobert Mustacchi (const void *) &big_zero, 330*7fd79137SRobert Mustacchi sizeof(big_zero), upointer_size); 331*7fd79137SRobert Mustacchi 332*7fd79137SRobert Mustacchi arange_ptr += upointer_size; 333*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, (void *) arange_ptr, 334*7fd79137SRobert Mustacchi (const void *) &big_zero, 335*7fd79137SRobert Mustacchi sizeof(big_zero), upointer_size); 336*7fd79137SRobert Mustacchi return (int) dbg->de_n_debug_sect; 337*7fd79137SRobert Mustacchi } 338