blob: 737dc5d110d694f7520cb86c2184a3accfab621d [file] [log] [blame]
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001/* Get macro information.
Petr Machatafb90bf32014-10-17 02:47:03 +02002 Copyright (C) 2002-2009, 2014 Red Hat, Inc.
Mark Wielaardde2ed972012-06-05 17:15:16 +02003 This file is part of elfutils.
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00004 Written by Ulrich Drepper <drepper@redhat.com>, 2002.
5
Mark Wielaardde2ed972012-06-05 17:15:16 +02006 This file is free software; you can redistribute it and/or modify
7 it under the terms of either
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00008
Mark Wielaardde2ed972012-06-05 17:15:16 +02009 * 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
Ulrich Drepper361df7d2006-04-04 21:38:57 +000022 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
Mark Wielaardde2ed972012-06-05 17:15:16 +020026 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/>. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000029
30#ifdef HAVE_CONFIG_H
31# include <config.h>
32#endif
33
Petr Machatafb90bf32014-10-17 02:47:03 +020034#include <assert.h>
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000035#include <dwarf.h>
Petr Machatafb90bf32014-10-17 02:47:03 +020036#include <search.h>
37#include <stdlib.h>
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000038#include <string.h>
39
40#include <libdwP.h>
41
Petr Machatafb90bf32014-10-17 02:47:03 +020042static int
43get_offset_from (Dwarf_Die *die, int name, Dwarf_Word *retp)
44{
45 /* Get the appropriate attribute. */
46 Dwarf_Attribute attr;
47 if (INTUSE(dwarf_attr) (die, name, &attr) == NULL)
48 return -1;
49
50 /* Offset into the corresponding section. */
51 return INTUSE(dwarf_formudata) (&attr, retp);
52}
53
54static int
55macro_op_compare (const void *p1, const void *p2)
56{
57 const Dwarf_Macro_Op_Table *t1 = (const Dwarf_Macro_Op_Table *) p1;
58 const Dwarf_Macro_Op_Table *t2 = (const Dwarf_Macro_Op_Table *) p2;
59
60 if (t1->offset < t2->offset)
61 return -1;
62 if (t1->offset > t2->offset)
63 return 1;
64
65 if (t1->sec_index < t2->sec_index)
66 return -1;
67 if (t1->sec_index > t2->sec_index)
68 return 1;
69
70 return 0;
71}
72
73static void
74build_table (Dwarf_Macro_Op_Table *table,
75 Dwarf_Macro_Op_Proto op_protos[static 255])
76{
77 unsigned ct = 0;
78 for (unsigned i = 1; i < 256; ++i)
79 if (op_protos[i - 1].forms != NULL)
80 table->table[table->opcodes[i - 1] = ct++] = op_protos[i - 1];
81 else
82 table->opcodes[i - 1] = 0xff;
83}
84
85#define MACRO_PROTO(NAME, ...) \
86 Dwarf_Macro_Op_Proto NAME = ({ \
87 static const uint8_t proto[] = {__VA_ARGS__}; \
88 (Dwarf_Macro_Op_Proto) {sizeof proto, proto}; \
89 })
90
91enum { macinfo_data_size = offsetof (Dwarf_Macro_Op_Table, table[5]) };
92static unsigned char macinfo_data[macinfo_data_size]
93 __attribute__ ((aligned (__alignof (Dwarf_Macro_Op_Table))));
94
95static __attribute__ ((constructor)) void
96init_macinfo_table (void)
97{
98 MACRO_PROTO (p_udata_str, DW_FORM_udata, DW_FORM_string);
99 MACRO_PROTO (p_udata_udata, DW_FORM_udata, DW_FORM_udata);
100 MACRO_PROTO (p_none);
101
102 Dwarf_Macro_Op_Proto op_protos[255] =
103 {
104 [DW_MACINFO_define - 1] = p_udata_str,
105 [DW_MACINFO_undef - 1] = p_udata_str,
106 [DW_MACINFO_vendor_ext - 1] = p_udata_str,
107 [DW_MACINFO_start_file - 1] = p_udata_udata,
108 [DW_MACINFO_end_file - 1] = p_none,
109 /* If you are adding more elements to this array, increase
110 MACINFO_DATA_SIZE above. */
111 };
112
113 Dwarf_Macro_Op_Table *macinfo_table = (void *) macinfo_data;
114 memset (macinfo_table, 0, sizeof macinfo_data);
115 build_table (macinfo_table, op_protos);
116 macinfo_table->sec_index = IDX_debug_macinfo;
117}
118
119static Dwarf_Macro_Op_Table *
120get_macinfo_table (Dwarf *dbg, Dwarf_Word macoff, Dwarf_Die *cudie)
121{
122 assert (cudie != NULL);
123
124 Dwarf_Attribute attr_mem, *attr
125 = INTUSE(dwarf_attr) (cudie, DW_AT_stmt_list, &attr_mem);
126 Dwarf_Off line_offset = (Dwarf_Off) -1;
127 if (attr != NULL)
128 INTUSE(dwarf_formudata) (attr, &line_offset);
129
130 Dwarf_Macro_Op_Table *table = libdw_alloc (dbg, Dwarf_Macro_Op_Table,
131 macinfo_data_size, 1);
132 memcpy (table, macinfo_data, macinfo_data_size);
133
134 table->offset = macoff;
135 table->sec_index = IDX_debug_macinfo;
136 table->line_offset = line_offset;
137 table->is_64bit = cudie->cu->address_size == 8;
138 table->comp_dir = __libdw_getcompdir (cudie);
139
140 return table;
141}
142
143static Dwarf_Macro_Op_Table *
144get_table_for_offset (Dwarf *dbg, Dwarf_Word macoff,
145 const unsigned char *readp,
146 const unsigned char *const endp,
147 Dwarf_Die *cudie)
148{
149 const unsigned char *startp = readp;
150
151 /* Request at least 3 bytes for header. */
152 if (readp + 3 > endp)
153 {
154 invalid_dwarf:
155 __libdw_seterrno (DWARF_E_INVALID_DWARF);
156 return NULL;
157 }
158
159 uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
160 if (version != 4)
161 {
162 __libdw_seterrno (DWARF_E_INVALID_VERSION);
163 return NULL;
164 }
165
166 uint8_t flags = *readp++;
167 bool is_64bit = (flags & 0x1) != 0;
168
169 Dwarf_Off line_offset = (Dwarf_Off) -1;
170 if ((flags & 0x2) != 0)
171 {
172 line_offset = read_addr_unaligned_inc (is_64bit ? 8 : 4, dbg, readp);
173 if (readp > endp)
174 goto invalid_dwarf;
175 }
176 else if (cudie != NULL)
177 {
178 Dwarf_Attribute attr_mem, *attr
179 = INTUSE(dwarf_attr) (cudie, DW_AT_stmt_list, &attr_mem);
180 if (attr != NULL)
181 INTUSE(dwarf_formudata) (attr, &line_offset);
182 }
183
184 /* """The macinfo entry types defined in this standard may, but
185 might not, be described in the table""".
186
187 I.e. these may be present. It's tempting to simply skip them,
188 but it's probably more correct to tolerate that a producer tweaks
189 the way certain opcodes are encoded, for whatever reasons. */
190
191 MACRO_PROTO (p_udata_str, DW_FORM_udata, DW_FORM_string);
192 MACRO_PROTO (p_udata_strp, DW_FORM_udata, DW_FORM_strp);
193 MACRO_PROTO (p_udata_udata, DW_FORM_udata, DW_FORM_udata);
194 MACRO_PROTO (p_secoffset, DW_FORM_sec_offset);
195 MACRO_PROTO (p_none);
196
197 Dwarf_Macro_Op_Proto op_protos[255] =
198 {
199 [DW_MACRO_GNU_define - 1] = p_udata_str,
200 [DW_MACRO_GNU_undef - 1] = p_udata_str,
201 [DW_MACRO_GNU_define_indirect - 1] = p_udata_strp,
202 [DW_MACRO_GNU_undef_indirect - 1] = p_udata_strp,
203 [DW_MACRO_GNU_start_file - 1] = p_udata_udata,
204 [DW_MACRO_GNU_end_file - 1] = p_none,
205 [DW_MACRO_GNU_transparent_include - 1] = p_secoffset,
206 /* N.B. DW_MACRO_undef_indirectx, DW_MACRO_define_indirectx
207 should be added when 130313.1 is supported. */
208 };
209
210 if ((flags & 0x4) != 0)
211 {
212 unsigned count = *readp++;
213 for (unsigned i = 0; i < count; ++i)
214 {
215 unsigned opcode = *readp++;
216
217 Dwarf_Macro_Op_Proto e;
218 get_uleb128 (e.nforms, readp); // XXX checking
219 e.forms = readp;
220 op_protos[opcode - 1] = e;
221
222 readp += e.nforms;
223 if (readp > endp)
224 {
225 __libdw_seterrno (DWARF_E_INVALID_DWARF);
226 return NULL;
227 }
228 }
229 }
230
231 size_t ct = 0;
232 for (unsigned i = 1; i < 256; ++i)
233 if (op_protos[i - 1].forms != NULL)
234 ++ct;
235
236 /* We support at most 0xfe opcodes defined in the table, as 0xff is
237 a value that means that given opcode is not stored at all. But
238 that should be fine, as opcode 0 is not allocated. */
239 assert (ct < 0xff);
240
241 size_t macop_table_size = offsetof (Dwarf_Macro_Op_Table, table[ct]);
242
243 Dwarf_Macro_Op_Table *table = libdw_alloc (dbg, Dwarf_Macro_Op_Table,
244 macop_table_size, 1);
245
246 *table = (Dwarf_Macro_Op_Table) {
247 .offset = macoff,
248 .sec_index = IDX_debug_macro,
249 .line_offset = line_offset,
250 .header_len = readp - startp,
251 .version = version,
252 .is_64bit = is_64bit,
253
254 /* NULL if CUDIE is NULL or DW_AT_comp_dir is absent. */
255 .comp_dir = __libdw_getcompdir (cudie),
256 };
257 build_table (table, op_protos);
258
259 return table;
260}
261
262static Dwarf_Macro_Op_Table *
263cache_op_table (Dwarf *dbg, int sec_index, Dwarf_Off macoff,
264 const unsigned char *startp,
265 const unsigned char *const endp,
266 Dwarf_Die *cudie)
267{
268 Dwarf_Macro_Op_Table fake = { .offset = macoff, .sec_index = sec_index };
269 Dwarf_Macro_Op_Table **found = tfind (&fake, &dbg->macro_ops,
270 macro_op_compare);
271 if (found != NULL)
272 return *found;
273
274 Dwarf_Macro_Op_Table *table = sec_index == IDX_debug_macro
275 ? get_table_for_offset (dbg, macoff, startp, endp, cudie)
276 : get_macinfo_table (dbg, macoff, cudie);
277
278 if (table == NULL)
279 return NULL;
280
281 Dwarf_Macro_Op_Table **ret = tsearch (table, &dbg->macro_ops,
282 macro_op_compare);
283 if (unlikely (ret == NULL))
284 {
285 __libdw_seterrno (DWARF_E_NOMEM);
286 return NULL;
287 }
288
289 return *ret;
290}
291
292static ptrdiff_t
293read_macros (Dwarf *dbg, int sec_index,
294 Dwarf_Off macoff, int (*callback) (Dwarf_Macro *, void *),
295 void *arg, ptrdiff_t offset, bool accept_0xff,
296 Dwarf_Die *cudie)
297{
298 Elf_Data *d = dbg->sectiondata[sec_index];
299 if (unlikely (d == NULL || d->d_buf == NULL))
300 {
301 __libdw_seterrno (DWARF_E_NO_ENTRY);
302 return -1;
303 }
304
305 if (unlikely (macoff >= d->d_size))
306 {
307 __libdw_seterrno (DWARF_E_INVALID_DWARF);
308 return -1;
309 }
310
311 const unsigned char *const startp = d->d_buf + macoff;
312 const unsigned char *const endp = d->d_buf + d->d_size;
313
314 Dwarf_Macro_Op_Table *table = cache_op_table (dbg, sec_index, macoff,
315 startp, endp, cudie);
316 if (table == NULL)
317 return -1;
318
319 if (offset == 0)
320 offset = table->header_len;
321
322 assert (offset >= 0);
323 assert (offset < endp - startp);
324 const unsigned char *readp = startp + offset;
325
326 while (readp < endp)
327 {
328 unsigned int opcode = *readp++;
329 if (opcode == 0)
330 /* Nothing more to do. */
331 return 0;
332
333 if (unlikely (opcode == 0xff && ! accept_0xff))
334 {
335 /* See comment below at dwarf_getmacros for explanation of
336 why we are doing this. */
337 __libdw_seterrno (DWARF_E_INVALID_OPCODE);
338 return -1;
339 }
340
341 unsigned int idx = table->opcodes[opcode - 1];
342 if (idx == 0xff)
343 {
344 __libdw_seterrno (DWARF_E_INVALID_OPCODE);
345 return -1;
346 }
347
348 Dwarf_Macro_Op_Proto *proto = &table->table[idx];
349
350 /* A fake CU with bare minimum data to fool dwarf_formX into
351 doing the right thing with the attributes that we put out.
352 We arbitrarily pretend it's version 4. */
353 Dwarf_CU fake_cu = {
354 .dbg = dbg,
355 .version = 4,
356 .offset_size = table->is_64bit ? 8 : 4,
357 };
358
359 Dwarf_Attribute attributes[proto->nforms];
360 for (Dwarf_Word i = 0; i < proto->nforms; ++i)
361 {
362 /* We pretend this is a DW_AT_GNU_macros attribute so that
363 DW_FORM_sec_offset forms get correctly interpreted as
364 offset into .debug_macro. */
365 attributes[i].code = DW_AT_GNU_macros;
366 attributes[i].form = proto->forms[i];
367 attributes[i].valp = (void *) readp;
368 attributes[i].cu = &fake_cu;
369
Mark Wielaardcb73b5a2014-12-04 21:43:44 +0100370 size_t len = __libdw_form_val_len (dbg, &fake_cu,
371 proto->forms[i], readp, endp);
372 if (len == (size_t) -1)
373 return -1;
374
375 readp += len;
Petr Machatafb90bf32014-10-17 02:47:03 +0200376 }
377
378 Dwarf_Macro macro = {
379 .table = table,
380 .opcode = opcode,
381 .attributes = attributes,
382 };
383
384 if (callback (&macro, arg) != DWARF_CB_OK)
385 return readp - startp;
386 }
387
388 return 0;
389}
390
Petr Machataedb079a2014-12-02 21:22:14 +0100391/* Token layout:
392
393 - The highest bit is used for distinguishing between callers that
394 know that opcode 0xff may have one of two incompatible meanings.
395 The mask that we use for selecting this bit is
396 DWARF_GETMACROS_START.
397
398 - The rest of the token (31 or 63 bits) encodes address inside the
399 macro unit.
400
401 Besides, token value of 0 signals end of iteration and -1 is
402 reserved for signaling errors. That means it's impossible to
403 represent maximum offset of a .debug_macro unit to new-style
404 callers (which in practice decreases the permissible macro unit
405 size by another 1 byte). */
406
407static ptrdiff_t
408token_from_offset (ptrdiff_t offset, bool accept_0xff)
409{
410 if (offset == -1 || offset == 0)
411 return offset;
412
413 /* Make sure the offset didn't overflow into the flag bit. */
414 if ((offset & DWARF_GETMACROS_START) != 0)
415 {
416 __libdw_seterrno (DWARF_E_TOO_BIG);
417 return -1;
418 }
419
420 if (accept_0xff)
421 offset |= DWARF_GETMACROS_START;
422
423 return offset;
424}
425
426static ptrdiff_t
427offset_from_token (ptrdiff_t token, bool *accept_0xffp)
428{
429 *accept_0xffp = (token & DWARF_GETMACROS_START) != 0;
430 token &= ~DWARF_GETMACROS_START;
431
432 return token;
433}
434
Petr Machatafb90bf32014-10-17 02:47:03 +0200435static ptrdiff_t
436gnu_macros_getmacros_off (Dwarf *dbg, Dwarf_Off macoff,
437 int (*callback) (Dwarf_Macro *, void *),
Petr Machataedb079a2014-12-02 21:22:14 +0100438 void *arg, ptrdiff_t offset, bool accept_0xff,
Petr Machatafb90bf32014-10-17 02:47:03 +0200439 Dwarf_Die *cudie)
440{
Petr Machataedb079a2014-12-02 21:22:14 +0100441 assert (offset >= 0);
Petr Machatafb90bf32014-10-17 02:47:03 +0200442
443 if (macoff >= dbg->sectiondata[IDX_debug_macro]->d_size)
444 {
445 __libdw_seterrno (DWARF_E_INVALID_OFFSET);
446 return -1;
447 }
448
Petr Machataedb079a2014-12-02 21:22:14 +0100449 return read_macros (dbg, IDX_debug_macro, macoff,
450 callback, arg, offset, accept_0xff, cudie);
Petr Machatafb90bf32014-10-17 02:47:03 +0200451}
452
453static ptrdiff_t
454macro_info_getmacros_off (Dwarf *dbg, Dwarf_Off macoff,
455 int (*callback) (Dwarf_Macro *, void *),
Petr Machataedb079a2014-12-02 21:22:14 +0100456 void *arg, ptrdiff_t offset, Dwarf_Die *cudie)
Petr Machatafb90bf32014-10-17 02:47:03 +0200457{
Petr Machataedb079a2014-12-02 21:22:14 +0100458 assert (offset >= 0);
Petr Machatafb90bf32014-10-17 02:47:03 +0200459
460 return read_macros (dbg, IDX_debug_macinfo, macoff,
Petr Machataedb079a2014-12-02 21:22:14 +0100461 callback, arg, offset, true, cudie);
Petr Machatafb90bf32014-10-17 02:47:03 +0200462}
463
464ptrdiff_t
465dwarf_getmacros_off (Dwarf *dbg, Dwarf_Off macoff,
466 int (*callback) (Dwarf_Macro *, void *),
467 void *arg, ptrdiff_t token)
468{
469 if (dbg == NULL)
470 {
471 __libdw_seterrno (DWARF_E_NO_DWARF);
472 return -1;
473 }
474
Petr Machataedb079a2014-12-02 21:22:14 +0100475 bool accept_0xff;
476 ptrdiff_t offset = offset_from_token (token, &accept_0xff);
477 assert (accept_0xff);
Petr Machatafb90bf32014-10-17 02:47:03 +0200478
Petr Machataedb079a2014-12-02 21:22:14 +0100479 offset = gnu_macros_getmacros_off (dbg, macoff, callback, arg, offset,
480 accept_0xff, NULL);
481
482 return token_from_offset (offset, accept_0xff);
Petr Machatafb90bf32014-10-17 02:47:03 +0200483}
484
Petr Machataedb079a2014-12-02 21:22:14 +0100485ptrdiff_t
486dwarf_getmacros (cudie, callback, arg, token)
487 Dwarf_Die *cudie;
488 int (*callback) (Dwarf_Macro *, void *);
489 void *arg;
490 ptrdiff_t token;
Petr Machatafb90bf32014-10-17 02:47:03 +0200491{
492 if (cudie == NULL)
493 {
494 __libdw_seterrno (DWARF_E_NO_DWARF);
495 return -1;
496 }
497
Petr Machatafb90bf32014-10-17 02:47:03 +0200498 /* This function might be called from a code that expects to see
499 DW_MACINFO_* opcodes, not DW_MACRO_{GNU_,}* ones. It is fine to
500 serve most DW_MACRO_{GNU_,}* opcodes to such code, because those
501 whose values are the same as DW_MACINFO_* ones also have the same
502 behavior. It is not very likely that a .debug_macro section
503 would only use the part of opcode space that it shares with
504 .debug_macinfo, but it is possible. Serving the opcodes that are
505 only valid in DW_MACRO_{GNU_,}* domain is OK as well, because
506 clients in general need to be ready that newer standards define
507 more opcodes, and have coping mechanisms for unfamiliar opcodes.
Roland McGrathe7c16332009-05-07 18:57:18 -0700508
Petr Machatafb90bf32014-10-17 02:47:03 +0200509 The one exception to the above rule is opcode 0xff, which has
510 concrete semantics in .debug_macinfo, but falls into vendor block
511 in .debug_macro, and can be assigned to do whatever. There is
512 some small probability that the two opcodes would look
513 superficially similar enough that a client would be confused and
514 misbehave as a result. For this reason, we refuse to serve
Petr Machataedb079a2014-12-02 21:22:14 +0100515 through this interface 0xff's originating from .debug_macro
516 unless the TOKEN that we obtained indicates the call originates
517 from a new-style caller. See above for details on what
518 information is encoded into tokens. */
Petr Machataf3df61f2009-05-07 21:02:33 +0200519
Petr Machataedb079a2014-12-02 21:22:14 +0100520 bool accept_0xff;
521 ptrdiff_t offset = offset_from_token (token, &accept_0xff);
522
523 /* DW_AT_macro_info */
524 if (dwarf_hasattr (cudie, DW_AT_macro_info))
525 {
526 Dwarf_Word macoff;
527 if (get_offset_from (cudie, DW_AT_macro_info, &macoff) != 0)
528 return -1;
529 offset = macro_info_getmacros_off (cudie->cu->dbg, macoff,
530 callback, arg, offset, cudie);
531 }
532 else
533 {
534 /* DW_AT_GNU_macros, DW_AT_macros */
535 Dwarf_Word macoff;
536 if (get_offset_from (cudie, DW_AT_GNU_macros, &macoff) != 0)
537 return -1;
538 offset = gnu_macros_getmacros_off (cudie->cu->dbg, macoff,
539 callback, arg, offset, accept_0xff,
540 cudie);
541 }
542
543 return token_from_offset (offset, accept_0xff);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000544}