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 /*#include <elfaccess.h> */ 43*7fd79137SRobert Mustacchi #include "pro_incl.h" 44*7fd79137SRobert Mustacchi #include "pro_section.h" 45*7fd79137SRobert Mustacchi #include "pro_reloc.h" 46*7fd79137SRobert Mustacchi #include "pro_reloc_symbolic.h" 47*7fd79137SRobert Mustacchi 48*7fd79137SRobert Mustacchi /* 49*7fd79137SRobert Mustacchi Return DW_DLV_ERROR on malloc error. 50*7fd79137SRobert Mustacchi Return DW_DLV_OK otherwise 51*7fd79137SRobert Mustacchi */ 52*7fd79137SRobert Mustacchi 53*7fd79137SRobert Mustacchi int 54*7fd79137SRobert Mustacchi _dwarf_pro_reloc_name_symbolic(Dwarf_P_Debug dbg, 55*7fd79137SRobert Mustacchi int base_sec_index, 56*7fd79137SRobert Mustacchi Dwarf_Unsigned offset, /* r_offset of reloc */ 57*7fd79137SRobert Mustacchi Dwarf_Unsigned symidx, 58*7fd79137SRobert Mustacchi enum Dwarf_Rel_Type type, 59*7fd79137SRobert Mustacchi int reltarget_length) 60*7fd79137SRobert Mustacchi { 61*7fd79137SRobert Mustacchi /* get a slot, fill in the slot entry */ 62*7fd79137SRobert Mustacchi void *relrec_to_fill = 0; 63*7fd79137SRobert Mustacchi int res = 0; 64*7fd79137SRobert Mustacchi struct Dwarf_Relocation_Data_s *slotp; 65*7fd79137SRobert Mustacchi 66*7fd79137SRobert Mustacchi res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, 67*7fd79137SRobert Mustacchi &relrec_to_fill); 68*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) 69*7fd79137SRobert Mustacchi return res; 70*7fd79137SRobert Mustacchi slotp = (struct Dwarf_Relocation_Data_s *) relrec_to_fill; 71*7fd79137SRobert Mustacchi slotp->drd_type = type; 72*7fd79137SRobert Mustacchi slotp->drd_length = reltarget_length; 73*7fd79137SRobert Mustacchi slotp->drd_offset = offset; 74*7fd79137SRobert Mustacchi slotp->drd_symbol_index = symidx; 75*7fd79137SRobert Mustacchi return DW_DLV_OK; 76*7fd79137SRobert Mustacchi } 77*7fd79137SRobert Mustacchi 78*7fd79137SRobert Mustacchi 79*7fd79137SRobert Mustacchi 80*7fd79137SRobert Mustacchi /* 81*7fd79137SRobert Mustacchi Return DW_DLV_ERROR on malloc error. 82*7fd79137SRobert Mustacchi Return DW_DLV_OK otherwise 83*7fd79137SRobert Mustacchi */ 84*7fd79137SRobert Mustacchi int 85*7fd79137SRobert Mustacchi _dwarf_pro_reloc_length_symbolic(Dwarf_P_Debug dbg, 86*7fd79137SRobert Mustacchi int base_sec_index, 87*7fd79137SRobert Mustacchi Dwarf_Unsigned offset, /* r_offset of reloc */ 88*7fd79137SRobert Mustacchi Dwarf_Unsigned start_symidx, 89*7fd79137SRobert Mustacchi Dwarf_Unsigned end_symidx, 90*7fd79137SRobert Mustacchi enum Dwarf_Rel_Type type, 91*7fd79137SRobert Mustacchi int reltarget_length) 92*7fd79137SRobert Mustacchi { 93*7fd79137SRobert Mustacchi /* get a slot, fill in the slot entry */ 94*7fd79137SRobert Mustacchi void *relrec_to_fill = 0; 95*7fd79137SRobert Mustacchi int res = 0; 96*7fd79137SRobert Mustacchi struct Dwarf_Relocation_Data_s *slotp1 = 0; 97*7fd79137SRobert Mustacchi struct Dwarf_Relocation_Data_s *slotp2 = 0; 98*7fd79137SRobert Mustacchi 99*7fd79137SRobert Mustacchi res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, 100*7fd79137SRobert Mustacchi &relrec_to_fill); 101*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) 102*7fd79137SRobert Mustacchi return res; 103*7fd79137SRobert Mustacchi slotp1 = (struct Dwarf_Relocation_Data_s *) relrec_to_fill; 104*7fd79137SRobert Mustacchi res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, 105*7fd79137SRobert Mustacchi &relrec_to_fill); 106*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) 107*7fd79137SRobert Mustacchi return res; 108*7fd79137SRobert Mustacchi slotp2 = (struct Dwarf_Relocation_Data_s *) relrec_to_fill; 109*7fd79137SRobert Mustacchi 110*7fd79137SRobert Mustacchi /* ASSERT: type == dwarf_drt_first_of_length_type_pair */ 111*7fd79137SRobert Mustacchi slotp1->drd_type = type; 112*7fd79137SRobert Mustacchi slotp1->drd_length = reltarget_length; 113*7fd79137SRobert Mustacchi slotp1->drd_offset = offset; 114*7fd79137SRobert Mustacchi slotp1->drd_symbol_index = start_symidx; 115*7fd79137SRobert Mustacchi 116*7fd79137SRobert Mustacchi slotp2->drd_type = dwarf_drt_second_of_length_pair; 117*7fd79137SRobert Mustacchi slotp2->drd_length = reltarget_length; 118*7fd79137SRobert Mustacchi slotp2->drd_offset = offset; 119*7fd79137SRobert Mustacchi slotp2->drd_symbol_index = end_symidx; 120*7fd79137SRobert Mustacchi return DW_DLV_OK; 121*7fd79137SRobert Mustacchi } 122*7fd79137SRobert Mustacchi 123*7fd79137SRobert Mustacchi /* 124*7fd79137SRobert Mustacchi Reset whatever fields of Dwarf_P_Per_Reloc_Sect_s 125*7fd79137SRobert Mustacchi we must to allow adding a fresh new single 126*7fd79137SRobert Mustacchi block easily (block consolidation use only). 127*7fd79137SRobert Mustacchi 128*7fd79137SRobert Mustacchi */ 129*7fd79137SRobert Mustacchi static void 130*7fd79137SRobert Mustacchi _dwarf_reset_reloc_sect_info(struct Dwarf_P_Per_Reloc_Sect_s *pblk, 131*7fd79137SRobert Mustacchi unsigned long ct) 132*7fd79137SRobert Mustacchi { 133*7fd79137SRobert Mustacchi 134*7fd79137SRobert Mustacchi 135*7fd79137SRobert Mustacchi /* Do not zero pr_sect_num_of_reloc_sect */ 136*7fd79137SRobert Mustacchi pblk->pr_reloc_total_count = 0; 137*7fd79137SRobert Mustacchi pblk->pr_first_block = 0; 138*7fd79137SRobert Mustacchi pblk->pr_last_block = 0; 139*7fd79137SRobert Mustacchi pblk->pr_block_count = 0; 140*7fd79137SRobert Mustacchi pblk->pr_slots_per_block_to_alloc = ct; 141*7fd79137SRobert Mustacchi } 142*7fd79137SRobert Mustacchi 143*7fd79137SRobert Mustacchi /* 144*7fd79137SRobert Mustacchi Ensure each stream is a single buffer and 145*7fd79137SRobert Mustacchi add that single buffer to the set of stream buffers. 146*7fd79137SRobert Mustacchi 147*7fd79137SRobert Mustacchi By creating a new buffer and copying if necessary. 148*7fd79137SRobert Mustacchi (If > 1 block, reduce to 1 block) 149*7fd79137SRobert Mustacchi 150*7fd79137SRobert Mustacchi Free the input set of buffers if we consolidate. 151*7fd79137SRobert Mustacchi 152*7fd79137SRobert Mustacchi We pass back *new_sec_count as zero because we 153*7fd79137SRobert Mustacchi are not creating normal sections for a .o, but 154*7fd79137SRobert Mustacchi symbolic relocations, separately counted. 155*7fd79137SRobert Mustacchi 156*7fd79137SRobert Mustacchi Return -1 on error (malloc failure) 157*7fd79137SRobert Mustacchi 158*7fd79137SRobert Mustacchi Return DW_DLV_OK on success. Any other return indicates 159*7fd79137SRobert Mustacchi malloc failed. 160*7fd79137SRobert Mustacchi */ 161*7fd79137SRobert Mustacchi int 162*7fd79137SRobert Mustacchi _dwarf_symbolic_relocs_to_disk(Dwarf_P_Debug dbg, 163*7fd79137SRobert Mustacchi Dwarf_Signed * new_sec_count) 164*7fd79137SRobert Mustacchi { 165*7fd79137SRobert Mustacchi /* unsigned long total_size =0; */ 166*7fd79137SRobert Mustacchi Dwarf_Small *data = 0; 167*7fd79137SRobert Mustacchi int sec_index = 0; 168*7fd79137SRobert Mustacchi int res = 0; 169*7fd79137SRobert Mustacchi unsigned long i = 0; 170*7fd79137SRobert Mustacchi Dwarf_Error error = 0; 171*7fd79137SRobert Mustacchi Dwarf_Signed sec_count = 0; 172*7fd79137SRobert Mustacchi Dwarf_P_Per_Reloc_Sect p_reloc = &dbg->de_reloc_sect[0]; 173*7fd79137SRobert Mustacchi 174*7fd79137SRobert Mustacchi for (i = 0; i < NUM_DEBUG_SECTIONS; ++i, ++p_reloc) { 175*7fd79137SRobert Mustacchi unsigned long ct = p_reloc->pr_reloc_total_count; 176*7fd79137SRobert Mustacchi struct Dwarf_P_Relocation_Block_s *p_blk; 177*7fd79137SRobert Mustacchi struct Dwarf_P_Relocation_Block_s *p_blk_last; 178*7fd79137SRobert Mustacchi int err; 179*7fd79137SRobert Mustacchi if (ct == 0) { 180*7fd79137SRobert Mustacchi continue; 181*7fd79137SRobert Mustacchi } 182*7fd79137SRobert Mustacchi 183*7fd79137SRobert Mustacchi /* len = dbg->de_relocation_record_size; */ 184*7fd79137SRobert Mustacchi ++sec_count; 185*7fd79137SRobert Mustacchi 186*7fd79137SRobert Mustacchi /* total_size = ct *len; */ 187*7fd79137SRobert Mustacchi sec_index = p_reloc->pr_sect_num_of_reloc_sect; 188*7fd79137SRobert Mustacchi if (sec_index == 0) { 189*7fd79137SRobert Mustacchi /* Call de_callback_func or de_callback_func_b, 190*7fd79137SRobert Mustacchi getting section number of reloc section. */ 191*7fd79137SRobert Mustacchi int rel_section_index = 0; 192*7fd79137SRobert Mustacchi int int_name = 0; 193*7fd79137SRobert Mustacchi Dwarf_Unsigned name_idx = 0; 194*7fd79137SRobert Mustacchi 195*7fd79137SRobert Mustacchi /* 196*7fd79137SRobert Mustacchi This is a bit of a fake, as we do not really have true 197*7fd79137SRobert Mustacchi elf sections at all. Just the data such might contain. 198*7fd79137SRobert Mustacchi But this lets the caller eventually link things 199*7fd79137SRobert Mustacchi together: without this call we would not know what rel 200*7fd79137SRobert Mustacchi data goes with what section when we are asked for the 201*7fd79137SRobert Mustacchi real arrays. */ 202*7fd79137SRobert Mustacchi 203*7fd79137SRobert Mustacchi if (dbg->de_callback_func_b) { 204*7fd79137SRobert Mustacchi rel_section_index = 205*7fd79137SRobert Mustacchi dbg->de_callback_func_b(_dwarf_rel_section_names[i], 206*7fd79137SRobert Mustacchi dbg->de_relocation_record_size, 207*7fd79137SRobert Mustacchi /* type */ SHT_REL, 208*7fd79137SRobert Mustacchi /* flags */ 0, 209*7fd79137SRobert Mustacchi /* link to symtab, which we cannot 210*7fd79137SRobert Mustacchi know */ SHN_UNDEF, 211*7fd79137SRobert Mustacchi /* sec rels apply to */ 212*7fd79137SRobert Mustacchi dbg->de_elf_sects[i], 213*7fd79137SRobert Mustacchi &name_idx, &err); 214*7fd79137SRobert Mustacchi } else { 215*7fd79137SRobert Mustacchi rel_section_index = 216*7fd79137SRobert Mustacchi dbg->de_callback_func(_dwarf_rel_section_names[i], 217*7fd79137SRobert Mustacchi dbg->de_relocation_record_size, 218*7fd79137SRobert Mustacchi /* type */ SHT_REL, 219*7fd79137SRobert Mustacchi /* flags */ 0, 220*7fd79137SRobert Mustacchi /* link to symtab, which we cannot 221*7fd79137SRobert Mustacchi know */ SHN_UNDEF, 222*7fd79137SRobert Mustacchi /* sec rels apply to, in elf, sh_info */ 223*7fd79137SRobert Mustacchi dbg->de_elf_sects[i], &int_name, &err); 224*7fd79137SRobert Mustacchi name_idx = int_name; 225*7fd79137SRobert Mustacchi } 226*7fd79137SRobert Mustacchi if (rel_section_index == -1) { 227*7fd79137SRobert Mustacchi { 228*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, &error, DW_DLE_ELF_SECT_ERR); 229*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 230*7fd79137SRobert Mustacchi } 231*7fd79137SRobert Mustacchi } 232*7fd79137SRobert Mustacchi p_reloc->pr_sect_num_of_reloc_sect = rel_section_index; 233*7fd79137SRobert Mustacchi sec_index = rel_section_index; 234*7fd79137SRobert Mustacchi } 235*7fd79137SRobert Mustacchi 236*7fd79137SRobert Mustacchi p_blk = p_reloc->pr_first_block; 237*7fd79137SRobert Mustacchi 238*7fd79137SRobert Mustacchi if (p_reloc->pr_block_count > 1) { 239*7fd79137SRobert Mustacchi struct Dwarf_P_Relocation_Block_s *new_blk; 240*7fd79137SRobert Mustacchi 241*7fd79137SRobert Mustacchi /* HACK , not normal interfaces, trashing p_reloc current 242*7fd79137SRobert Mustacchi contents! */ 243*7fd79137SRobert Mustacchi _dwarf_reset_reloc_sect_info(p_reloc, ct); 244*7fd79137SRobert Mustacchi 245*7fd79137SRobert Mustacchi /* Creating new single block for all 'ct' entries */ 246*7fd79137SRobert Mustacchi res = _dwarf_pro_pre_alloc_n_reloc_slots(dbg, (int) i, ct); 247*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 248*7fd79137SRobert Mustacchi return res; 249*7fd79137SRobert Mustacchi } 250*7fd79137SRobert Mustacchi new_blk = p_reloc->pr_first_block; 251*7fd79137SRobert Mustacchi 252*7fd79137SRobert Mustacchi data = (Dwarf_Small *) new_blk->rb_data; 253*7fd79137SRobert Mustacchi 254*7fd79137SRobert Mustacchi /* The following loop does the consolidation to a single 255*7fd79137SRobert Mustacchi block and frees the input block(s). */ 256*7fd79137SRobert Mustacchi do { 257*7fd79137SRobert Mustacchi unsigned long len = 258*7fd79137SRobert Mustacchi p_blk->rb_where_to_add_next - p_blk->rb_data; 259*7fd79137SRobert Mustacchi memcpy(data, p_blk->rb_data, len); 260*7fd79137SRobert Mustacchi data += len; 261*7fd79137SRobert Mustacchi p_blk_last = p_blk; 262*7fd79137SRobert Mustacchi p_blk = p_blk->rb_next; 263*7fd79137SRobert Mustacchi _dwarf_p_dealloc(dbg, (Dwarf_Small *) p_blk_last); 264*7fd79137SRobert Mustacchi } while (p_blk); 265*7fd79137SRobert Mustacchi /* ASSERT: sum of len copied == total_size */ 266*7fd79137SRobert Mustacchi new_blk->rb_next_slot_to_use = ct; 267*7fd79137SRobert Mustacchi new_blk->rb_where_to_add_next = (char *) data; 268*7fd79137SRobert Mustacchi p_reloc->pr_reloc_total_count = ct; 269*7fd79137SRobert Mustacchi 270*7fd79137SRobert Mustacchi /* have now created a single block, but no change in slots 271*7fd79137SRobert Mustacchi used (pr_reloc_total_count) */ 272*7fd79137SRobert Mustacchi } 273*7fd79137SRobert Mustacchi } 274*7fd79137SRobert Mustacchi *new_sec_count = 0; 275*7fd79137SRobert Mustacchi return DW_DLV_OK; 276*7fd79137SRobert Mustacchi } 277