xref: /titanic_41/usr/src/tools/ctf/dwarf/common/pro_expr.c (revision 26f3cdf03f1adcc98f6d3d99843ee71e9229a8c0)
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