• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Helper functions for form handling.
2    Copyright (C) 2003, 2004 Red Hat, Inc.
3    Written by Ulrich Drepper <drepper@redhat.com>, 2003.
4 
5    This program is Open Source software; you can redistribute it and/or
6    modify it under the terms of the Open Software License version 1.0 as
7    published by the Open Source Initiative.
8 
9    You should have received a copy of the Open Software License along
10    with this program; if not, you may obtain a copy of the Open Software
11    License version 1.0 from http://www.opensource.org/licenses/osl.php or
12    by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
13    3001 King Ranch Road, Ukiah, CA 95482.   */
14 
15 #ifdef HAVE_CONFIG_H
16 # include <config.h>
17 #endif
18 
19 #include <dwarf.h>
20 #include <string.h>
21 
22 #include "libdwP.h"
23 
24 
25 size_t
26 internal_function_def
__libdw_form_val_len(Dwarf * dbg,struct Dwarf_CU * cu,unsigned int form,unsigned char * valp)27 __libdw_form_val_len (Dwarf *dbg, struct Dwarf_CU *cu, unsigned int form,
28 		      unsigned char *valp)
29 {
30   unsigned char *saved;
31   unsigned int u128;
32   size_t result;
33 
34   switch (form)
35     {
36     case DW_FORM_addr:
37       result = cu->address_size;
38       break;
39 
40     case DW_FORM_strp:
41     case DW_FORM_ref_addr:
42       result = cu->offset_size;
43       break;
44 
45     case DW_FORM_block1:
46       result = *valp + 1;
47       break;
48 
49     case DW_FORM_block2:
50       result = read_2ubyte_unaligned (dbg, valp) + 2;
51       break;
52 
53     case DW_FORM_block4:
54       result = read_4ubyte_unaligned (dbg, valp) + 4;
55       break;
56 
57     case DW_FORM_block:
58       saved = valp;
59       get_uleb128 (u128, valp);
60       result = u128 + (valp - saved);
61       break;
62 
63     case DW_FORM_ref1:
64     case DW_FORM_data1:
65     case DW_FORM_flag:
66       result = 1;
67       break;
68 
69     case DW_FORM_data2:
70     case DW_FORM_ref2:
71       result = 2;
72       break;
73 
74     case DW_FORM_data4:
75     case DW_FORM_ref4:
76       result = 4;
77       break;
78 
79     case DW_FORM_data8:
80     case DW_FORM_ref8:
81       result = 8;
82       break;
83 
84     case DW_FORM_string:
85       result = strlen ((char *) valp) + 1;
86       break;
87 
88     case DW_FORM_sdata:
89     case DW_FORM_udata:
90     case DW_FORM_ref_udata:
91       saved = valp;
92       get_uleb128 (u128, valp);
93       result = valp - saved;
94       break;
95 
96     case DW_FORM_indirect:
97       saved = valp;
98       get_uleb128 (u128, valp);
99       // XXX Is this really correct?
100       result = __libdw_form_val_len (dbg, cu, u128, valp);
101       if (result != (size_t) -1)
102 	result += valp - saved;
103       break;
104 
105     default:
106       __libdw_seterrno (DWARF_E_INVALID_DWARF);
107       result = (size_t) -1l;
108       break;
109     }
110 
111   return result;
112 }
113