1 /* 2 3 Copyright (C) 2000 Silicon Graphics, Inc. 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., 59 Temple Place - Suite 330, Boston MA 02111-1307, 23 USA. 24 25 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 26 Mountain View, CA 94043, or: 27 28 http://www.sgi.com 29 30 For further information regarding this notice, see: 31 32 http://oss.sgi.com/projects/GenInfo/NoticeExplan 33 34 */ 35 36 37 38 #include "config.h" 39 #include "libdwarfdefs.h" 40 #include <stdio.h> 41 #include <string.h> 42 #include <sys/types.h> 43 #include "pro_incl.h" 44 #include "pro_expr.h" 45 46 /* 47 This function creates a new expression 48 struct that can be used to build up a 49 location expression. 50 */ 51 Dwarf_P_Expr 52 dwarf_new_expr(Dwarf_P_Debug dbg, Dwarf_Error * error) 53 { 54 Dwarf_P_Expr ret_expr; 55 56 if (dbg == NULL) { 57 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 58 return (NULL); 59 } 60 61 ret_expr = (Dwarf_P_Expr) 62 _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Expr_s)); 63 if (ret_expr == NULL) { 64 _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 65 return (NULL); 66 } 67 68 ret_expr->ex_dbg = dbg; 69 70 return (ret_expr); 71 } 72 73 74 Dwarf_Unsigned 75 dwarf_add_expr_gen(Dwarf_P_Expr expr, 76 Dwarf_Small opcode, 77 Dwarf_Unsigned val1, 78 Dwarf_Unsigned val2, Dwarf_Error * error) 79 { 80 char encode_buffer[2 * ENCODE_SPACE_NEEDED]; /* 2* since 81 used to 82 concatenate 83 2 leb's 84 below */ 85 char encode_buffer2[ENCODE_SPACE_NEEDED]; 86 int res; 87 Dwarf_P_Debug dbg = expr->ex_dbg; 88 89 /* 90 Give the buffer where the operands are first going to be 91 assembled the largest alignment. */ 92 Dwarf_Unsigned operand_buffer[10]; 93 94 /* 95 Size of the byte stream buffer that needs to be memcpy-ed. */ 96 int operand_size; 97 98 /* 99 Points to the byte stream for the first operand, and finally to 100 the buffer that is memcp-ed into the Dwarf_P_Expr_s struct. */ 101 Dwarf_Small *operand; 102 103 /* Size of the byte stream for second operand. */ 104 int operand2_size; 105 106 /* Points to next byte to be written in Dwarf_P_Expr_s struct. */ 107 Dwarf_Small *next_byte_ptr; 108 109 /* Offset past the last byte written into Dwarf_P_Expr_s. */ 110 int next_byte_offset; 111 112 /* ***** BEGIN CODE ***** */ 113 114 if (expr == NULL) { 115 _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); 116 return (DW_DLV_NOCOUNT); 117 } 118 119 if (expr->ex_dbg == NULL) { 120 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 121 return (DW_DLV_NOCOUNT); 122 } 123 124 operand = NULL; 125 operand_size = 0; 126 127 switch (opcode) { 128 case DW_OP_reg0: 129 case DW_OP_reg1: 130 case DW_OP_reg2: 131 case DW_OP_reg3: 132 case DW_OP_reg4: 133 case DW_OP_reg5: 134 case DW_OP_reg6: 135 case DW_OP_reg7: 136 case DW_OP_reg8: 137 case DW_OP_reg9: 138 case DW_OP_reg10: 139 case DW_OP_reg11: 140 case DW_OP_reg12: 141 case DW_OP_reg13: 142 case DW_OP_reg14: 143 case DW_OP_reg15: 144 case DW_OP_reg16: 145 case DW_OP_reg17: 146 case DW_OP_reg18: 147 case DW_OP_reg19: 148 case DW_OP_reg20: 149 case DW_OP_reg21: 150 case DW_OP_reg22: 151 case DW_OP_reg23: 152 case DW_OP_reg24: 153 case DW_OP_reg25: 154 case DW_OP_reg26: 155 case DW_OP_reg27: 156 case DW_OP_reg28: 157 case DW_OP_reg29: 158 case DW_OP_reg30: 159 case DW_OP_reg31: 160 break; 161 162 case DW_OP_breg0: 163 case DW_OP_breg1: 164 case DW_OP_breg2: 165 case DW_OP_breg3: 166 case DW_OP_breg4: 167 case DW_OP_breg5: 168 case DW_OP_breg6: 169 case DW_OP_breg7: 170 case DW_OP_breg8: 171 case DW_OP_breg9: 172 case DW_OP_breg10: 173 case DW_OP_breg11: 174 case DW_OP_breg12: 175 case DW_OP_breg13: 176 case DW_OP_breg14: 177 case DW_OP_breg15: 178 case DW_OP_breg16: 179 case DW_OP_breg17: 180 case DW_OP_breg18: 181 case DW_OP_breg19: 182 case DW_OP_breg20: 183 case DW_OP_breg21: 184 case DW_OP_breg22: 185 case DW_OP_breg23: 186 case DW_OP_breg24: 187 case DW_OP_breg25: 188 case DW_OP_breg26: 189 case DW_OP_breg27: 190 case DW_OP_breg28: 191 case DW_OP_breg29: 192 case DW_OP_breg30: 193 case DW_OP_breg31: 194 res = _dwarf_pro_encode_signed_leb128_nm(val1, 195 &operand_size, 196 encode_buffer, 197 sizeof(encode_buffer)); 198 if (res != DW_DLV_OK) { 199 _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 200 return (DW_DLV_NOCOUNT); 201 } 202 operand = (Dwarf_Small *) encode_buffer; 203 break; 204 205 case DW_OP_regx: 206 res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, 207 encode_buffer, 208 sizeof(encode_buffer)); 209 if (res != DW_DLV_OK) { 210 _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 211 return (DW_DLV_NOCOUNT); 212 } 213 operand = (Dwarf_Small *) encode_buffer; 214 break; 215 216 case DW_OP_lit0: 217 case DW_OP_lit1: 218 case DW_OP_lit2: 219 case DW_OP_lit3: 220 case DW_OP_lit4: 221 case DW_OP_lit5: 222 case DW_OP_lit6: 223 case DW_OP_lit7: 224 case DW_OP_lit8: 225 case DW_OP_lit9: 226 case DW_OP_lit10: 227 case DW_OP_lit11: 228 case DW_OP_lit12: 229 case DW_OP_lit13: 230 case DW_OP_lit14: 231 case DW_OP_lit15: 232 case DW_OP_lit16: 233 case DW_OP_lit17: 234 case DW_OP_lit18: 235 case DW_OP_lit19: 236 case DW_OP_lit20: 237 case DW_OP_lit21: 238 case DW_OP_lit22: 239 case DW_OP_lit23: 240 case DW_OP_lit24: 241 case DW_OP_lit25: 242 case DW_OP_lit26: 243 case DW_OP_lit27: 244 case DW_OP_lit28: 245 case DW_OP_lit29: 246 case DW_OP_lit30: 247 case DW_OP_lit31: 248 break; 249 250 case DW_OP_addr: 251 _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE); 252 return (DW_DLV_NOCOUNT); 253 254 case DW_OP_const1u: 255 case DW_OP_const1s: 256 operand = (Dwarf_Small *) & operand_buffer[0]; 257 WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 1); 258 operand_size = 1; 259 break; 260 261 case DW_OP_const2u: 262 case DW_OP_const2s: 263 operand = (Dwarf_Small *) & operand_buffer[0]; 264 WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 2); 265 operand_size = 2; 266 break; 267 268 case DW_OP_const4u: 269 case DW_OP_const4s: 270 operand = (Dwarf_Small *) & operand_buffer[0]; 271 WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 4); 272 operand_size = 4; 273 break; 274 275 case DW_OP_const8u: 276 case DW_OP_const8s: 277 operand = (Dwarf_Small *) & operand_buffer[0]; 278 WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 8); 279 operand_size = 8; 280 break; 281 282 case DW_OP_constu: 283 res = _dwarf_pro_encode_leb128_nm(val1, 284 &operand_size, 285 encode_buffer, 286 sizeof(encode_buffer)); 287 if (res != DW_DLV_OK) { 288 _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 289 return (DW_DLV_NOCOUNT); 290 } 291 operand = (Dwarf_Small *) encode_buffer; 292 break; 293 294 case DW_OP_consts: 295 res = _dwarf_pro_encode_signed_leb128_nm(val1, 296 &operand_size, 297 encode_buffer, 298 sizeof(encode_buffer)); 299 if (res != DW_DLV_OK) { 300 _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 301 return (DW_DLV_NOCOUNT); 302 } 303 operand = (Dwarf_Small *) encode_buffer; 304 break; 305 306 case DW_OP_fbreg: 307 res = _dwarf_pro_encode_signed_leb128_nm(val1, 308 &operand_size, 309 encode_buffer, 310 sizeof(encode_buffer)); 311 if (res != DW_DLV_OK) { 312 _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 313 return (DW_DLV_NOCOUNT); 314 } 315 operand = (Dwarf_Small *) encode_buffer; 316 break; 317 318 case DW_OP_bregx: 319 res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, 320 encode_buffer, 321 sizeof(encode_buffer)); 322 if (res != DW_DLV_OK) { 323 _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 324 return (DW_DLV_NOCOUNT); 325 } 326 operand = (Dwarf_Small *) encode_buffer; 327 /* put this one directly into 'operand' at tail of prev value */ 328 res = _dwarf_pro_encode_signed_leb128_nm(val2, &operand2_size, 329 ((char *) operand) + 330 operand_size, 331 sizeof 332 (encode_buffer2)); 333 if (res != DW_DLV_OK) { 334 _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 335 return (DW_DLV_NOCOUNT); 336 } 337 operand_size += operand2_size; 338 339 case DW_OP_dup: 340 case DW_OP_drop: 341 break; 342 343 case DW_OP_pick: 344 operand = (Dwarf_Small *) & operand_buffer[0]; 345 /* Cast of val1 to pointer is ok as if val1 does not point into 346 our (process) address space we are in big trouble anyway 347 (internal error in libdwarf or in libdwarf caller). Compiler 348 may warn about cast to pointer. */ 349 WRITE_UNALIGNED(dbg, operand, (const void *)(uintptr_t)val1, 350 sizeof(val1), 1); 351 operand_size = 1; 352 break; 353 354 case DW_OP_over: 355 case DW_OP_swap: 356 case DW_OP_rot: 357 case DW_OP_deref: 358 case DW_OP_xderef: 359 break; 360 361 case DW_OP_deref_size: 362 case DW_OP_xderef_size: 363 operand = (Dwarf_Small *) & operand_buffer[0]; 364 /* Cast of val1 to pointer is ok as if val1 does not point into 365 our (process) address space we are in big trouble anyway 366 (internal error in libdwarf or in libdwarf caller). Compiler 367 may warn about cast to pointer. */ 368 WRITE_UNALIGNED(dbg, operand, (const void *)(uintptr_t) val1, 369 sizeof(val1), 1); 370 operand_size = 1; 371 break; 372 373 case DW_OP_abs: 374 case DW_OP_and: 375 case DW_OP_div: 376 case DW_OP_minus: 377 case DW_OP_mod: 378 case DW_OP_mul: 379 case DW_OP_neg: 380 case DW_OP_not: 381 case DW_OP_or: 382 case DW_OP_plus: 383 break; 384 385 case DW_OP_plus_uconst: 386 res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, 387 encode_buffer, 388 sizeof(encode_buffer)); 389 if (res != DW_DLV_OK) { 390 _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 391 return (DW_DLV_NOCOUNT); 392 } 393 operand = (Dwarf_Small *) encode_buffer; 394 break; 395 396 case DW_OP_shl: 397 case DW_OP_shr: 398 case DW_OP_shra: 399 case DW_OP_xor: 400 break; 401 402 case DW_OP_le: 403 case DW_OP_ge: 404 case DW_OP_eq: 405 case DW_OP_lt: 406 case DW_OP_gt: 407 case DW_OP_ne: 408 break; 409 410 case DW_OP_skip: 411 case DW_OP_bra: 412 /* FIX: unhandled! OP_bra, OP_skip! */ 413 _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE); 414 return (DW_DLV_NOCOUNT); 415 416 case DW_OP_piece: 417 res = _dwarf_pro_encode_leb128_nm(val1, &operand_size, 418 encode_buffer, 419 sizeof(encode_buffer)); 420 if (res != DW_DLV_OK) { 421 _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 422 return (DW_DLV_NOCOUNT); 423 } 424 operand = (Dwarf_Small *) encode_buffer; 425 break; 426 427 case DW_OP_nop: 428 break; 429 430 default: 431 _dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE); 432 return (DW_DLV_NOCOUNT); 433 } 434 435 next_byte_offset = expr->ex_next_byte_offset + operand_size + 1; 436 437 if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) { 438 _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD); 439 return (DW_DLV_NOCOUNT); 440 } 441 442 next_byte_ptr = 443 &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset; 444 445 *next_byte_ptr = opcode; 446 next_byte_ptr++; 447 memcpy(next_byte_ptr, operand, operand_size); 448 449 expr->ex_next_byte_offset = next_byte_offset; 450 return (next_byte_offset); 451 } 452 453 Dwarf_Unsigned 454 dwarf_add_expr_addr_b(Dwarf_P_Expr expr, 455 Dwarf_Unsigned addr, 456 Dwarf_Unsigned sym_index, Dwarf_Error * error) 457 { 458 Dwarf_P_Debug dbg; 459 Dwarf_Small *next_byte_ptr; 460 Dwarf_Unsigned next_byte_offset; 461 int upointer_size; 462 463 if (expr == NULL) { 464 _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); 465 return (DW_DLV_NOCOUNT); 466 } 467 468 dbg = expr->ex_dbg; 469 if (dbg == NULL) { 470 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 471 return (DW_DLV_NOCOUNT); 472 } 473 474 upointer_size = dbg->de_pointer_size; 475 next_byte_offset = expr->ex_next_byte_offset + upointer_size + 1; 476 if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) { 477 _dwarf_p_error(dbg, error, DW_DLE_EXPR_LENGTH_BAD); 478 return (DW_DLV_NOCOUNT); 479 } 480 481 next_byte_ptr = 482 &(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset; 483 484 *next_byte_ptr = DW_OP_addr; 485 next_byte_ptr++; 486 WRITE_UNALIGNED(dbg, next_byte_ptr, (const void *) &addr, 487 sizeof(addr), upointer_size); 488 489 if (expr->ex_reloc_offset != 0) { 490 _dwarf_p_error(dbg, error, DW_DLE_MULTIPLE_RELOC_IN_EXPR); 491 return (DW_DLV_NOCOUNT); 492 } 493 494 expr->ex_reloc_sym_index = sym_index; 495 expr->ex_reloc_offset = expr->ex_next_byte_offset + 1; 496 497 expr->ex_next_byte_offset = next_byte_offset; 498 return (next_byte_offset); 499 } 500 501 Dwarf_Unsigned 502 dwarf_add_expr_addr(Dwarf_P_Expr expr, 503 Dwarf_Unsigned addr, 504 Dwarf_Signed sym_index, Dwarf_Error * error) 505 { 506 return 507 dwarf_add_expr_addr_b(expr, addr, (Dwarf_Unsigned) sym_index, 508 error); 509 } 510 511 512 Dwarf_Unsigned 513 dwarf_expr_current_offset(Dwarf_P_Expr expr, Dwarf_Error * error) 514 { 515 if (expr == NULL) { 516 _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); 517 return (DW_DLV_NOCOUNT); 518 } 519 520 if (expr->ex_dbg == NULL) { 521 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 522 return (DW_DLV_NOCOUNT); 523 } 524 525 return (expr->ex_next_byte_offset); 526 } 527 528 529 Dwarf_Addr 530 dwarf_expr_into_block(Dwarf_P_Expr expr, 531 Dwarf_Unsigned * length, Dwarf_Error * error) 532 { 533 if (expr == NULL) { 534 _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL); 535 return (DW_DLV_BADADDR); 536 } 537 538 if (expr->ex_dbg == NULL) { 539 _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 540 return (DW_DLV_BADADDR); 541 } 542 543 if (length != NULL) 544 *length = expr->ex_next_byte_offset; 545 /* The following cast from pointer to integer is ok as long as 546 Dwarf_Addr is at least as large as a pointer. Which is a 547 requirement of libdwarf so must be satisfied (some compilers 548 emit a warning about the following line). */ 549 return ((Dwarf_Addr)(uintptr_t) &(expr->ex_byte_stream[0])); 550 } 551