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 #include <string.h> 31 #include "pro_incl.h" 32 #include <stddef.h> 33 #include "dwarf.h" 34 #include "libdwarf.h" 35 #include "pro_opaque.h" 36 #include "pro_error.h" 37 #include "pro_encode_nm.h" 38 #include "pro_alloc.h" 39 #include "pro_section.h" 40 #include "pro_macinfo.h" 41 42 /* I don't much like the error strings this generates, since 43 like the rest of libdwarf they are simple strings with 44 no useful numbers in them. But that's not something I can 45 fix without more work than I have time for 46 right now. davea Nov 94. 47 */ 48 49 /* these are gross overestimates of the number of 50 ** bytes needed to store a number in LEB form. 51 ** Just estimates, and since blocks are reasonable size, 52 ** the end-block waste is small. 53 ** Of course the waste is NOT present on disk. 54 */ 55 56 #define COMMAND_LEN ENCODE_SPACE_NEEDED 57 #define LINE_LEN ENCODE_SPACE_NEEDED 58 #define BASE_MACINFO_MALLOC_LEN 2048 59 60 static int 61 libdwarf_compose_begin(Dwarf_P_Debug dbg, int code, 62 size_t maxlen, int *compose_error_type) 63 { 64 unsigned char *nextchar; 65 struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo; 66 67 if (curblk == 0) { 68 struct dw_macinfo_block_s *newb; 69 size_t len; 70 71 /* initial allocation */ 72 size_t blen = BASE_MACINFO_MALLOC_LEN; 73 74 if (blen < maxlen) { 75 blen = 2 * maxlen; 76 } 77 len = sizeof(struct dw_macinfo_block_s) + blen; 78 newb = 79 (struct dw_macinfo_block_s *) _dwarf_p_get_alloc(dbg, len); 80 if (!newb) { 81 *compose_error_type = DW_DLE_MACINFO_MALLOC_FAIL; 82 return DW_DLV_ERROR; 83 } 84 newb->mb_data = 85 (char *) newb + sizeof(struct dw_macinfo_block_s); 86 newb->mb_avail_len = blen; 87 newb->mb_used_len = 0; 88 newb->mb_macinfo_data_space_len = blen; 89 dbg->de_first_macinfo = newb; 90 dbg->de_current_macinfo = newb; 91 curblk = newb; 92 } else if (curblk->mb_avail_len < maxlen) { 93 struct dw_macinfo_block_s *newb; 94 size_t len; 95 96 /* no space left in block: allocate a new block */ 97 size_t blen = 98 dbg->de_current_macinfo->mb_macinfo_data_space_len * 2; 99 if (blen < maxlen) { 100 blen = 2 * maxlen; 101 } 102 len = sizeof(struct dw_macinfo_block_s) + blen; 103 newb = 104 (struct dw_macinfo_block_s *) _dwarf_p_get_alloc(dbg, len); 105 if (!newb) { 106 *compose_error_type = DW_DLE_MACINFO_MALLOC_FAIL; 107 return DW_DLV_ERROR; 108 } 109 newb->mb_data = 110 (char *) newb + sizeof(struct dw_macinfo_block_s); 111 newb->mb_avail_len = blen; 112 newb->mb_used_len = 0; 113 newb->mb_macinfo_data_space_len = blen; 114 dbg->de_first_macinfo->mb_next = newb; 115 dbg->de_current_macinfo = newb; 116 curblk = newb; 117 } 118 /* now curblk has enough room */ 119 dbg->de_compose_avail = curblk->mb_avail_len; 120 dbg->de_compose_used_len = curblk->mb_used_len; 121 nextchar = 122 (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len); 123 *nextchar = code; 124 dbg->de_compose_avail--; 125 ++dbg->de_compose_used_len; 126 return DW_DLV_OK; 127 } 128 129 130 131 static void 132 libdwarf_compose_add_string(Dwarf_P_Debug dbg, const char *string, size_t len) 133 { 134 struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo; 135 unsigned char *nextchar; 136 137 nextchar = 138 (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len); 139 140 len += 1; /* count the null terminator */ 141 142 memcpy(nextchar, string, len); 143 dbg->de_compose_avail -= len; 144 dbg->de_compose_used_len += len; 145 return; 146 147 } 148 static int 149 libdwarf_compose_add_line(Dwarf_P_Debug dbg, 150 Dwarf_Unsigned line, int *compose_error_type) 151 { 152 struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo; 153 unsigned char *nextchar; 154 int res; 155 int nbytes; 156 157 nextchar = 158 (unsigned char *) (curblk->mb_data + dbg->de_compose_used_len); 159 160 /* Put the created leb number directly into the macro buffer If 161 dbg->de_compose_avail is > INT_MAX this will not work as the 162 'int' will look negative to _dwarf_pro_encode_leb128_nm! */ 163 164 res = _dwarf_pro_encode_leb128_nm(line, &nbytes, 165 (char *) nextchar, 166 (int) dbg->de_compose_avail); 167 if (res != DW_DLV_OK) { 168 *compose_error_type = DW_DLE_MACINFO_INTERNAL_ERROR_SPACE; 169 return DW_DLV_ERROR; 170 } 171 172 dbg->de_compose_avail -= nbytes; 173 dbg->de_compose_used_len += nbytes; 174 return DW_DLV_OK; 175 } 176 177 /* This function actually 'commits' the space used by the 178 preceeding calls. */ 179 static int 180 libdwarf_compose_complete(Dwarf_P_Debug dbg, int *compose_error_type) 181 { 182 struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo; 183 184 if (dbg->de_compose_used_len > curblk->mb_macinfo_data_space_len) { 185 *compose_error_type = DW_DLE_MACINFO_INTERNAL_ERROR_SPACE; 186 return DW_DLV_ERROR; 187 } 188 curblk->mb_avail_len = dbg->de_compose_avail; 189 curblk->mb_used_len = dbg->de_compose_used_len; 190 return DW_DLV_OK; 191 } 192 193 194 195 int 196 dwarf_def_macro(Dwarf_P_Debug dbg, 197 Dwarf_Unsigned line, 198 char *macname, char *macvalue, Dwarf_Error * error) 199 { 200 size_t len; 201 size_t len2; 202 size_t length_est; 203 int res; 204 int compose_error_type; 205 206 if (dbg == NULL) { 207 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 208 return (DW_DLV_ERROR); 209 } 210 if (macname == 0) { 211 _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL); 212 return (DW_DLV_ERROR); 213 } 214 len = strlen(macname) + 1; 215 if (len == 0) { 216 _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY); 217 return (DW_DLV_ERROR); 218 } 219 if (macvalue) { 220 len2 = strlen(macvalue) + 1; 221 } else { 222 len2 = 0; 223 } 224 225 /* 1 for space character we add */ 226 length_est = COMMAND_LEN + LINE_LEN + len + len2 + 1; 227 228 res = libdwarf_compose_begin(dbg, DW_MACINFO_define, length_est, 229 &compose_error_type); 230 if (res != DW_DLV_OK) { 231 _dwarf_p_error(NULL, error, compose_error_type); 232 return (DW_DLV_ERROR); 233 } 234 res = libdwarf_compose_add_line(dbg, line, &compose_error_type); 235 if (res != DW_DLV_OK) { 236 _dwarf_p_error(NULL, error, compose_error_type); 237 return (DW_DLV_ERROR); 238 } 239 libdwarf_compose_add_string(dbg, macname, len); 240 libdwarf_compose_add_string(dbg, " ", 1); 241 if (macvalue) { 242 libdwarf_compose_add_string(dbg, " ", 1); 243 libdwarf_compose_add_string(dbg, macvalue, len2); 244 } 245 res = libdwarf_compose_complete(dbg, &compose_error_type); 246 if (res != DW_DLV_OK) { 247 _dwarf_p_error(NULL, error, compose_error_type); 248 return (DW_DLV_ERROR); 249 } 250 return DW_DLV_OK; 251 } 252 253 int 254 dwarf_undef_macro(Dwarf_P_Debug dbg, 255 Dwarf_Unsigned line, 256 char *macname, Dwarf_Error * error) 257 { 258 259 size_t len; 260 size_t length_est; 261 int res; 262 int compose_error_type; 263 264 if (dbg == NULL) { 265 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 266 return (DW_DLV_ERROR); 267 } 268 if (macname == 0) { 269 _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL); 270 return (DW_DLV_ERROR); 271 } 272 len = strlen(macname) + 1; 273 if (len == 0) { 274 _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY); 275 return (DW_DLV_ERROR); 276 } 277 length_est = COMMAND_LEN + LINE_LEN + len; 278 res = libdwarf_compose_begin(dbg, DW_MACINFO_undef, length_est, 279 &compose_error_type); 280 if (res != DW_DLV_OK) { 281 _dwarf_p_error(NULL, error, compose_error_type); 282 return (DW_DLV_ERROR); 283 } 284 res = libdwarf_compose_add_line(dbg, line, &compose_error_type); 285 if (res != DW_DLV_OK) { 286 _dwarf_p_error(NULL, error, compose_error_type); 287 return (DW_DLV_ERROR); 288 } 289 libdwarf_compose_add_string(dbg, macname, len); 290 res = libdwarf_compose_complete(dbg, &compose_error_type); 291 if (res != DW_DLV_OK) { 292 _dwarf_p_error(NULL, error, compose_error_type); 293 return (DW_DLV_ERROR); 294 } 295 return DW_DLV_OK; 296 } 297 298 int 299 dwarf_start_macro_file(Dwarf_P_Debug dbg, 300 Dwarf_Unsigned fileindex, 301 Dwarf_Unsigned linenumber, Dwarf_Error * error) 302 { 303 size_t length_est; 304 int res; 305 int compose_error_type; 306 307 if (dbg == NULL) { 308 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 309 return (DW_DLV_ERROR); 310 } 311 length_est = COMMAND_LEN + LINE_LEN + LINE_LEN; 312 res = libdwarf_compose_begin(dbg, DW_MACINFO_start_file, length_est, 313 &compose_error_type); 314 if (res != DW_DLV_OK) { 315 _dwarf_p_error(NULL, error, compose_error_type); 316 return (DW_DLV_ERROR); 317 } 318 res = libdwarf_compose_add_line(dbg, fileindex, 319 &compose_error_type); 320 if (res != DW_DLV_OK) { 321 _dwarf_p_error(NULL, error, compose_error_type); 322 return (DW_DLV_ERROR); 323 } 324 res = libdwarf_compose_add_line(dbg, linenumber, 325 &compose_error_type); 326 if (res != DW_DLV_OK) { 327 _dwarf_p_error(NULL, error, compose_error_type); 328 return (DW_DLV_ERROR); 329 } 330 return DW_DLV_OK; 331 } 332 333 int 334 dwarf_end_macro_file(Dwarf_P_Debug dbg, Dwarf_Error * error) 335 { 336 size_t length_est; 337 int res; 338 int compose_error_type; 339 340 if (dbg == NULL) { 341 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 342 return (DW_DLV_ERROR); 343 } 344 length_est = COMMAND_LEN; 345 res = libdwarf_compose_begin(dbg, DW_MACINFO_end_file, length_est, 346 &compose_error_type); 347 if (res == DW_DLV_ERROR) { 348 _dwarf_p_error(dbg, error, compose_error_type); 349 return (DW_DLV_ERROR); 350 } 351 res = libdwarf_compose_complete(dbg, &compose_error_type); 352 if (res == DW_DLV_ERROR) { 353 _dwarf_p_error(dbg, error, compose_error_type); 354 return res; 355 } 356 return res; 357 } 358 359 int 360 dwarf_vendor_ext(Dwarf_P_Debug dbg, 361 Dwarf_Unsigned constant, 362 char *string, Dwarf_Error * error) 363 { 364 size_t len; 365 size_t length_est; 366 int res; 367 int compose_error_type; 368 369 if (dbg == NULL) { 370 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 371 return (DW_DLV_ERROR); 372 } 373 if (string == 0) { 374 _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL); 375 return (DW_DLV_ERROR); 376 } 377 len = strlen(string) + 1; 378 if (len == 0) { 379 _dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY); 380 return (DW_DLV_ERROR); 381 } 382 length_est = COMMAND_LEN + LINE_LEN + len; 383 res = libdwarf_compose_begin(dbg, DW_MACINFO_vendor_ext, length_est, 384 &compose_error_type); 385 if (res != DW_DLV_OK) { 386 _dwarf_p_error(NULL, error, compose_error_type); 387 return (DW_DLV_ERROR); 388 } 389 res = libdwarf_compose_add_line(dbg, constant, &compose_error_type); 390 if (res != DW_DLV_OK) { 391 _dwarf_p_error(NULL, error, compose_error_type); 392 return (DW_DLV_ERROR); 393 } 394 libdwarf_compose_add_string(dbg, string, len); 395 libdwarf_compose_complete(dbg, &compose_error_type); 396 return DW_DLV_OK; 397 } 398 399 400 401 int 402 _dwarf_pro_transform_macro_info_to_disk(Dwarf_P_Debug dbg, 403 Dwarf_Signed *nbufs, 404 Dwarf_Error * error) 405 { 406 /* Total num of bytes in .debug_macinfo section. */ 407 Dwarf_Unsigned mac_num_bytes; 408 409 /* Points to first byte of .debug_macinfo buffer. */ 410 Dwarf_Small *macinfo; 411 412 /* Fills in the .debug_macinfo buffer. */ 413 Dwarf_Small *macinfo_ptr; 414 415 416 /* Used to scan the section data buffers. */ 417 struct dw_macinfo_block_s *m_prev; 418 struct dw_macinfo_block_s *m_sect; 419 420 421 /* Get the size of the debug_macinfo data */ 422 mac_num_bytes = 0; 423 for (m_sect = dbg->de_first_macinfo; m_sect != NULL; 424 m_sect = m_sect->mb_next) { 425 mac_num_bytes += m_sect->mb_used_len; 426 } 427 /* The final entry has a type code of 0 to indicate It is final 428 for this CU Takes just 1 byte. */ 429 mac_num_bytes += 1; 430 431 GET_CHUNK(dbg, dbg->de_elf_sects[DEBUG_MACINFO], 432 macinfo, (unsigned long) mac_num_bytes, error); 433 434 macinfo_ptr = macinfo; 435 m_prev = 0; 436 for (m_sect = dbg->de_first_macinfo; m_sect != NULL; 437 m_sect = m_sect->mb_next) { 438 memcpy(macinfo_ptr, m_sect->mb_data, m_sect->mb_used_len); 439 macinfo_ptr += m_sect->mb_used_len; 440 if (m_prev) { 441 _dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev); 442 m_prev = 0; 443 } 444 m_prev = m_sect; 445 } 446 *macinfo_ptr = 0; /* the type code of 0 as last entry */ 447 if (m_prev) { 448 _dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev); 449 m_prev = 0; 450 } 451 452 dbg->de_first_macinfo = NULL; 453 dbg->de_current_macinfo = NULL; 454 455 *nbufs = dbg->de_n_debug_sect; 456 return DW_DLV_OK; 457 } 458