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