Sync usage with man page.
[netbsd-mini2440.git] / external / bsd / libdwarf / dist / dwarf_loc.c
blob502aff3a66fe07d025458b3f48b9ad8d4a67424a
1 /* $NetBSD$ */
3 /*-
4 * Copyright (c) 2007 John Birrell (jb@freebsd.org)
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
28 * $FreeBSD: src/lib/libdwarf/dwarf_loc.c,v 1.2.2.1 2009/08/03 08:13:06 kensmith Exp $
31 #include <stdlib.h>
32 #include "_libdwarf.h"
34 static int64_t
35 dwarf_decode_sleb128(uint8_t **dp)
37 int64_t ret = 0;
38 uint8_t b;
39 int shift = 0;
41 uint8_t *src = *dp;
43 do {
44 b = *src++;
46 ret |= ((b & 0x7f) << shift);
48 shift += 7;
49 } while ((b & 0x80) != 0);
51 if (shift < 32 && (b & 0x40) != 0)
52 ret |= (-1 << shift);
54 *dp = src;
56 return ret;
59 static uint64_t
60 dwarf_decode_uleb128(uint8_t **dp)
62 uint64_t ret = 0;
63 uint8_t b;
64 int shift = 0;
66 uint8_t *src = *dp;
68 do {
69 b = *src++;
71 ret |= ((b & 0x7f) << shift);
73 shift += 7;
74 } while ((b & 0x80) != 0);
76 *dp = src;
78 return ret;
82 * Given an array of bytes of length 'len' representing a
83 * DWARF expression, compute the number of operations based
84 * on there being one byte describing the operation and
85 * zero or more bytes of operands as defined in the standard
86 * for each operation type.
88 int
89 dwarf_op_num(uint8_t pointer_size, uint8_t *p, int len)
91 int count = 0;
92 int64_t sval;
93 uint64_t uval;
94 uint8_t *last = p + len;
97 * Process each byte. If an error occurs, then the
98 * count will be set to -1.
100 while (p < last && count >= 0) {
101 count++;
103 switch (*p++) {
104 /* Operations with no operands. */
105 case DW_OP_deref:
106 case DW_OP_reg0:
107 case DW_OP_reg1:
108 case DW_OP_reg2:
109 case DW_OP_reg3:
110 case DW_OP_reg4:
111 case DW_OP_reg5:
112 case DW_OP_reg6:
113 case DW_OP_reg7:
114 case DW_OP_reg8:
115 case DW_OP_reg9:
116 case DW_OP_reg10:
117 case DW_OP_reg11:
118 case DW_OP_reg12:
119 case DW_OP_reg13:
120 case DW_OP_reg14:
121 case DW_OP_reg15:
122 case DW_OP_reg16:
123 case DW_OP_reg17:
124 case DW_OP_reg18:
125 case DW_OP_reg19:
126 case DW_OP_reg20:
127 case DW_OP_reg21:
128 case DW_OP_reg22:
129 case DW_OP_reg23:
130 case DW_OP_reg24:
131 case DW_OP_reg25:
132 case DW_OP_reg26:
133 case DW_OP_reg27:
134 case DW_OP_reg28:
135 case DW_OP_reg29:
136 case DW_OP_reg30:
137 case DW_OP_reg31:
139 case DW_OP_lit0:
140 case DW_OP_lit1:
141 case DW_OP_lit2:
142 case DW_OP_lit3:
143 case DW_OP_lit4:
144 case DW_OP_lit5:
145 case DW_OP_lit6:
146 case DW_OP_lit7:
147 case DW_OP_lit8:
148 case DW_OP_lit9:
149 case DW_OP_lit10:
150 case DW_OP_lit11:
151 case DW_OP_lit12:
152 case DW_OP_lit13:
153 case DW_OP_lit14:
154 case DW_OP_lit15:
155 case DW_OP_lit16:
156 case DW_OP_lit17:
157 case DW_OP_lit18:
158 case DW_OP_lit19:
159 case DW_OP_lit20:
160 case DW_OP_lit21:
161 case DW_OP_lit22:
162 case DW_OP_lit23:
163 case DW_OP_lit24:
164 case DW_OP_lit25:
165 case DW_OP_lit26:
166 case DW_OP_lit27:
167 case DW_OP_lit28:
168 case DW_OP_lit29:
169 case DW_OP_lit30:
170 case DW_OP_lit31:
172 case DW_OP_dup:
173 case DW_OP_drop:
175 case DW_OP_over:
177 case DW_OP_swap:
178 case DW_OP_rot:
179 case DW_OP_xderef:
181 case DW_OP_abs:
182 case DW_OP_and:
183 case DW_OP_div:
184 case DW_OP_minus:
185 case DW_OP_mod:
186 case DW_OP_mul:
187 case DW_OP_neg:
188 case DW_OP_not:
189 case DW_OP_or:
190 case DW_OP_plus:
192 case DW_OP_shl:
193 case DW_OP_shr:
194 case DW_OP_shra:
195 case DW_OP_xor:
197 case DW_OP_eq:
198 case DW_OP_ge:
199 case DW_OP_gt:
200 case DW_OP_le:
201 case DW_OP_lt:
202 case DW_OP_ne:
204 case DW_OP_nop:
205 break;
207 /* Operations with 1-byte operands. */
208 case DW_OP_const1u:
209 case DW_OP_const1s:
210 case DW_OP_pick:
211 case DW_OP_deref_size:
212 case DW_OP_xderef_size:
213 p++;
214 break;
216 /* Operations with 2-byte operands. */
217 case DW_OP_const2u:
218 case DW_OP_const2s:
219 case DW_OP_bra:
220 case DW_OP_skip:
221 p += 2;
222 break;
224 /* Operations with 4-byte operands. */
225 case DW_OP_const4u:
226 case DW_OP_const4s:
227 p += 4;
228 break;
230 /* Operations with 8-byte operands. */
231 case DW_OP_const8u:
232 case DW_OP_const8s:
233 p += 8;
234 break;
236 /* Operations with an unsigned LEB128 operand. */
237 case DW_OP_constu:
238 case DW_OP_plus_uconst:
239 case DW_OP_regx:
240 case DW_OP_piece:
241 uval = dwarf_decode_uleb128(&p);
242 break;
244 /* Operations with a signed LEB128 operand. */
245 case DW_OP_consts:
246 case DW_OP_breg0:
247 case DW_OP_breg1:
248 case DW_OP_breg2:
249 case DW_OP_breg3:
250 case DW_OP_breg4:
251 case DW_OP_breg5:
252 case DW_OP_breg6:
253 case DW_OP_breg7:
254 case DW_OP_breg8:
255 case DW_OP_breg9:
256 case DW_OP_breg10:
257 case DW_OP_breg11:
258 case DW_OP_breg12:
259 case DW_OP_breg13:
260 case DW_OP_breg14:
261 case DW_OP_breg15:
262 case DW_OP_breg16:
263 case DW_OP_breg17:
264 case DW_OP_breg18:
265 case DW_OP_breg19:
266 case DW_OP_breg20:
267 case DW_OP_breg21:
268 case DW_OP_breg22:
269 case DW_OP_breg23:
270 case DW_OP_breg24:
271 case DW_OP_breg25:
272 case DW_OP_breg26:
273 case DW_OP_breg27:
274 case DW_OP_breg28:
275 case DW_OP_breg29:
276 case DW_OP_breg30:
277 case DW_OP_breg31:
278 case DW_OP_fbreg:
279 sval = dwarf_decode_sleb128(&p);
280 break;
283 * Operations with an unsigned LEB128 operand
284 * followed by a signed LEB128 operand.
286 case DW_OP_bregx:
287 uval = dwarf_decode_uleb128(&p);
288 sval = dwarf_decode_sleb128(&p);
289 break;
291 /* Target address size operand. */
292 case DW_OP_addr:
293 p += pointer_size;
294 break;
296 /* All other operations cause an error. */
297 default:
298 count = -1;
299 break;
303 return count;
306 static int
307 dwarf_loc_fill(Dwarf_Locdesc *lbuf, uint8_t pointer_size, uint8_t *p, int len)
309 int count = 0;
310 int ret = DWARF_E_NONE;
311 uint64_t operand1;
312 uint64_t operand2;
313 uint8_t *last = p + len;
316 * Process each byte. If an error occurs, then the
317 * count will be set to -1.
319 while (p < last && ret == DWARF_E_NONE) {
320 operand1 = 0;
321 operand2 = 0;
323 lbuf->ld_s[count].lr_atom = *p;
325 switch (*p++) {
326 /* Operations with no operands. */
327 case DW_OP_deref:
328 case DW_OP_reg0:
329 case DW_OP_reg1:
330 case DW_OP_reg2:
331 case DW_OP_reg3:
332 case DW_OP_reg4:
333 case DW_OP_reg5:
334 case DW_OP_reg6:
335 case DW_OP_reg7:
336 case DW_OP_reg8:
337 case DW_OP_reg9:
338 case DW_OP_reg10:
339 case DW_OP_reg11:
340 case DW_OP_reg12:
341 case DW_OP_reg13:
342 case DW_OP_reg14:
343 case DW_OP_reg15:
344 case DW_OP_reg16:
345 case DW_OP_reg17:
346 case DW_OP_reg18:
347 case DW_OP_reg19:
348 case DW_OP_reg20:
349 case DW_OP_reg21:
350 case DW_OP_reg22:
351 case DW_OP_reg23:
352 case DW_OP_reg24:
353 case DW_OP_reg25:
354 case DW_OP_reg26:
355 case DW_OP_reg27:
356 case DW_OP_reg28:
357 case DW_OP_reg29:
358 case DW_OP_reg30:
359 case DW_OP_reg31:
361 case DW_OP_lit0:
362 case DW_OP_lit1:
363 case DW_OP_lit2:
364 case DW_OP_lit3:
365 case DW_OP_lit4:
366 case DW_OP_lit5:
367 case DW_OP_lit6:
368 case DW_OP_lit7:
369 case DW_OP_lit8:
370 case DW_OP_lit9:
371 case DW_OP_lit10:
372 case DW_OP_lit11:
373 case DW_OP_lit12:
374 case DW_OP_lit13:
375 case DW_OP_lit14:
376 case DW_OP_lit15:
377 case DW_OP_lit16:
378 case DW_OP_lit17:
379 case DW_OP_lit18:
380 case DW_OP_lit19:
381 case DW_OP_lit20:
382 case DW_OP_lit21:
383 case DW_OP_lit22:
384 case DW_OP_lit23:
385 case DW_OP_lit24:
386 case DW_OP_lit25:
387 case DW_OP_lit26:
388 case DW_OP_lit27:
389 case DW_OP_lit28:
390 case DW_OP_lit29:
391 case DW_OP_lit30:
392 case DW_OP_lit31:
394 case DW_OP_dup:
395 case DW_OP_drop:
397 case DW_OP_over:
399 case DW_OP_swap:
400 case DW_OP_rot:
401 case DW_OP_xderef:
403 case DW_OP_abs:
404 case DW_OP_and:
405 case DW_OP_div:
406 case DW_OP_minus:
407 case DW_OP_mod:
408 case DW_OP_mul:
409 case DW_OP_neg:
410 case DW_OP_not:
411 case DW_OP_or:
412 case DW_OP_plus:
414 case DW_OP_shl:
415 case DW_OP_shr:
416 case DW_OP_shra:
417 case DW_OP_xor:
419 case DW_OP_eq:
420 case DW_OP_ge:
421 case DW_OP_gt:
422 case DW_OP_le:
423 case DW_OP_lt:
424 case DW_OP_ne:
426 case DW_OP_nop:
427 break;
429 /* Operations with 1-byte operands. */
430 case DW_OP_const1u:
431 case DW_OP_const1s:
432 case DW_OP_pick:
433 case DW_OP_deref_size:
434 case DW_OP_xderef_size:
435 operand1 = *p++;
436 break;
438 /* Operations with 2-byte operands. */
439 case DW_OP_const2u:
440 case DW_OP_const2s:
441 case DW_OP_bra:
442 case DW_OP_skip:
443 p += 2;
444 break;
446 /* Operations with 4-byte operands. */
447 case DW_OP_const4u:
448 case DW_OP_const4s:
449 p += 4;
450 break;
452 /* Operations with 8-byte operands. */
453 case DW_OP_const8u:
454 case DW_OP_const8s:
455 p += 8;
456 break;
458 /* Operations with an unsigned LEB128 operand. */
459 case DW_OP_constu:
460 case DW_OP_plus_uconst:
461 case DW_OP_regx:
462 case DW_OP_piece:
463 operand1 = dwarf_decode_uleb128(&p);
464 break;
466 /* Operations with a signed LEB128 operand. */
467 case DW_OP_consts:
468 case DW_OP_breg0:
469 case DW_OP_breg1:
470 case DW_OP_breg2:
471 case DW_OP_breg3:
472 case DW_OP_breg4:
473 case DW_OP_breg5:
474 case DW_OP_breg6:
475 case DW_OP_breg7:
476 case DW_OP_breg8:
477 case DW_OP_breg9:
478 case DW_OP_breg10:
479 case DW_OP_breg11:
480 case DW_OP_breg12:
481 case DW_OP_breg13:
482 case DW_OP_breg14:
483 case DW_OP_breg15:
484 case DW_OP_breg16:
485 case DW_OP_breg17:
486 case DW_OP_breg18:
487 case DW_OP_breg19:
488 case DW_OP_breg20:
489 case DW_OP_breg21:
490 case DW_OP_breg22:
491 case DW_OP_breg23:
492 case DW_OP_breg24:
493 case DW_OP_breg25:
494 case DW_OP_breg26:
495 case DW_OP_breg27:
496 case DW_OP_breg28:
497 case DW_OP_breg29:
498 case DW_OP_breg30:
499 case DW_OP_breg31:
500 case DW_OP_fbreg:
501 operand1 = dwarf_decode_sleb128(&p);
502 break;
505 * Operations with an unsigned LEB128 operand
506 * followed by a signed LEB128 operand.
508 case DW_OP_bregx:
509 operand1 = dwarf_decode_uleb128(&p);
510 operand2 = dwarf_decode_sleb128(&p);
511 break;
513 /* Target address size operand. */
514 case DW_OP_addr:
515 p += pointer_size;
516 break;
518 /* All other operations cause an error. */
519 default:
520 break;
523 lbuf->ld_s[count].lr_number = operand1;
524 lbuf->ld_s[count].lr_number2 = operand2;
526 count++;
529 return ret;
533 dwarf_locdesc(Dwarf_Die die, uint64_t attr, Dwarf_Locdesc **llbuf, Dwarf_Signed *lenp, Dwarf_Error *err)
535 Dwarf_AttrValue av;
536 Dwarf_Locdesc *lbuf;
537 int num;
538 int ret = DWARF_E_NONE;
540 if (err == NULL)
541 return DWARF_E_ERROR;
543 if (die == NULL || llbuf == NULL || lenp == NULL) {
544 DWARF_SET_ERROR(err, DWARF_E_ARGUMENT);
545 return DWARF_E_ARGUMENT;
548 if ((av = dwarf_attrval_find(die, attr)) == NULL) {
549 DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY);
550 ret = DWARF_E_NO_ENTRY;
551 } else if ((lbuf = calloc(sizeof(Dwarf_Locdesc), 1)) == NULL) {
552 DWARF_SET_ERROR(err, DWARF_E_MEMORY);
553 ret = DWARF_E_MEMORY;
554 } else {
555 *lenp = 0;
556 switch (av->av_form) {
557 case DW_FORM_block:
558 case DW_FORM_block1:
559 case DW_FORM_block2:
560 case DW_FORM_block4:
561 /* Compute the number of locations: */
562 if ((num = dwarf_op_num(die->die_cu->cu_pointer_size,
563 av->u[1].u8p, av->u[0].u64)) < 0) {
564 DWARF_SET_ERROR(err, DWARF_E_INVALID_EXPR);
565 ret = DWARF_E_INVALID_EXPR;
567 /* Allocate an array of location structures. */
568 } else if ((lbuf->ld_s =
569 calloc(sizeof(Dwarf_Loc), num)) == NULL) {
570 DWARF_SET_ERROR(err, DWARF_E_MEMORY);
571 ret = DWARF_E_MEMORY;
573 /* Fill the array of location structures. */
574 } else if ((ret = dwarf_loc_fill(lbuf,
575 die->die_cu->cu_pointer_size,
576 av->u[1].u8p, av->u[0].u64)) != DWARF_E_NONE) {
577 free(lbuf->ld_s);
578 } else
579 /* Only one descriptor is returned. */
580 *lenp = 1;
581 break;
582 default:
583 printf("%s(%d): form %s not handled\n",__func__,
584 __LINE__,get_form_desc(av->av_form));
585 DWARF_SET_ERROR(err, DWARF_E_NOT_IMPLEMENTED);
586 ret = DWARF_E_ERROR;
589 if (ret == DWARF_E_NONE) {
590 *llbuf = lbuf;
591 } else
592 free(lbuf);
595 return ret;
599 dwarf_locdesc_free(Dwarf_Locdesc *lbuf, Dwarf_Error *err)
601 if (err == NULL)
602 return DWARF_E_ERROR;
604 if (lbuf == NULL) {
605 DWARF_SET_ERROR(err, DWARF_E_ARGUMENT);
606 return DWARF_E_ARGUMENT;
609 if (lbuf->ld_s != NULL)
610 free(lbuf->ld_s);
612 free(lbuf);
614 return DWARF_E_NONE;