1 /* 2 3 Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. 4 Portions Copyright 2016 David Anderson. All Rights Reserved. 5 6 This program is free software; you can redistribute it and/or modify it 7 under the terms of version 2.1 of the GNU Lesser General Public License 8 as published by the Free Software Foundation. 9 10 This program is distributed in the hope that it would be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 14 Further, this software is distributed without any warranty that it is 15 free of the rightful claim of any third person regarding infringement 16 or the like. Any license provided herein, whether implied or 17 otherwise, applies only to this software file. Patent licenses, if 18 any, provided herein do not apply to combinations of this program with 19 other software, or any other product whatsoever. 20 21 You should have received a copy of the GNU Lesser General Public 22 License along with this program; if not, write the Free Software 23 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, 24 USA. 25 26 */ 27 28 #include "config.h" 29 #include "libdwarfdefs.h" 30 #include <stdio.h> 31 #ifdef HAVE_STRING_H 32 #include <string.h> 33 #endif /* HAVE_STRING_H */ 34 #ifdef HAVE_STDDEF_H 35 #include <stddef.h> 36 #endif /* HAVE_STDDEF_H */ 37 /*#include <elfaccess.h> */ 38 #include "pro_incl.h" 39 #include "dwarf.h" 40 #include "libdwarf.h" 41 #include "pro_opaque.h" 42 #include "pro_error.h" 43 #include "pro_alloc.h" 44 #include "pro_section.h" 45 #include "pro_reloc.h" 46 #include "pro_reloc_symbolic.h" 47 48 #ifndef SHT_REL 49 #define SHT_REL 9 50 #endif /* SHT_REL */ 51 #ifndef SHN_UNDEF 52 #define SHN_UNDEF 0 53 #endif /* SHN_UNDEF */ 54 55 /* Return DW_DLV_ERROR on malloc error. 56 Return DW_DLV_OK otherwise */ 57 58 int 59 _dwarf_pro_reloc_name_symbolic(Dwarf_P_Debug dbg, 60 int base_sec_index, 61 Dwarf_Unsigned offset, /* r_offset of reloc */ 62 Dwarf_Unsigned symidx, 63 enum Dwarf_Rel_Type type, 64 int reltarget_length) 65 { 66 /* get a slot, fill in the slot entry */ 67 void *relrec_to_fill = 0; 68 int res = 0; 69 struct Dwarf_Relocation_Data_s *slotp; 70 71 res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, 72 &relrec_to_fill); 73 if (res != DW_DLV_OK) 74 return res; 75 slotp = (struct Dwarf_Relocation_Data_s *) relrec_to_fill; 76 slotp->drd_type = type; 77 slotp->drd_length = reltarget_length; 78 slotp->drd_offset = offset; 79 slotp->drd_symbol_index = symidx; 80 return DW_DLV_OK; 81 } 82 83 84 85 /* Return DW_DLV_ERROR on malloc error. 86 Return DW_DLV_OK otherwise */ 87 int 88 _dwarf_pro_reloc_length_symbolic(Dwarf_P_Debug dbg, 89 int base_sec_index, 90 Dwarf_Unsigned offset, /* r_offset of reloc */ 91 Dwarf_Unsigned start_symidx, 92 Dwarf_Unsigned end_symidx, 93 enum Dwarf_Rel_Type type, 94 int reltarget_length) 95 { 96 /* get a slot, fill in the slot entry */ 97 void *relrec_to_fill = 0; 98 int res = 0; 99 struct Dwarf_Relocation_Data_s *slotp1 = 0; 100 struct Dwarf_Relocation_Data_s *slotp2 = 0; 101 102 res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, 103 &relrec_to_fill); 104 if (res != DW_DLV_OK) 105 return res; 106 slotp1 = (struct Dwarf_Relocation_Data_s *) relrec_to_fill; 107 res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index, 108 &relrec_to_fill); 109 if (res != DW_DLV_OK) 110 return res; 111 slotp2 = (struct Dwarf_Relocation_Data_s *) relrec_to_fill; 112 113 /* ASSERT: type == dwarf_drt_first_of_length_type_pair */ 114 slotp1->drd_type = type; 115 slotp1->drd_length = reltarget_length; 116 slotp1->drd_offset = offset; 117 slotp1->drd_symbol_index = start_symidx; 118 119 slotp2->drd_type = dwarf_drt_second_of_length_pair; 120 slotp2->drd_length = reltarget_length; 121 slotp2->drd_offset = offset; 122 slotp2->drd_symbol_index = end_symidx; 123 return DW_DLV_OK; 124 } 125 126 /* Ensure each stream is a single buffer and 127 add that single buffer to the set of stream buffers. 128 129 By creating a new buffer and copying if necessary. 130 (If > 1 block, reduce to 1 block) 131 132 Free the input set of buffers if we consolidate. 133 134 We pass back *new_sec_count as zero because we 135 are not creating normal sections for a .o, but 136 symbolic relocations, separately counted. 137 138 Return -1 on error (malloc failure) 139 140 Return DW_DLV_OK on success. Any other return indicates 141 malloc failed. */ 142 int 143 _dwarf_symbolic_relocs_to_disk(Dwarf_P_Debug dbg, 144 Dwarf_Signed * new_sec_count) 145 { 146 int i = 0; 147 Dwarf_Error error = 0; 148 149 for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) { 150 int sec_index = 0; 151 Dwarf_P_Per_Reloc_Sect p_reloc = dbg->de_reloc_sect + i; 152 unsigned long ct = p_reloc->pr_reloc_total_count; 153 int err = 0; 154 if (ct == 0) { 155 /* No relocations in here. Nothing to do. */ 156 continue; 157 } 158 159 /* total_size = ct *len; */ 160 sec_index = p_reloc->pr_sect_num_of_reloc_sect; 161 if (sec_index == 0) { 162 /* sec_index zero means we have not processed this 163 section of relocations yet. */ 164 /* Call de_callback_func 165 getting section number of reloc section. */ 166 int rel_section_index = 0; 167 Dwarf_Unsigned name_idx = 0; 168 169 /* This is a bit of a fake, as we do not really have true 170 elf sections at all. Just the data such might contain. 171 But this lets the caller eventually link things 172 together: without this call we would not know what rel 173 data goes with what section when we are asked for the 174 real arrays. */ 175 176 if (dbg->de_callback_func) { 177 /* For symbolic relocations de_callback_func 178 may well return 0. */ 179 rel_section_index = 180 dbg->de_callback_func(_dwarf_rel_section_names[i], 181 dbg->de_relocation_record_size, 182 /* type */ SHT_REL, 183 /* flags */ 0, 184 /* link to symtab, which we cannot 185 know */ SHN_UNDEF, 186 /* sec rels apply to */ 187 dbg->de_elf_sects[i], 188 &name_idx, 189 dbg->de_user_data,&err); 190 } 191 if (rel_section_index == -1) { 192 { 193 _dwarf_p_error(dbg, &error, DW_DLE_ELF_SECT_ERR); 194 return (DW_DLV_ERROR); 195 } 196 } 197 p_reloc->pr_sect_num_of_reloc_sect = rel_section_index; 198 } 199 200 201 /* If pr_block_count 0 or 1 then the blocks are 202 an array (with 0 or 1 entries) so we'll just 203 return to the for loop. No more work to do here. */ 204 if (p_reloc->pr_block_count < 2) { 205 continue; 206 } 207 { 208 /* Since more than one relocation on the section 209 we now convert the list of relocation blocks 210 into a proper array of blocks. */ 211 struct Dwarf_P_Relocation_Block_s *new_blk = 0; 212 struct Dwarf_P_Relocation_Block_s *p_blk = 0; 213 Dwarf_Small *data = 0; 214 int res = 0; 215 216 p_blk = p_reloc->pr_first_block; 217 /* Do not zero pr_sect_num_of_reloc_sect */ 218 p_reloc->pr_reloc_total_count = 0; 219 p_reloc->pr_first_block = 0; 220 p_reloc->pr_last_block = 0; 221 p_reloc->pr_block_count = 0; 222 /* Now we know a number making a single 223 array. Replaces DEFAULT_SLOTS_PER_BLOCK */ 224 p_reloc->pr_slots_per_block_to_alloc = ct; 225 226 /* Creating new single block for all 'ct' entries. 227 Assigns a pointer value to pr_first_block 228 (which means our p_reloc). 229 It updates p_reloc->pr_first_block */ 230 res = _dwarf_pro_pre_alloc_specific_reloc_slots(dbg, 231 p_reloc,ct); 232 if (res != DW_DLV_OK) { 233 return res; 234 } 235 236 new_blk = p_reloc->pr_first_block; 237 data = (Dwarf_Small *) new_blk->rb_data; 238 239 /* The following loop does the consolidation to a single 240 block and frees the input block(s). 241 p_blk points to the old singly-linked-list 242 and is the 243 only access to that list. 244 data is a pointer to the new array of ct entries 245 which is our target(destination) of the copies. 246 */ 247 do { 248 struct Dwarf_P_Relocation_Block_s *p_blk_last = 0; 249 /* len identifies the data in all the slots 250 in use in this block. */ 251 unsigned long len = 252 p_blk->rb_where_to_add_next - p_blk->rb_data; 253 memcpy(data, p_blk->rb_data, len); 254 data += len; 255 p_blk_last = p_blk; 256 p_blk = p_blk->rb_next; 257 _dwarf_p_dealloc(dbg, (Dwarf_Small *) p_blk_last); 258 } while (p_blk); 259 /* ASSERT: the dangling p_blk list all dealloc'd 260 which is really a no-op, all deallocations 261 take place at producer_finish(). */ 262 /* ASSERT: sum of len copied == total_size */ 263 new_blk->rb_next_slot_to_use = ct; 264 new_blk->rb_where_to_add_next = (char *) data; 265 p_reloc->pr_reloc_total_count = ct; 266 267 /* Have now created a single block, but no 268 change in slots used (pr_reloc_total_count) */ 269 } 270 } 271 /* There is no section data with symbolic, 272 so there is no count. */ 273 *new_sec_count = 0; 274 return DW_DLV_OK; 275 } 276