1 /* 2 Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. 3 Portions Copyright 2011-2019 David Anderson. 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., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, 23 USA. 24 25 */ 26 27 #include "config.h" 28 #include "libdwarfdefs.h" 29 #include <stdio.h> 30 #ifdef HAVE_STRING_H 31 #include <string.h> 32 #endif /* HAVE_STRING_H */ 33 #ifdef HAVE_ELFACCESS_H 34 #include <elfaccess.h> 35 #endif 36 #include "pro_incl.h" 37 #ifdef HAVE_STDDEF_H 38 #include <stddef.h> 39 #endif /* HAVE_STDDEF_H */ 40 #include "dwarf.h" 41 #include "libdwarf.h" 42 #include "pro_opaque.h" 43 #include "pro_error.h" 44 #include "pro_alloc.h" 45 #include "pro_section.h" 46 #include "pro_types.h" 47 48 #define SIZEOFT32 4 49 50 /* 51 This function adds another type name to the 52 list of type names for the given Dwarf_P_Debug. 53 It returns 0 on error, and 1 otherwise. 54 */ 55 Dwarf_Unsigned 56 dwarf_add_typename(Dwarf_P_Debug dbg, 57 Dwarf_P_Die die, 58 char *type_name, 59 Dwarf_Error * error) 60 { 61 int res = 0; 62 63 res = _dwarf_add_simple_name_entry(dbg, die, type_name, 64 dwarf_snk_typename, error); 65 if (res != DW_DLV_OK) { 66 return 0; 67 } 68 return 1; 69 70 } 71 int 72 dwarf_add_typename_a(Dwarf_P_Debug dbg, 73 Dwarf_P_Die die, 74 char *type_name, 75 Dwarf_Error * error) 76 { 77 int res = 0; 78 79 res = _dwarf_add_simple_name_entry(dbg, die, type_name, 80 dwarf_snk_typename, error); 81 return res; 82 } 83 84 /* 85 The following is the generic 'add a simple name entry' 86 for any of the simple name sections. 87 88 See enum dwarf_sn_kind in pro_opaque.h 89 90 */ 91 int 92 _dwarf_add_simple_name_entry(Dwarf_P_Debug dbg, 93 Dwarf_P_Die die, 94 char *entry_name, 95 enum dwarf_sn_kind entrykind, 96 Dwarf_Error * error) 97 { 98 Dwarf_P_Simple_nameentry nameentry; 99 Dwarf_P_Simple_name_header hdr; 100 char *name; 101 int uword_size; 102 103 if (dbg == NULL) { 104 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 105 return DW_DLV_ERROR; 106 } 107 108 if (die == NULL) { 109 _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL); 110 return DW_DLV_ERROR; 111 } 112 113 114 nameentry = (Dwarf_P_Simple_nameentry) 115 _dwarf_p_get_alloc(dbg, 116 sizeof(struct Dwarf_P_Simple_nameentry_s)); 117 if (nameentry == NULL) { 118 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 119 return DW_DLV_ERROR; 120 } 121 122 name = _dwarf_p_get_alloc(dbg, strlen(entry_name) + 1); 123 if (name == NULL) { 124 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 125 return DW_DLV_ERROR; 126 } 127 strcpy(name, entry_name); 128 129 nameentry->sne_die = die; 130 nameentry->sne_name = name; 131 nameentry->sne_name_len = strlen(name); 132 uword_size = dbg->de_dwarf_offset_size; 133 134 hdr = &dbg->de_simple_name_headers[entrykind]; 135 if (hdr->sn_head == NULL) 136 hdr->sn_head = hdr->sn_tail = nameentry; 137 else { 138 hdr->sn_tail->sne_next = nameentry; 139 hdr->sn_tail = nameentry; 140 } 141 hdr->sn_count++; 142 hdr->sn_net_len += uword_size + nameentry->sne_name_len + 1; 143 144 return DW_DLV_OK; 145 } 146 147 148 149 /* 150 _dwarf_transform_simplename_to_disk writes 151 ".rel.debug_pubnames", 152 ".rel.debug_funcnames", sgi extension 153 ".rel.debug_typenames", sgi extension 154 ".rel.debug_varnames", sgi extension 155 ".rel.debug_weaknames", sgi extension 156 to disk. 157 section_index indexes one of those sections. 158 entrykind is one of those 'kind's. */ 159 int 160 _dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg, 161 enum dwarf_sn_kind entrykind, 162 int section_index, /* in de_elf_sects etc */ 163 Dwarf_Signed *nbufs, 164 Dwarf_Error * error) 165 { 166 167 168 /* Used to fill in 0. */ 169 const Dwarf_Signed big_zero = 0; 170 171 /* Used to scan the section data buffers. */ 172 Dwarf_P_Section_Data debug_sect; 173 174 Dwarf_Signed debug_info_size; 175 176 Dwarf_P_Simple_nameentry nameentry_original; 177 Dwarf_P_Simple_nameentry nameentry; 178 Dwarf_Small *stream_bytes; 179 Dwarf_Small *cur_stream_bytes_ptr; 180 Dwarf_Unsigned stream_bytes_count; 181 Dwarf_Unsigned adjusted_length; /* count excluding length field */ 182 183 184 int uword_size = dbg->de_dwarf_offset_size; 185 int extension_size = dbg->de_64bit_extension ? 4 : 0; 186 187 Dwarf_P_Simple_name_header hdr; 188 189 190 /* ***** BEGIN CODE ***** */ 191 192 debug_info_size = 0; 193 for (debug_sect = dbg->de_debug_sects; debug_sect != NULL; 194 debug_sect = debug_sect->ds_next) { 195 /* We want the size of the .debug_info section for this CU 196 because the dwarf spec requires us to output it below so we 197 look for it specifically. */ 198 if (debug_sect->ds_elf_sect_no == dbg->de_elf_sects[DEBUG_INFO]) { 199 debug_info_size += debug_sect->ds_nbytes; 200 } 201 } 202 203 hdr = &dbg->de_simple_name_headers[entrykind]; 204 /* Size of the .debug_typenames (or similar) section header. */ 205 stream_bytes_count = extension_size + uword_size + /* Size of 206 length field. */ 207 DWARF_HALF_SIZE + /* Size of version field. */ 208 uword_size + /* Size of .debug_info offset. */ 209 uword_size; /* Size of .debug_names. */ 210 211 212 213 nameentry_original = hdr->sn_head; 214 /* add in the content size */ 215 stream_bytes_count += hdr->sn_net_len; 216 217 /* Size of the last 0 offset. */ 218 stream_bytes_count += uword_size; 219 220 /* Now we know how long the entire section is */ 221 GET_CHUNK(dbg, dbg->de_elf_sects[section_index], 222 stream_bytes, (unsigned long) stream_bytes_count, error); 223 cur_stream_bytes_ptr = stream_bytes; 224 225 if (extension_size) { 226 DISTINGUISHED_VALUE_ARRAY(v4); 227 228 WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, 229 (const void *)&v4[0],SIZEOFT32 , extension_size); 230 cur_stream_bytes_ptr += extension_size; 231 232 } 233 /* Write the adjusted length of .debug_*names section. */ 234 adjusted_length = stream_bytes_count - uword_size - extension_size; 235 WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, 236 (const void *) &adjusted_length, 237 sizeof(adjusted_length), uword_size); 238 cur_stream_bytes_ptr += uword_size; 239 240 /* Write the version as 2 bytes. */ 241 { 242 Dwarf_Half verstamp = CURRENT_VERSION_STAMP; 243 244 WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, 245 (const void *) &verstamp, 246 sizeof(verstamp), DWARF_HALF_SIZE); 247 cur_stream_bytes_ptr += DWARF_HALF_SIZE; 248 } 249 250 /* Write the offset of the compile-unit. */ 251 WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, 252 (const void *) &big_zero, 253 sizeof(big_zero), uword_size); 254 cur_stream_bytes_ptr += uword_size; 255 256 /* now create the relocation for the compile_unit offset */ 257 { 258 int res = dbg->de_relocate_by_name_symbol(dbg, 259 section_index, 260 extension_size + uword_size + 261 DWARF_HALF_SIZE /* r_offset */ , 262 /* debug_info section name symbol */ 263 dbg->de_sect_name_idx[DEBUG_INFO], 264 dwarf_drt_data_reloc, 265 uword_size); 266 267 if (res != DW_DLV_OK) { 268 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 269 return DW_DLV_ERROR; 270 } 271 } 272 273 /* Write the size of .debug_info section. */ 274 WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, 275 (const void *) &debug_info_size, 276 sizeof(debug_info_size), uword_size); 277 cur_stream_bytes_ptr += uword_size; 278 279 280 for (nameentry = nameentry_original; 281 nameentry != NULL; nameentry = nameentry->sne_next) { 282 283 /* Copy offset of die from start of compile-unit. */ 284 WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, 285 (const void *) &nameentry->sne_die->di_offset, 286 sizeof(nameentry->sne_die->di_offset), 287 uword_size); 288 cur_stream_bytes_ptr += uword_size; 289 290 /* Copy the type name. */ 291 strcpy((char *) cur_stream_bytes_ptr, nameentry->sne_name); 292 cur_stream_bytes_ptr += nameentry->sne_name_len + 1; 293 } 294 295 WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr, 296 (const void *) &big_zero, 297 sizeof(big_zero), uword_size); 298 *nbufs = dbg->de_n_debug_sect; 299 return DW_DLV_OK; 300 } 301