blob: 5e56376d1169d2aad1d9b83f8aae7feb6822973e [file] [log] [blame]
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001/* Return high program counter value 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
25dwarf_highpc (die, return_highpc, error)
26 Dwarf_Die die;
27 Dwarf_Addr *return_highpc;
28 Dwarf_Error *error;
29{
30 Dwarf_Debug dbg = die->cu->dbg;
31 Dwarf_Small *die_addr;
32 Dwarf_Word u128;
33 Dwarf_Abbrev abbrev;
34 Dwarf_Small *attrp;
35
36 /* Address of the given die. */
37 die_addr = die->addr;
38
39 /* Get abbrev code. */
40 get_uleb128 (u128, die_addr);
41 /* And get the abbreviation itself. */
42 abbrev = __libdwarf_get_abbrev (dbg, die->cu, u128, error);
43 if (abbrev == NULL)
44 return DW_DLV_ERROR;
45
46 /* This is where the attributes start. */
47 attrp = abbrev->attrp;
48
49 /* Search the name attribute. */
50 while (1)
51 {
52 Dwarf_Word attr_name;
53 Dwarf_Word attr_form;
54
55 /* Are we still in bounds? */
56 if (unlikely (attrp
57 >= ((Dwarf_Small *) dbg->sections[IDX_debug_abbrev].addr
58 + dbg->sections[IDX_debug_abbrev].size)))
59 {
60 __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
61 return DW_DLV_ERROR;
62 }
63
64 /* Get attribute name and form.
65
66 XXX We don't check whether this reads beyond the end of the
67 section. */
68 get_uleb128 (attr_name, attrp);
69 get_uleb128 (attr_form, attrp);
70
71 /* We can stop if we found the attribute with value zero. */
72 if (attr_name == 0 && attr_form == 0)
73 break;
74
75 /* Is this the name attribute? */
76 if (unlikely (attr_name == DW_AT_high_pc))
77 {
78 if (unlikely (attr_form != DW_FORM_addr))
79 {
80 __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
81 return DW_DLV_ERROR;
82 }
83
84 if (die->cu->address_size == 4)
85 *return_highpc = read_4ubyte_unaligned (dbg, die_addr);
86 else
87 *return_highpc = read_8ubyte_unaligned (dbg, die_addr);
88
89 return DW_DLV_OK;
90 }
91
92 /* Skip over the rest of this attribute (if there is any). */
93 if (attr_form != 0)
94 {
95 size_t len;
96
97 if (unlikely (__libdwarf_form_val_len (dbg, die->cu, attr_form,
98 die_addr, &len, error)
99 != DW_DLV_OK))
100 return DW_DLV_ERROR;
101
102 die_addr += len;
103 }
104 }
105
106 /* No such attribute present. */
107 return DW_DLV_NO_ENTRY;
108}