blob: 2dfcd57aec6d1ab1da5deec9453b2ba15a443f86 [file] [log] [blame]
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001/* Return string in name attribute of 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#include <string.h>
21
22#include <libdwarfP.h>
23
24
25int
26dwarf_diename (die, return_name, error)
27 Dwarf_Die die;
28 char **return_name;
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 (attr_name == DW_AT_name)
78 {
79 char *str;
80
81 /* We found it. Duplicate the string and return. There are
82 two possible forms: DW_FORM_string and DW_FORM_strp. */
83 if (attr_form == DW_FORM_string)
84 {
85 str = (char *) die_addr;
86 }
87 else if (likely (attr_form == DW_FORM_strp))
88 {
89 Dwarf_Unsigned off;
90 Dwarf_Signed len;
91
92 if (die->cu->offset_size == 4)
93 off = read_4ubyte_unaligned (dbg, die_addr);
94 else
95 off = read_8ubyte_unaligned (dbg, die_addr);
96
97 /* This is an offset in the .debug_str section. Make sure
98 it's within range. */
99 if (unlikely (dwarf_get_str (dbg, off, &str, &len, error)
100 != DW_DLV_OK))
101 {
102 __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
103 return DW_DLV_ERROR;
104 }
105 }
106 else
107 {
108 __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
109 return DW_DLV_ERROR;
110 }
111
112 str = strdup (str);
113 if (str == NULL)
114 {
115 __libdwarf_error (dbg, error, DW_E_NOMEM);
116 return DW_DLV_ERROR;
117 }
118
119 *return_name = str;
120 return DW_DLV_OK;
121 }
122
123 /* Skip over the rest of this attribute (if there is any). */
124 if (attr_form != 0)
125 {
126 size_t len;
127
128 if (unlikely (__libdwarf_form_val_len (dbg, die->cu, attr_form,
129 die_addr, &len, error)
130 != DW_DLV_OK))
131 return DW_DLV_ERROR;
132
133 die_addr += len;
134 }
135 }
136
137 /* No name attribute present. */
138 return DW_DLV_NO_ENTRY;
139}