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