Branch data Line data Source code
1 : : /* Get macro information.
2 : : Copyright (C) 2002-2009 Red Hat, Inc.
3 : : This file is part of elfutils.
4 : : Written by Ulrich Drepper <drepper@redhat.com>, 2002.
5 : :
6 : : This file is free software; you can redistribute it and/or modify
7 : : it under the terms of either
8 : :
9 : : * the GNU Lesser General Public License as published by the Free
10 : : Software Foundation; either version 3 of the License, or (at
11 : : your option) any later version
12 : :
13 : : or
14 : :
15 : : * the GNU General Public License as published by the Free
16 : : Software Foundation; either version 2 of the License, or (at
17 : : your option) any later version
18 : :
19 : : or both in parallel, as here.
20 : :
21 : : elfutils is distributed in the hope that it will be useful, but
22 : : WITHOUT ANY WARRANTY; without even the implied warranty of
23 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 : : General Public License for more details.
25 : :
26 : : You should have received copies of the GNU General Public License and
27 : : the GNU Lesser General Public License along with this program. If
28 : : not, see <http://www.gnu.org/licenses/>. */
29 : :
30 : : #ifdef HAVE_CONFIG_H
31 : : # include <config.h>
32 : : #endif
33 : :
34 : : #include <dwarf.h>
35 : : #include <string.h>
36 : :
37 : : #include <libdwP.h>
38 : :
39 : :
40 : : ptrdiff_t
41 : 266 : dwarf_getmacros (die, callback, arg, offset)
42 : : Dwarf_Die *die;
43 : : int (*callback) (Dwarf_Macro *, void *);
44 : : void *arg;
45 : : ptrdiff_t offset;
46 : : {
47 [ + - ]: 266 : if (die == NULL)
48 : : return -1;
49 : :
50 : 266 : Elf_Data *d = die->cu->dbg->sectiondata[IDX_debug_macinfo];
51 [ + - ][ - + ]: 266 : if (unlikely (d == NULL) || unlikely (d->d_buf == NULL))
52 : : {
53 : 0 : __libdw_seterrno (DWARF_E_NO_ENTRY);
54 : : return -1;
55 : : }
56 : :
57 [ + + ]: 266 : if (offset == 0)
58 : : {
59 : : /* Get the appropriate attribute. */
60 : : Dwarf_Attribute attr;
61 [ + - ]: 2 : if (INTUSE(dwarf_attr) (die, DW_AT_macro_info, &attr) == NULL)
62 : : return -1;
63 : :
64 : : /* Offset into the .debug_macinfo section. */
65 : : Dwarf_Word macoff;
66 [ + - ]: 2 : if (INTUSE(dwarf_formudata) (&attr, &macoff) != 0)
67 : : return -1;
68 : :
69 : 2 : offset = macoff;
70 : : }
71 [ + - ]: 266 : if (unlikely (offset > (ptrdiff_t) d->d_size))
72 : : goto invalid;
73 : :
74 : 266 : const unsigned char *readp = d->d_buf + offset;
75 : 266 : const unsigned char *readendp = d->d_buf + d->d_size;
76 : :
77 [ + - ]: 266 : if (readp == readendp)
78 : : return 0;
79 : :
80 [ + - ]: 266 : while (readp < readendp)
81 : : {
82 : 266 : unsigned int opcode = *readp++;
83 : : unsigned int u128;
84 : 266 : unsigned int u128_2 = 0;
85 : 266 : const char *str = NULL;
86 : : const unsigned char *endp;
87 : :
88 [ + + + - : 266 : switch (opcode)
+ ]
89 : : {
90 : : case DW_MACINFO_define:
91 : : case DW_MACINFO_undef:
92 : : case DW_MACINFO_vendor_ext:
93 : : /* For the first two opcodes the parameters are
94 : : line, string
95 : : For the latter
96 : : number, string.
97 : : We can treat these cases together. */
98 [ - + ]: 260 : get_uleb128 (u128, readp);
99 : :
100 : 260 : endp = memchr (readp, '\0', readendp - readp);
101 [ + - ]: 260 : if (endp == NULL)
102 : : goto invalid;
103 : :
104 : 260 : str = (char *) readp;
105 : 260 : readp = endp + 1;
106 : 260 : break;
107 : :
108 : : case DW_MACINFO_start_file:
109 : : /* The two parameters are line and file index. */
110 [ - + ]: 2 : get_uleb128 (u128, readp);
111 [ - + ]: 2 : get_uleb128 (u128_2, readp);
112 : : break;
113 : :
114 : : case DW_MACINFO_end_file:
115 : : /* No parameters for this one. */
116 : : u128 = 0;
117 : : break;
118 : :
119 : : case 0:
120 : : /* Nothing more to do. */
121 : : return 0;
122 : :
123 : : default:
124 : : goto invalid;
125 : : }
126 : :
127 : : Dwarf_Macro mac;
128 : 264 : mac.opcode = opcode;
129 : 264 : mac.param1 = u128;
130 [ + + ]: 264 : if (str == NULL)
131 : 4 : mac.param2.u = u128_2;
132 : : else
133 : 260 : mac.param2.s = str;
134 : :
135 [ + - ]: 264 : if (callback (&mac, arg) != DWARF_CB_OK)
136 : 266 : return readp - (const unsigned char *) d->d_buf;
137 : : }
138 : :
139 : : /* If we come here the termination of the data for the CU is not
140 : : present. */
141 : : invalid:
142 : 266 : __libdw_seterrno (DWARF_E_INVALID_DWARF);
143 : : return -1;
144 : : }
|