blob: 39727f8ae5bc15f7b3aafce9a341ad1aeb7813e8 [file] [log] [blame]
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001/* Return constant value of given attribute type associated with die.
2 Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
3 Written by Ulrich Drepper <drepper@redhat.com>, 2000.
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
21#include <libdwarfP.h>
22
23
24int
25__libdwarf_getconstant (die, name, return_size, error)
26 Dwarf_Die die;
27 Dwarf_Half name;
28 Dwarf_Unsigned *return_size;
29 Dwarf_Error *error;
30{
31 Dwarf_Debug dbg = die->cu->dbg;
32 Dwarf_Small *die_addr;
33 Dwarf_Word u128;
34 Dwarf_Abbrev abbrev;
35 Dwarf_Small *attrp;
36
37 /* Address of the given die. */
38 die_addr = die->addr;
39
40 /* Get abbrev code. */
41 get_uleb128 (u128, die_addr);
42 /* And get the abbreviation itself. */
43 abbrev = __libdwarf_get_abbrev (dbg, die->cu, u128, error);
44 if (abbrev == NULL)
45 return DW_DLV_ERROR;
46
47 /* This is where the attributes start. */
48 attrp = abbrev->attrp;
49
50 /* Search the name attribute. */
51 while (1)
52 {
53 Dwarf_Word attr_name;
54 Dwarf_Word attr_form;
55
56 /* Are we still in bounds? */
57 if (unlikely (attrp
58 >= ((Dwarf_Small *) dbg->sections[IDX_debug_abbrev].addr
59 + dbg->sections[IDX_debug_abbrev].size)))
60 {
61 __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
62 return DW_DLV_ERROR;
63 }
64
65 /* Get attribute name and form.
66
67 XXX We don't check whether this reads beyond the end of the
68 section. */
69 get_uleb128 (attr_name, attrp);
70 get_uleb128 (attr_form, attrp);
71
72 /* We can stop if we found the attribute with value zero. */
73 if (attr_name == 0 && attr_form == 0)
74 break;
75
76 /* Is this the name attribute? */
77 if (unlikely (attr_name == name))
78 {
79 switch (attr_form)
80 {
81 case DW_FORM_data1:
82 *return_size = *die_addr;
83 break;
84 case DW_FORM_data2:
85 *return_size = read_2ubyte_unaligned (dbg, die_addr);
86 break;
87 case DW_FORM_data4:
88 *return_size = read_4ubyte_unaligned (dbg, die_addr);
89 break;
90 case DW_FORM_data8:
91 *return_size = read_8ubyte_unaligned (dbg, die_addr);
92 break;
93 case DW_FORM_sdata:
94 get_sleb128 (u128, die_addr);
95 *return_size = u128;
96 break;
97 case DW_FORM_udata:
98 get_uleb128 (u128, die_addr);
99 *return_size = u128;
100 break;
101 default:
102 __libdwarf_error (dbg, error, DW_E_NO_CONSTANT);
103 return DW_DLV_ERROR;
104 }
105
106 return DW_DLV_OK;
107 }
108
109 /* Skip over the rest of this attribute (if there is any). */
110 if (attr_form != 0)
111 {
112 size_t len;
113
114 if (unlikely (__libdwarf_form_val_len (dbg, die->cu, attr_form,
115 die_addr, &len, error)
116 != DW_DLV_OK))
117 return DW_DLV_ERROR;
118
119 die_addr += len;
120 }
121 }
122
123 /* No such attribute present. */
124 return DW_DLV_NO_ENTRY;
125}