1 /* 2 3 Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. 4 Portions Copyright 2011-2017 David Anderson. All Rights Reserved. 5 Portions Copyright 2012 SN Systems Ltd. All rights reserved. 6 7 This program is free software; you can redistribute it 8 and/or modify it under the terms of version 2.1 of the 9 GNU Lesser General Public License as published by the Free 10 Software Foundation. 11 12 This program is distributed in the hope that it would be 13 useful, but WITHOUT ANY WARRANTY; without even the implied 14 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 15 PURPOSE. 16 17 Further, this software is distributed without any warranty 18 that it is free of the rightful claim of any third person 19 regarding infringement or the like. Any license provided 20 herein, whether implied or otherwise, applies only to this 21 software file. Patent licenses, if any, provided herein 22 do not apply to combinations of this program with other 23 software, or any other product whatsoever. 24 25 You should have received a copy of the GNU Lesser General 26 Public License along with this program; if not, write the 27 Free Software Foundation, Inc., 51 Franklin Street - Fifth 28 Floor, Boston MA 02110-1301, USA. 29 30 */ 31 32 #include "config.h" 33 #include "libdwarfdefs.h" 34 #include <stdio.h> 35 #include <string.h> 36 #include <limits.h> 37 #include "pro_incl.h" 38 #include <stddef.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_encode_nm.h" 45 #include "pro_frame.h" 46 47 #define SIZEOFT16 2 48 #define SIZEOFT32 4 49 #define SIZEOFT64 8 50 51 #ifdef WORDS_BIGENDIAN 52 #define ASNOUT(t,s,l) \ 53 do { \ 54 unsigned sbyte = 0; \ 55 const char *p = 0; \ 56 if (l > sizeof(s)) { \ 57 _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\ 58 return DW_DLV_ERROR; \ 59 } \ 60 sbyte = sizeof(s) - l; \ 61 p = (const char *)(&s); \ 62 dbg->de_copy_word(t,(const void *)(p+sbyte),l);\ 63 } while (0) 64 #else /* LITTLEENDIAN */ 65 #define ASNOUT(t,s,l) \ 66 do { \ 67 const char *p = 0; \ 68 if (l > sizeof(s)) { \ 69 _dwarf_p_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);\ 70 return DW_DLV_ERROR; \ 71 } \ 72 p = (const char *)(&s); \ 73 dbg->de_copy_word(t,(const void *)p,l); \ 74 } while (0) 75 #endif /* ENDIANNESS */ 76 77 78 static void _dwarf_pro_add_to_fde(Dwarf_P_Fde fde, 79 Dwarf_P_Frame_Pgm inst); 80 81 /* This function adds a cie struct to the debug pointer. Its in the 82 form of a linked list. 83 augmenter: string reps augmentation (implementation defined) 84 code_align: alignment of code 85 data_align: alignment of data 86 init_bytes: byts having initial instructions 87 init_n_bytes: number of bytes of initial instructions */ 88 89 90 Dwarf_Unsigned 91 dwarf_add_frame_cie(Dwarf_P_Debug dbg, 92 char *augmenter, 93 Dwarf_Small code_align, 94 Dwarf_Small data_align, 95 Dwarf_Small return_reg, 96 Dwarf_Ptr init_bytes, 97 Dwarf_Unsigned init_n_bytes, 98 Dwarf_Error * error) 99 { 100 Dwarf_Unsigned index = 0; 101 int res = 0; 102 103 res = dwarf_add_frame_cie_a(dbg,augmenter, code_align, 104 data_align,return_reg,init_bytes, 105 init_n_bytes, 106 &index,error); 107 if (res != DW_DLV_OK) { 108 return DW_DLV_NOCOUNT; 109 } 110 return index; 111 } 112 113 114 int 115 dwarf_add_frame_cie_a(Dwarf_P_Debug dbg, 116 char *augmenter, 117 Dwarf_Small code_align, 118 Dwarf_Small data_align, 119 Dwarf_Small return_reg, 120 Dwarf_Ptr init_bytes, 121 Dwarf_Unsigned init_n_bytes, 122 Dwarf_Unsigned * cie_index_out, 123 Dwarf_Error * error) 124 { 125 Dwarf_P_Cie curcie; 126 char *tmpaug = 0; 127 128 if (dbg->de_frame_cies == NULL) { 129 dbg->de_frame_cies = (Dwarf_P_Cie) 130 _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s)); 131 if (dbg->de_frame_cies == NULL) { 132 DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_ERROR); 133 } 134 curcie = dbg->de_frame_cies; 135 dbg->de_n_cie = 1; 136 dbg->de_last_cie = curcie; 137 } else { 138 curcie = dbg->de_last_cie; 139 curcie->cie_next = (Dwarf_P_Cie) 140 _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s)); 141 if (curcie->cie_next == NULL) { 142 DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_ERROR); 143 } 144 curcie = curcie->cie_next; 145 dbg->de_n_cie++; 146 dbg->de_last_cie = curcie; 147 } 148 curcie->cie_version = 1; 149 if (dbg->de_output_version > 2) { 150 curcie->cie_version = dbg->de_output_version; 151 } else { 152 /* V2 dwarf has debug_frame as version 1, there 153 is no 2 used in this section. */ 154 curcie->cie_version = 1; 155 } 156 tmpaug = (char *)_dwarf_p_get_alloc(dbg,strlen(augmenter)+1); 157 if (!tmpaug) { 158 DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_ERROR); 159 } 160 strcpy(tmpaug,augmenter); 161 curcie->cie_aug = tmpaug; 162 curcie->cie_code_align = code_align; 163 curcie->cie_data_align = data_align; 164 curcie->cie_ret_reg = return_reg; 165 curcie->cie_inst = (char *) init_bytes; 166 curcie->cie_inst_bytes = (long) init_n_bytes; 167 curcie->cie_next = NULL; 168 *cie_index_out = dbg->de_n_cie; 169 return DW_DLV_OK; 170 } 171 172 173 /* This functions adds a fde struct to the debug pointer. Its in the 174 form of a linked list. 175 die: subprogram/function die corresponding to this fde 176 cie: cie referred to by this fde, obtained from call to 177 add_frame_cie() routine. 178 virt_addr: beginning address 179 code_len: length of code reps by the fde */ 180 /*ARGSUSED*/ /* pretend all args used */ 181 Dwarf_Unsigned 182 dwarf_add_frame_fde(Dwarf_P_Debug dbg, 183 Dwarf_P_Fde fde, 184 Dwarf_P_Die die, 185 Dwarf_Unsigned cie, 186 Dwarf_Unsigned virt_addr, 187 Dwarf_Unsigned code_len, 188 Dwarf_Unsigned symidx, Dwarf_Error * error) 189 { 190 Dwarf_Unsigned index = 0; 191 int res = 0; 192 193 res = dwarf_add_frame_fde_c(dbg, fde, die, cie, virt_addr, 194 code_len, symidx, 0, 0,&index, error); 195 if (res != DW_DLV_OK) { 196 return DW_DLV_NOCOUNT; 197 } 198 return index; 199 } 200 201 /* There is no dwarf_add_frame_fde_a */ 202 /*ARGSUSED10*/ 203 Dwarf_Unsigned 204 dwarf_add_frame_fde_b(Dwarf_P_Debug dbg, 205 Dwarf_P_Fde fde, 206 Dwarf_P_Die die, 207 Dwarf_Unsigned cie, 208 Dwarf_Unsigned virt_addr, 209 Dwarf_Unsigned code_len, 210 Dwarf_Unsigned symidx, 211 Dwarf_Unsigned symidx_of_end, 212 Dwarf_Addr offset_from_end_sym, 213 Dwarf_Error * error) 214 { 215 Dwarf_Unsigned index = 0; 216 int res = 0; 217 218 res = dwarf_add_frame_fde_c(dbg,fde,die,cie, 219 virt_addr,code_len,symidx,symidx_of_end, 220 offset_from_end_sym,&index,error); 221 if (res != DW_DLV_OK) { 222 return DW_DLV_NOCOUNT; 223 } 224 return index; 225 } 226 227 /* New December 2018 */ 228 int 229 dwarf_add_frame_fde_c(Dwarf_P_Debug dbg, 230 Dwarf_P_Fde fde, 231 Dwarf_P_Die die, 232 Dwarf_Unsigned cie, 233 Dwarf_Unsigned virt_addr, 234 Dwarf_Unsigned code_len, 235 Dwarf_Unsigned symidx, 236 Dwarf_Unsigned symidx_of_end, 237 Dwarf_Addr offset_from_end_sym, 238 Dwarf_Unsigned *index_to_fde, 239 UNUSEDARG Dwarf_Error * error) 240 { 241 Dwarf_P_Fde curfde; 242 243 fde->fde_die = die; 244 fde->fde_cie = (long) cie; 245 fde->fde_initloc = virt_addr; 246 fde->fde_r_symidx = symidx; 247 fde->fde_addr_range = code_len; 248 fde->fde_offset_into_exception_tables = DW_DLX_NO_EH_OFFSET; 249 fde->fde_exception_table_symbol = 0; 250 fde->fde_end_symbol_offset = offset_from_end_sym; 251 fde->fde_end_symbol = symidx_of_end; 252 fde->fde_dbg = dbg; 253 254 curfde = dbg->de_last_fde; 255 if (curfde == NULL) { 256 dbg->de_frame_fdes = fde; 257 dbg->de_last_fde = fde; 258 dbg->de_n_fde = 1; 259 } else { 260 curfde->fde_next = fde; 261 dbg->de_last_fde = fde; 262 dbg->de_n_fde++; 263 } 264 *index_to_fde = dbg->de_n_fde; 265 return DW_DLV_OK; 266 } 267 268 /* This function adds information to an fde. The fde is 269 linked into the linked list of fde's maintained in the Dwarf_P_Debug 270 structure. 271 dbg: The debug descriptor. 272 fde: The fde to be added. 273 die: subprogram/function die corresponding to this fde 274 cie: cie referred to by this fde, obtained from call to 275 add_frame_cie() routine. 276 virt_addr: beginning address 277 code_len: length of code reps by the fde 278 symidx: The symbol id of the symbol wrt to which relocation needs 279 to be performed for 'virt_addr'. 280 offset_into_exception_tables: The start of exception tables for 281 this function (indicated as an offset into the exception 282 tables). A value of -1 indicates that there is no exception 283 table entries associated with this function. 284 exception_table_symbol: The symbol id of the section for exception 285 tables wrt to which the offset_into_exception_tables will 286 be relocated. */ 287 Dwarf_Unsigned 288 dwarf_add_frame_info(Dwarf_P_Debug dbg, 289 Dwarf_P_Fde fde, 290 Dwarf_P_Die die, 291 Dwarf_Unsigned cie, 292 Dwarf_Unsigned virt_addr, 293 Dwarf_Unsigned code_len, 294 Dwarf_Unsigned symidx, 295 Dwarf_Signed offset_into_exception_tables, 296 Dwarf_Unsigned exception_table_symbol, 297 Dwarf_Error * error) 298 { 299 Dwarf_Unsigned fde_index = 0; 300 int res = 0; 301 302 res = dwarf_add_frame_info_c(dbg, fde, die, cie, virt_addr, 303 code_len, symidx, 304 /* end_symbol */ 0, 305 /* offset_from_end */ 0, 306 offset_into_exception_tables, 307 exception_table_symbol, 308 &fde_index, error); 309 if (res != DW_DLV_OK) { 310 return DW_DLV_NOCOUNT; 311 } 312 return fde_index; 313 } 314 315 /*ARGSUSED*/ /* pretend all args used */ 316 Dwarf_Unsigned 317 dwarf_add_frame_info_b(Dwarf_P_Debug dbg, 318 Dwarf_P_Fde fde, 319 Dwarf_P_Die die, 320 Dwarf_Unsigned cie, 321 Dwarf_Unsigned virt_addr, 322 Dwarf_Unsigned code_len, 323 Dwarf_Unsigned symidx, 324 Dwarf_Unsigned end_symidx, 325 Dwarf_Unsigned offset_from_end_symbol, 326 Dwarf_Signed offset_into_exception_tables, 327 Dwarf_Unsigned exception_table_symbol, 328 UNUSEDARG Dwarf_Error * error) 329 { 330 Dwarf_Unsigned fde_index = 0; 331 int res = 0; 332 333 res = dwarf_add_frame_info_c(dbg, fde, die, cie, virt_addr, 334 code_len, symidx, end_symidx, 335 offset_from_end_symbol, 336 offset_into_exception_tables, 337 exception_table_symbol, 338 &fde_index, error); 339 if (res != DW_DLV_OK) { 340 return DW_DLV_NOCOUNT; 341 } 342 return fde_index; 343 } 344 345 int 346 dwarf_add_frame_info_c(Dwarf_P_Debug dbg, 347 Dwarf_P_Fde fde, 348 Dwarf_P_Die die, 349 Dwarf_Unsigned cie, 350 Dwarf_Unsigned virt_addr, 351 Dwarf_Unsigned code_len, 352 Dwarf_Unsigned symidx, 353 Dwarf_Unsigned end_symidx, 354 Dwarf_Unsigned offset_from_end_symbol, 355 Dwarf_Signed offset_into_exception_tables, 356 Dwarf_Unsigned exception_table_symbol, 357 Dwarf_Unsigned *fde_index_out, 358 UNUSEDARG Dwarf_Error * error) 359 { 360 Dwarf_P_Fde curfde; 361 362 fde->fde_die = die; 363 fde->fde_cie = (long) cie; 364 fde->fde_initloc = virt_addr; 365 fde->fde_r_symidx = symidx; 366 fde->fde_addr_range = code_len; 367 fde->fde_offset_into_exception_tables = 368 offset_into_exception_tables; 369 fde->fde_exception_table_symbol = exception_table_symbol; 370 fde->fde_end_symbol_offset = offset_from_end_symbol; 371 fde->fde_end_symbol = end_symidx; 372 fde->fde_dbg = dbg; 373 374 curfde = dbg->de_last_fde; 375 if (curfde == NULL) { 376 dbg->de_frame_fdes = fde; 377 dbg->de_last_fde = fde; 378 dbg->de_n_fde = 1; 379 } else { 380 curfde->fde_next = fde; 381 dbg->de_last_fde = fde; 382 dbg->de_n_fde++; 383 } 384 *fde_index_out = dbg->de_n_fde; 385 return DW_DLV_OK; 386 } 387 388 /* This is an alternate to inserting frame instructions 389 one instruction at a time. But use either this 390 or instruction level, not both in one fde. */ 391 int 392 dwarf_insert_fde_inst_bytes(Dwarf_P_Debug dbg, 393 Dwarf_P_Fde fde,Dwarf_Unsigned len, Dwarf_Ptr ibytes, 394 Dwarf_Error *error) 395 { 396 if (len == 0) { 397 return DW_DLV_OK; 398 } 399 if (fde->fde_block || fde->fde_inst) { 400 DWARF_P_DBG_ERROR(dbg, DW_DLE_DUPLICATE_INST_BLOCK, 401 DW_DLV_ERROR); 402 } 403 fde->fde_block = (Dwarf_Ptr)_dwarf_p_get_alloc(dbg, len); 404 memcpy(fde->fde_block,ibytes,len); 405 fde->fde_inst_block_size = len; 406 fde->fde_n_bytes += len; 407 return DW_DLV_OK; 408 } 409 410 411 412 /* Create a new fde. */ 413 Dwarf_P_Fde 414 dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error * error) 415 { 416 Dwarf_P_Fde fde = 0; 417 int res = 0; 418 419 res = dwarf_new_fde_a(dbg,&fde,error); 420 if (res != DW_DLV_OK) { 421 return (Dwarf_P_Fde) DW_DLV_BADADDR; 422 } 423 return fde; 424 } 425 int 426 dwarf_new_fde_a(Dwarf_P_Debug dbg, 427 Dwarf_P_Fde *fde_out, 428 Dwarf_Error * error) 429 { 430 Dwarf_P_Fde fde; 431 432 fde = (Dwarf_P_Fde) 433 _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Fde_s)); 434 if (fde == NULL) { 435 DWARF_P_DBG_ERROR(dbg, DW_DLE_FDE_ALLOC, DW_DLV_ERROR); 436 } 437 fde->fde_dbg = dbg; 438 fde->fde_uwordb_size = dbg->de_dwarf_offset_size; 439 *fde_out = fde; 440 return DW_DLV_OK; 441 } 442 443 444 /* Add a cfe_offset instruction to the fde passed in. */ 445 Dwarf_P_Fde 446 dwarf_fde_cfa_offset(Dwarf_P_Fde fde, 447 Dwarf_Unsigned reg, 448 Dwarf_Signed offset, 449 Dwarf_Error * error) 450 { 451 int res = 0; 452 453 res = dwarf_fde_cfa_offset_a(fde,reg,offset,error); 454 if (res != DW_DLV_OK) { 455 return (Dwarf_P_Fde) DW_DLV_BADADDR; 456 } 457 return fde; 458 } 459 460 461 int 462 dwarf_fde_cfa_offset_a(Dwarf_P_Fde fde, 463 Dwarf_Unsigned reg, 464 Dwarf_Signed offset, 465 Dwarf_Error * error) 466 { 467 Dwarf_Ubyte opc, regno; 468 char *ptr = 0; 469 Dwarf_P_Frame_Pgm curinst; 470 int nbytes = 0; 471 int res = 0; 472 char buff1[ENCODE_SPACE_NEEDED]; 473 Dwarf_P_Debug dbg = fde->fde_dbg; 474 475 curinst = (Dwarf_P_Frame_Pgm) 476 _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s)); 477 if (curinst == NULL) { 478 DWARF_P_DBG_ERROR(dbg, DW_DLE_FPGM_ALLOC, DW_DLV_ERROR); 479 } 480 opc = DW_CFA_offset; 481 regno = reg; 482 if (regno & 0xc0) { 483 DWARF_P_DBG_ERROR(dbg, DW_DLE_REGNO_OVFL,DW_DLV_ERROR); 484 } 485 opc = opc | regno; /* lower 6 bits are register number */ 486 curinst->dfp_opcode = opc; 487 res = _dwarf_pro_encode_leb128_nm(offset, &nbytes, 488 buff1, sizeof(buff1)); 489 if (res != DW_DLV_OK) { 490 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 491 return DW_DLV_ERROR; 492 } 493 ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); 494 if (ptr == NULL) { 495 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 496 return DW_DLV_ERROR; 497 } 498 memcpy(ptr, buff1, nbytes); 499 500 curinst->dfp_args = ptr; 501 curinst->dfp_nbytes = nbytes; 502 curinst->dfp_next = NULL; 503 504 _dwarf_pro_add_to_fde(fde, curinst); 505 return DW_DLV_OK; 506 } 507 508 /* Generic routine to add opcode to fde instructions. val1 and 509 val2 are parameters whose interpretation depends on the 'op'. 510 511 This does not work properly for DW_DLC_SYMBOLIC_RELOCATIONS 512 for DW_CFA_set_loc or DW_DVA_advance_loc* 'op', as 513 these ops normally are addresses or (DW_CFA_set_loc) 514 or code lengths (DW_DVA_advance_loc*) and such must be 515 represented with relocations and symbol indices for 516 DW_DLC_SYMBOLIC_RELOCATIONS. 517 518 This does not treat all DW_CFA instructions yet. 519 520 For certain operations a val? value must be 521 signed (though passed in as unsigned here). 522 523 Does not check that the frame 524 version is 3(for dwarf3) or 4 (for dwarf4) or 5 525 when applying operations that are only valid for 526 particular versions. */ 527 Dwarf_P_Fde 528 dwarf_add_fde_inst(Dwarf_P_Fde fde, 529 Dwarf_Small op, 530 Dwarf_Unsigned val1, 531 Dwarf_Unsigned val2, Dwarf_Error * error) 532 { 533 int res = 0; 534 535 res = dwarf_add_fde_inst_a(fde,op,val1,val2,error); 536 if (res != DW_DLV_OK) { 537 return ((Dwarf_P_Fde) DW_DLV_BADADDR); 538 } 539 return fde; 540 } 541 542 /* December 2018. A more sensible return value. */ 543 int 544 dwarf_add_fde_inst_a(Dwarf_P_Fde fde, 545 Dwarf_Small op, 546 Dwarf_Unsigned val1, 547 Dwarf_Unsigned val2, 548 Dwarf_Error * error) 549 { 550 Dwarf_P_Frame_Pgm curinst; 551 int nbytes = 0; 552 int nbytes1 = 0; 553 int nbytes2 = 0; 554 Dwarf_Ubyte db = 0; 555 Dwarf_Half dh = 0; 556 Dwarf_Unsigned du = 0; 557 char *ptr = 0; 558 int res = 0; 559 char buff1[ENCODE_SPACE_NEEDED]; 560 char buff2[ENCODE_SPACE_NEEDED]; 561 Dwarf_P_Debug dbg = fde->fde_dbg; 562 /* This is a hack telling the code when to transform 563 a value to a signed leb number. */ 564 int signed_second = 0; 565 int signed_first = 0; 566 567 568 buff1[0] = 0; 569 buff2[0] = 0; 570 curinst = (Dwarf_P_Frame_Pgm) 571 _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s)); 572 if (curinst == NULL) { 573 _dwarf_p_error(dbg, error, DW_DLE_FPGM_ALLOC); 574 return DW_DLV_ERROR; 575 } 576 switch (op) { 577 578 case DW_CFA_advance_loc: { 579 if (val1 <= 0x3f) { 580 db = val1; 581 op |= db; 582 } else if (!(val1& ~0xff)) { 583 op = DW_CFA_advance_loc1; 584 db = val1; 585 ptr = (char *) _dwarf_p_get_alloc(dbg, 1); 586 if (ptr == NULL) { 587 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 588 return DW_DLV_ERROR; 589 } 590 memcpy((void *) ptr, (const void *) &db, 1); 591 nbytes = 1; 592 } else if (!(val1& (~(Dwarf_Unsigned)0xffff))) { 593 if (sizeof(dh) < SIZEOFT16) { 594 _dwarf_p_error(dbg, error, 595 DW_DLE_DEBUG_FRAME_LENGTH_BAD); 596 return DW_DLV_ERROR; 597 } 598 op = DW_CFA_advance_loc2; 599 dh = val1; 600 ptr = (char *) _dwarf_p_get_alloc(dbg, SIZEOFT16); 601 if (ptr == NULL) { 602 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 603 return DW_DLV_ERROR; 604 } 605 /* No byte swapping, assuming running at 606 target endianness. */ 607 ASNOUT((void *) ptr, dh, SIZEOFT16); 608 nbytes = SIZEOFT16; 609 } else if (!(val1& ~(Dwarf_Unsigned)0xffffffff)) { 610 if (sizeof(du) < SIZEOFT32) { 611 _dwarf_p_error(dbg, error, 612 DW_DLE_DEBUG_FRAME_LENGTH_BAD); 613 return DW_DLV_ERROR; 614 } 615 op = DW_CFA_advance_loc4; 616 du = val1; 617 ptr = (char *) _dwarf_p_get_alloc(dbg, SIZEOFT32); 618 if (ptr == NULL) { 619 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 620 return DW_DLV_ERROR; 621 } 622 ASNOUT((void *) ptr, du, SIZEOFT32); 623 nbytes = SIZEOFT32; 624 } else { 625 if (sizeof(du) < SIZEOFT64) { 626 _dwarf_p_error(dbg, error, 627 DW_DLE_DEBUG_FRAME_LENGTH_BAD); 628 return DW_DLV_ERROR; 629 } 630 op = DW_CFA_MIPS_advance_loc8; 631 du = val1; 632 ptr = (char *) _dwarf_p_get_alloc(dbg, 633 SIZEOFT64); 634 if (ptr == NULL) { 635 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 636 return DW_DLV_ERROR; 637 } 638 /* No byte swapping, assuming running at 639 target endianness. */ 640 ASNOUT((void *) ptr, du, SIZEOFT64); 641 nbytes = SIZEOFT64; 642 } 643 break; 644 } 645 case DW_CFA_offset: 646 if (val1 <= MAX_6_BIT_VALUE) { 647 db = val1; 648 op |= db; 649 res = _dwarf_pro_encode_leb128_nm(val2, &nbytes, 650 buff1, sizeof(buff1)); 651 if (res != DW_DLV_OK) { 652 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 653 return DW_DLV_ERROR; 654 } 655 ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); 656 if (ptr == NULL) { 657 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 658 return DW_DLV_ERROR; 659 } 660 memcpy(ptr, buff1, nbytes); 661 662 } else { 663 op = DW_CFA_offset_extended; 664 goto two_leb; 665 } 666 break; 667 case DW_CFA_offset_extended_sf: /* DWARF3 */ 668 signed_second = 1; 669 goto two_leb; 670 case DW_CFA_offset_extended: 671 goto two_leb; 672 673 case DW_CFA_undefined: 674 case DW_CFA_same_value: 675 goto one_leb; 676 677 case DW_CFA_val_offset: 678 goto two_leb; 679 case DW_CFA_val_offset_sf: 680 signed_second = 1; 681 goto two_leb; 682 case DW_CFA_def_cfa_sf: 683 signed_second = 1; 684 goto two_leb; 685 case DW_CFA_register: 686 case DW_CFA_def_cfa: 687 two_leb: 688 res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1, 689 buff1, sizeof(buff1)); 690 if (res != DW_DLV_OK) { 691 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 692 return DW_DLV_ERROR; 693 } 694 if (!signed_second) { 695 res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2, 696 buff2, sizeof(buff2)); 697 } else { 698 Dwarf_Signed val2s = val2; 699 res = _dwarf_pro_encode_signed_leb128_nm(val2s, &nbytes2, 700 buff2, sizeof(buff2)); 701 } 702 if (res != DW_DLV_OK) { 703 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 704 return DW_DLV_ERROR; 705 } 706 707 res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2, 708 buff2, sizeof(buff2)); 709 if (res != DW_DLV_OK) { 710 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 711 return DW_DLV_ERROR; 712 } 713 714 ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes1 + nbytes2); 715 if (ptr == NULL) { 716 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 717 return DW_DLV_ERROR; 718 } 719 memcpy(ptr, buff1, nbytes1); 720 memcpy(ptr + nbytes1, buff2, nbytes2); 721 nbytes = nbytes1 + nbytes2; 722 break; 723 724 case DW_CFA_def_cfa_offset_sf: /* DWARF3 */ 725 signed_first = 1; 726 goto one_leb; 727 case DW_CFA_def_cfa_register: 728 case DW_CFA_def_cfa_offset: 729 one_leb: 730 if (!signed_first) { 731 res = _dwarf_pro_encode_leb128_nm(val1, &nbytes, 732 buff1, sizeof(buff1)); 733 } else { 734 Dwarf_Signed val1s = val1; 735 res = _dwarf_pro_encode_signed_leb128_nm(val1s, &nbytes, 736 buff1, sizeof(buff1)); 737 } 738 if (res != DW_DLV_OK) { 739 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 740 return DW_DLV_ERROR; 741 } 742 ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); 743 if (ptr == NULL) { 744 _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 745 return DW_DLV_ERROR; 746 } 747 memcpy(ptr, buff1, nbytes); 748 break; 749 case DW_CFA_def_cfa_expression: /* DWARF3 */ 750 /* FIXME: argument is dwarf expr, not handled yet. */ 751 case DW_CFA_expression: /* DWARF3 */ 752 /* First arg: ULEB reg num. 2nd arg dwarf expr in form block. 753 FIXME: not handled yet. */ 754 case DW_CFA_val_expression: /* DWARF3f */ 755 /* First arg: ULEB reg num. 2nd arg dwarf expr in form block. 756 FIXME: not handled yet. */ 757 default: 758 _dwarf_p_error(dbg, error, DW_DLE_DEBUGFRAME_ERROR); 759 return DW_DLV_ERROR; 760 } 761 762 curinst->dfp_opcode = op; 763 curinst->dfp_args = ptr; 764 curinst->dfp_nbytes = nbytes; 765 curinst->dfp_next = NULL; 766 _dwarf_pro_add_to_fde(fde, curinst); 767 return DW_DLV_OK; 768 } 769 770 771 /* Instructions are added to an fde in the form of a linked 772 list. This function manages the linked list. */ 773 void 774 _dwarf_pro_add_to_fde(Dwarf_P_Fde fde, Dwarf_P_Frame_Pgm curinst) 775 { 776 if (fde->fde_last_inst) { 777 fde->fde_last_inst->dfp_next = curinst; 778 fde->fde_last_inst = curinst; 779 fde->fde_n_inst++; 780 fde->fde_n_bytes += 781 (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte)); 782 } else { 783 fde->fde_last_inst = curinst; 784 fde->fde_inst = curinst; 785 fde->fde_n_inst = 1; 786 fde->fde_n_bytes = 787 (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte)); 788 } 789 } 790