1 /* Get macro information.
2 Copyright (C) 2002-2009, 2014, 2017, 2018 Red Hat, Inc.
3 This file is part of elfutils.
4
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
7
8 * the GNU Lesser General Public License as published by the Free
9 Software Foundation; either version 3 of the License, or (at
10 your option) any later version
11
12 or
13
14 * the GNU General Public License as published by the Free
15 Software Foundation; either version 2 of the License, or (at
16 your option) any later version
17
18 or both in parallel, as here.
19
20 elfutils is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
24
25 You should have received copies of the GNU General Public License and
26 the GNU Lesser General Public License along with this program. If
27 not, see <http://www.gnu.org/licenses/>. */
28
29 #ifdef HAVE_CONFIG_H
30 # include <config.h>
31 #endif
32
33 #include <assert.h>
34 #include <dwarf.h>
35 #include <search.h>
36 #include <stdlib.h>
37 #include <string.h>
38
39 #include <libdwP.h>
40
41 static int
get_offset_from(Dwarf_Die * die,int name,Dwarf_Word * retp)42 get_offset_from (Dwarf_Die *die, int name, Dwarf_Word *retp)
43 {
44 /* Get the appropriate attribute. */
45 Dwarf_Attribute attr;
46 if (INTUSE(dwarf_attr) (die, name, &attr) == NULL)
47 return -1;
48
49 /* Offset into the corresponding section. */
50 if (INTUSE(dwarf_formudata) (&attr, retp) != 0)
51 return -1;
52
53 Dwarf_Off offset;
54 if (INTUSE(dwarf_cu_dwp_section_info) (die->cu, DW_SECT_MACRO, &offset, NULL)
55 != 0)
56 return -1;
57 *retp += offset;
58 return 0;
59 }
60
61 static int
macro_op_compare(const void * p1,const void * p2)62 macro_op_compare (const void *p1, const void *p2)
63 {
64 const Dwarf_Macro_Op_Table *t1 = (const Dwarf_Macro_Op_Table *) p1;
65 const Dwarf_Macro_Op_Table *t2 = (const Dwarf_Macro_Op_Table *) p2;
66
67 if (t1->offset < t2->offset)
68 return -1;
69 if (t1->offset > t2->offset)
70 return 1;
71
72 if (t1->sec_index < t2->sec_index)
73 return -1;
74 if (t1->sec_index > t2->sec_index)
75 return 1;
76
77 return 0;
78 }
79
80 static void
build_table(Dwarf_Macro_Op_Table * table,Dwarf_Macro_Op_Proto op_protos[static255])81 build_table (Dwarf_Macro_Op_Table *table,
82 Dwarf_Macro_Op_Proto op_protos[static 255])
83 {
84 unsigned ct = 0;
85 for (unsigned i = 1; i < 256; ++i)
86 if (op_protos[i - 1].forms != NULL)
87 table->table[table->opcodes[i - 1] = ct++] = op_protos[i - 1];
88 else
89 table->opcodes[i - 1] = 0xff;
90 }
91
92 #define MACRO_PROTO(NAME, ...) \
93 Dwarf_Macro_Op_Proto NAME = ({ \
94 static const uint8_t proto[] = {__VA_ARGS__}; \
95 (Dwarf_Macro_Op_Proto) {sizeof proto, proto}; \
96 })
97
98 enum { macinfo_data_size = offsetof (Dwarf_Macro_Op_Table, table[5]) };
99 static unsigned char macinfo_data[macinfo_data_size]
100 __attribute__ ((aligned (__alignof (Dwarf_Macro_Op_Table))));
101
102 static __attribute__ ((constructor)) void
init_macinfo_table(void)103 init_macinfo_table (void)
104 {
105 MACRO_PROTO (p_udata_str, DW_FORM_udata, DW_FORM_string);
106 MACRO_PROTO (p_udata_udata, DW_FORM_udata, DW_FORM_udata);
107 MACRO_PROTO (p_none);
108
109 Dwarf_Macro_Op_Proto op_protos[255] =
110 {
111 [DW_MACINFO_define - 1] = p_udata_str,
112 [DW_MACINFO_undef - 1] = p_udata_str,
113 [DW_MACINFO_vendor_ext - 1] = p_udata_str,
114 [DW_MACINFO_start_file - 1] = p_udata_udata,
115 [DW_MACINFO_end_file - 1] = p_none,
116 /* If you are adding more elements to this array, increase
117 MACINFO_DATA_SIZE above. */
118 };
119
120 Dwarf_Macro_Op_Table *macinfo_table = (void *) macinfo_data;
121 memset (macinfo_table, 0, sizeof macinfo_data);
122 build_table (macinfo_table, op_protos);
123 macinfo_table->sec_index = IDX_debug_macinfo;
124 }
125
126 static Dwarf_Macro_Op_Table *
get_macinfo_table(Dwarf * dbg,Dwarf_Word macoff,Dwarf_Die * cudie)127 get_macinfo_table (Dwarf *dbg, Dwarf_Word macoff, Dwarf_Die *cudie)
128 {
129 assert (cudie != NULL);
130
131 Dwarf_Attribute attr_mem, *attr
132 = INTUSE(dwarf_attr) (cudie, DW_AT_stmt_list, &attr_mem);
133 Dwarf_Off line_offset = (Dwarf_Off) -1;
134 if (attr != NULL)
135 {
136 if (unlikely (INTUSE(dwarf_formudata) (attr, &line_offset) != 0))
137 return NULL;
138 }
139 else if (cudie->cu->unit_type == DW_UT_split_compile
140 && dbg->sectiondata[IDX_debug_line] != NULL)
141 line_offset = 0;
142 if (line_offset != (Dwarf_Off) -1)
143 {
144 Dwarf_Off dwp_offset;
145 if (INTUSE(dwarf_cu_dwp_section_info) (cudie->cu, DW_SECT_LINE,
146 &dwp_offset, NULL) != 0)
147 return NULL;
148 line_offset += dwp_offset;
149 }
150
151 Dwarf_Macro_Op_Table *table = libdw_alloc (dbg, Dwarf_Macro_Op_Table,
152 macinfo_data_size, 1);
153 memcpy (table, macinfo_data, macinfo_data_size);
154
155 table->dbg = dbg;
156 table->offset = macoff;
157 table->sec_index = IDX_debug_macinfo;
158 table->line_offset = line_offset;
159 table->address_size = cudie->cu->address_size;
160 table->offset_size = cudie->cu->offset_size;
161 table->comp_dir = __libdw_getcompdir (cudie);
162
163 return table;
164 }
165
166 static Dwarf_Macro_Op_Table *
get_table_for_offset(Dwarf * dbg,Dwarf_Word macoff,const unsigned char * readp,const unsigned char * const endp,Dwarf_Die * cudie)167 get_table_for_offset (Dwarf *dbg, Dwarf_Word macoff,
168 const unsigned char *readp,
169 const unsigned char *const endp,
170 Dwarf_Die *cudie)
171 {
172 const unsigned char *startp = readp;
173
174 /* Request at least 3 bytes for header. */
175 if (readp + 3 > endp)
176 {
177 invalid_dwarf:
178 __libdw_seterrno (DWARF_E_INVALID_DWARF);
179 return NULL;
180 }
181
182 uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
183 if (version != 4 && version != 5)
184 {
185 __libdw_seterrno (DWARF_E_INVALID_VERSION);
186 return NULL;
187 }
188
189 uint8_t flags = *readp++;
190 bool is_64bit = (flags & 0x1) != 0;
191
192 Dwarf_Off line_offset = (Dwarf_Off) -1;
193 if ((flags & 0x2) != 0)
194 {
195 line_offset = read_addr_unaligned_inc (is_64bit ? 8 : 4, dbg, readp);
196 if (readp > endp)
197 goto invalid_dwarf;
198 }
199 else if (cudie != NULL)
200 {
201 Dwarf_Attribute attr_mem, *attr
202 = INTUSE(dwarf_attr) (cudie, DW_AT_stmt_list, &attr_mem);
203 if (attr != NULL)
204 if (unlikely (INTUSE(dwarf_formudata) (attr, &line_offset) != 0))
205 return NULL;
206 }
207 if (line_offset != (Dwarf_Off) -1 && cudie != NULL)
208 {
209 Dwarf_Off dwp_offset;
210 if (INTUSE(dwarf_cu_dwp_section_info) (cudie->cu, DW_SECT_LINE,
211 &dwp_offset, NULL) != 0)
212 return NULL;
213 line_offset += dwp_offset;
214 }
215
216 uint8_t address_size;
217 if (cudie != NULL)
218 address_size = cudie->cu->address_size;
219 else
220 {
221 char *ident = elf_getident (dbg->elf, NULL);
222 address_size = ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
223 }
224
225 /* """The macinfo entry types defined in this standard may, but
226 might not, be described in the table""".
227
228 I.e. these may be present. It's tempting to simply skip them,
229 but it's probably more correct to tolerate that a producer tweaks
230 the way certain opcodes are encoded, for whatever reasons. */
231
232 MACRO_PROTO (p_udata_str, DW_FORM_udata, DW_FORM_string);
233 MACRO_PROTO (p_udata_strp, DW_FORM_udata, DW_FORM_strp);
234 MACRO_PROTO (p_udata_strsup, DW_FORM_udata, DW_FORM_strp_sup);
235 MACRO_PROTO (p_udata_strx, DW_FORM_udata, DW_FORM_strx);
236 MACRO_PROTO (p_udata_udata, DW_FORM_udata, DW_FORM_udata);
237 MACRO_PROTO (p_secoffset, DW_FORM_sec_offset);
238 MACRO_PROTO (p_none);
239
240 Dwarf_Macro_Op_Proto op_protos[255] =
241 {
242 [DW_MACRO_define - 1] = p_udata_str,
243 [DW_MACRO_undef - 1] = p_udata_str,
244 [DW_MACRO_define_strp - 1] = p_udata_strp,
245 [DW_MACRO_undef_strp - 1] = p_udata_strp,
246 [DW_MACRO_start_file - 1] = p_udata_udata,
247 [DW_MACRO_end_file - 1] = p_none,
248 [DW_MACRO_import - 1] = p_secoffset,
249 [DW_MACRO_define_sup - 1] = p_udata_strsup,
250 [DW_MACRO_undef_sup - 1] = p_udata_strsup,
251 [DW_MACRO_import_sup - 1] = p_secoffset, /* XXX - but in sup!. */
252 [DW_MACRO_define_strx - 1] = p_udata_strx,
253 [DW_MACRO_undef_strx - 1] = p_udata_strx,
254 };
255
256 if ((flags & 0x4) != 0)
257 {
258 unsigned count = *readp++;
259 for (unsigned i = 0; i < count; ++i)
260 {
261 unsigned opcode = *readp++;
262
263 Dwarf_Macro_Op_Proto e;
264 if (readp >= endp)
265 goto invalid;
266 get_uleb128 (e.nforms, readp, endp);
267 e.forms = readp;
268 op_protos[opcode - 1] = e;
269
270 readp += e.nforms;
271 if (readp > endp)
272 {
273 invalid:
274 __libdw_seterrno (DWARF_E_INVALID_DWARF);
275 return NULL;
276 }
277 }
278 }
279
280 size_t ct = 0;
281 for (unsigned i = 1; i < 256; ++i)
282 if (op_protos[i - 1].forms != NULL)
283 ++ct;
284
285 /* We support at most 0xfe opcodes defined in the table, as 0xff is
286 a value that means that given opcode is not stored at all. But
287 that should be fine, as opcode 0 is not allocated. */
288 assert (ct < 0xff);
289
290 size_t macop_table_size = offsetof (Dwarf_Macro_Op_Table, table[ct]);
291
292 Dwarf_Macro_Op_Table *table = libdw_alloc (dbg, Dwarf_Macro_Op_Table,
293 macop_table_size, 1);
294
295 *table = (Dwarf_Macro_Op_Table) {
296 .dbg = dbg,
297 .offset = macoff,
298 .sec_index = IDX_debug_macro,
299 .line_offset = line_offset,
300 .header_len = readp - startp,
301 .version = version,
302 .address_size = address_size,
303 .offset_size = is_64bit ? 8 : 4,
304
305 /* NULL if CUDIE is NULL or DW_AT_comp_dir is absent. */
306 .comp_dir = __libdw_getcompdir (cudie),
307 };
308 build_table (table, op_protos);
309
310 return table;
311 }
312
313 static Dwarf_Macro_Op_Table *
cache_op_table(Dwarf * dbg,int sec_index,Dwarf_Off macoff,const unsigned char * startp,const unsigned char * const endp,Dwarf_Die * cudie)314 cache_op_table (Dwarf *dbg, int sec_index, Dwarf_Off macoff,
315 const unsigned char *startp,
316 const unsigned char *const endp,
317 Dwarf_Die *cudie)
318 {
319 Dwarf_Macro_Op_Table fake = { .offset = macoff, .sec_index = sec_index };
320 Dwarf_Macro_Op_Table **found = tfind (&fake, &dbg->macro_ops,
321 macro_op_compare);
322 if (found != NULL)
323 return *found;
324
325 Dwarf_Macro_Op_Table *table = sec_index == IDX_debug_macro
326 ? get_table_for_offset (dbg, macoff, startp, endp, cudie)
327 : get_macinfo_table (dbg, macoff, cudie);
328
329 if (table == NULL)
330 return NULL;
331
332 Dwarf_Macro_Op_Table **ret = tsearch (table, &dbg->macro_ops,
333 macro_op_compare);
334 if (unlikely (ret == NULL))
335 {
336 __libdw_seterrno (DWARF_E_NOMEM);
337 return NULL;
338 }
339
340 return *ret;
341 }
342
343 static ptrdiff_t
read_macros(Dwarf * dbg,int sec_index,Dwarf_Off macoff,int (* callback)(Dwarf_Macro *,void *),void * arg,ptrdiff_t offset,bool accept_0xff,Dwarf_Die * cudie)344 read_macros (Dwarf *dbg, int sec_index,
345 Dwarf_Off macoff, int (*callback) (Dwarf_Macro *, void *),
346 void *arg, ptrdiff_t offset, bool accept_0xff,
347 Dwarf_Die *cudie)
348 {
349 Elf_Data *d = dbg->sectiondata[sec_index];
350 if (unlikely (d == NULL || d->d_buf == NULL))
351 {
352 __libdw_seterrno (DWARF_E_NO_ENTRY);
353 return -1;
354 }
355
356 if (unlikely (macoff >= d->d_size))
357 {
358 __libdw_seterrno (DWARF_E_INVALID_DWARF);
359 return -1;
360 }
361
362 const unsigned char *const startp = d->d_buf + macoff;
363 const unsigned char *const endp = d->d_buf + d->d_size;
364
365 Dwarf_Macro_Op_Table *table = cache_op_table (dbg, sec_index, macoff,
366 startp, endp, cudie);
367 if (table == NULL)
368 return -1;
369
370 if (offset == 0)
371 offset = table->header_len;
372
373 assert (offset >= 0);
374 assert (offset < endp - startp);
375 const unsigned char *readp = startp + offset;
376
377 while (readp < endp)
378 {
379 unsigned int opcode = *readp++;
380 if (opcode == 0)
381 /* Nothing more to do. */
382 return 0;
383
384 if (unlikely (opcode == 0xff && ! accept_0xff))
385 {
386 /* See comment below at dwarf_getmacros for explanation of
387 why we are doing this. */
388 __libdw_seterrno (DWARF_E_INVALID_OPCODE);
389 return -1;
390 }
391
392 unsigned int idx = table->opcodes[opcode - 1];
393 if (idx == 0xff)
394 {
395 __libdw_seterrno (DWARF_E_INVALID_OPCODE);
396 return -1;
397 }
398
399 Dwarf_Macro_Op_Proto *proto = &table->table[idx];
400
401 /* A fake CU with bare minimum data to fool dwarf_formX into
402 doing the right thing with the attributes that we put out.
403 We pretend it is the same version as the actual table.
404 Version 4 for the old GNU extension, version 5 for DWARF5.
405 To handle DW_FORM_strx[1234] we set the .str_offsets_base
406 from the given CU.
407 XXX We will need to deal with DW_MACRO_import_sup and change
408 out the dbg somehow for the DW_FORM_sec_offset to make sense. */
409 Dwarf_CU fake_cu = {
410 .dbg = dbg,
411 .sec_idx = sec_index,
412 .version = table->version,
413 .offset_size = table->offset_size,
414 .str_off_base = str_offsets_base_off (dbg, (cudie != NULL
415 ? cudie->cu: NULL)),
416 .startp = (void *) startp + offset,
417 .endp = (void *) endp,
418 };
419
420 Dwarf_Attribute *attributes;
421 Dwarf_Attribute *attributesp = NULL;
422 Dwarf_Attribute nattributes[8];
423 if (unlikely (proto->nforms > 8))
424 {
425 attributesp = malloc (sizeof (Dwarf_Attribute) * proto->nforms);
426 if (attributesp == NULL)
427 {
428 __libdw_seterrno (DWARF_E_NOMEM);
429 return -1;
430 }
431 attributes = attributesp;
432 }
433 else
434 attributes = &nattributes[0];
435
436 for (Dwarf_Word i = 0; i < proto->nforms; ++i)
437 {
438 /* We pretend this is a DW_AT[_GNU]_macros attribute so that
439 DW_FORM_sec_offset forms get correctly interpreted as
440 offset into .debug_macro. XXX Deal with DW_MACRO_import_sup
441 (swap .dbg) for DW_FORM_sec_offset? */
442 attributes[i].code = (fake_cu.version == 4 ? DW_AT_GNU_macros
443 : DW_AT_macros);
444 attributes[i].form = proto->forms[i];
445 attributes[i].valp = (void *) readp;
446 attributes[i].cu = &fake_cu;
447
448 /* We don't want forms that aren't allowed because they could
449 read from the "abbrev" like DW_FORM_implicit_const. */
450 if (! libdw_valid_user_form (attributes[i].form))
451 {
452 __libdw_seterrno (DWARF_E_INVALID_DWARF);
453 free (attributesp);
454 return -1;
455 }
456
457 size_t len = __libdw_form_val_len (&fake_cu, proto->forms[i], readp);
458 if (unlikely (len == (size_t) -1))
459 {
460 free (attributesp);
461 return -1;
462 }
463
464 readp += len;
465 }
466
467 Dwarf_Macro macro = {
468 .table = table,
469 .opcode = opcode,
470 .attributes = attributes,
471 };
472
473 int res = callback (¯o, arg);
474 if (unlikely (attributesp != NULL))
475 free (attributesp);
476
477 if (res != DWARF_CB_OK)
478 return readp - startp;
479 }
480
481 return 0;
482 }
483
484 /* Token layout:
485
486 - The highest bit is used for distinguishing between callers that
487 know that opcode 0xff may have one of two incompatible meanings.
488 The mask that we use for selecting this bit is
489 DWARF_GETMACROS_START.
490
491 - The rest of the token (31 or 63 bits) encodes address inside the
492 macro unit.
493
494 Besides, token value of 0 signals end of iteration and -1 is
495 reserved for signaling errors. That means it's impossible to
496 represent maximum offset of a .debug_macro unit to new-style
497 callers (which in practice decreases the permissible macro unit
498 size by another 1 byte). */
499
500 static ptrdiff_t
token_from_offset(ptrdiff_t offset,bool accept_0xff)501 token_from_offset (ptrdiff_t offset, bool accept_0xff)
502 {
503 if (offset == -1 || offset == 0)
504 return offset;
505
506 /* Make sure the offset didn't overflow into the flag bit. */
507 if ((offset & DWARF_GETMACROS_START) != 0)
508 {
509 __libdw_seterrno (DWARF_E_TOO_BIG);
510 return -1;
511 }
512
513 if (accept_0xff)
514 offset |= DWARF_GETMACROS_START;
515
516 return offset;
517 }
518
519 static ptrdiff_t
offset_from_token(ptrdiff_t token,bool * accept_0xffp)520 offset_from_token (ptrdiff_t token, bool *accept_0xffp)
521 {
522 *accept_0xffp = (token & DWARF_GETMACROS_START) != 0;
523 token &= ~DWARF_GETMACROS_START;
524
525 return token;
526 }
527
528 static ptrdiff_t
gnu_macros_getmacros_off(Dwarf * dbg,Dwarf_Off macoff,int (* callback)(Dwarf_Macro *,void *),void * arg,ptrdiff_t offset,bool accept_0xff,Dwarf_Die * cudie)529 gnu_macros_getmacros_off (Dwarf *dbg, Dwarf_Off macoff,
530 int (*callback) (Dwarf_Macro *, void *),
531 void *arg, ptrdiff_t offset, bool accept_0xff,
532 Dwarf_Die *cudie)
533 {
534 assert (offset >= 0);
535
536 if (macoff >= dbg->sectiondata[IDX_debug_macro]->d_size)
537 {
538 __libdw_seterrno (DWARF_E_INVALID_OFFSET);
539 return -1;
540 }
541
542 return read_macros (dbg, IDX_debug_macro, macoff,
543 callback, arg, offset, accept_0xff, cudie);
544 }
545
546 static ptrdiff_t
macro_info_getmacros_off(Dwarf * dbg,Dwarf_Off macoff,int (* callback)(Dwarf_Macro *,void *),void * arg,ptrdiff_t offset,Dwarf_Die * cudie)547 macro_info_getmacros_off (Dwarf *dbg, Dwarf_Off macoff,
548 int (*callback) (Dwarf_Macro *, void *),
549 void *arg, ptrdiff_t offset, Dwarf_Die *cudie)
550 {
551 assert (offset >= 0);
552
553 return read_macros (dbg, IDX_debug_macinfo, macoff,
554 callback, arg, offset, true, cudie);
555 }
556
557 ptrdiff_t
dwarf_getmacros_off(Dwarf * dbg,Dwarf_Off macoff,int (* callback)(Dwarf_Macro *,void *),void * arg,ptrdiff_t token)558 dwarf_getmacros_off (Dwarf *dbg, Dwarf_Off macoff,
559 int (*callback) (Dwarf_Macro *, void *),
560 void *arg, ptrdiff_t token)
561 {
562 if (dbg == NULL)
563 {
564 __libdw_seterrno (DWARF_E_NO_DWARF);
565 return -1;
566 }
567
568 bool accept_0xff;
569 ptrdiff_t offset = offset_from_token (token, &accept_0xff);
570 assert (accept_0xff);
571
572 offset = gnu_macros_getmacros_off (dbg, macoff, callback, arg, offset,
573 accept_0xff, NULL);
574
575 return token_from_offset (offset, accept_0xff);
576 }
577
578 ptrdiff_t
dwarf_getmacros(Dwarf_Die * cudie,int (* callback)(Dwarf_Macro *,void *),void * arg,ptrdiff_t token)579 dwarf_getmacros (Dwarf_Die *cudie, int (*callback) (Dwarf_Macro *, void *),
580 void *arg, ptrdiff_t token)
581 {
582 if (cudie == NULL)
583 {
584 __libdw_seterrno (DWARF_E_NO_DWARF);
585 return -1;
586 }
587
588 /* This function might be called from a code that expects to see
589 DW_MACINFO_* opcodes, not DW_MACRO_{GNU_,}* ones. It is fine to
590 serve most DW_MACRO_{GNU_,}* opcodes to such code, because those
591 whose values are the same as DW_MACINFO_* ones also have the same
592 behavior. It is not very likely that a .debug_macro section
593 would only use the part of opcode space that it shares with
594 .debug_macinfo, but it is possible. Serving the opcodes that are
595 only valid in DW_MACRO_{GNU_,}* domain is OK as well, because
596 clients in general need to be ready that newer standards define
597 more opcodes, and have coping mechanisms for unfamiliar opcodes.
598
599 The one exception to the above rule is opcode 0xff, which has
600 concrete semantics in .debug_macinfo, but falls into vendor block
601 in .debug_macro, and can be assigned to do whatever. There is
602 some small probability that the two opcodes would look
603 superficially similar enough that a client would be confused and
604 misbehave as a result. For this reason, we refuse to serve
605 through this interface 0xff's originating from .debug_macro
606 unless the TOKEN that we obtained indicates the call originates
607 from a new-style caller. See above for details on what
608 information is encoded into tokens. */
609
610 bool accept_0xff;
611 ptrdiff_t offset = offset_from_token (token, &accept_0xff);
612
613 /* DW_AT_macro_info */
614 if (dwarf_hasattr (cudie, DW_AT_macro_info))
615 {
616 Dwarf_Word macoff;
617 if (get_offset_from (cudie, DW_AT_macro_info, &macoff) != 0)
618 return -1;
619 offset = macro_info_getmacros_off (cudie->cu->dbg, macoff,
620 callback, arg, offset, cudie);
621 }
622 else
623 {
624 /* DW_AT_GNU_macros, DW_AT_macros */
625 Dwarf_Word macoff;
626 if (get_offset_from (cudie, DW_AT_GNU_macros, &macoff) != 0
627 && get_offset_from (cudie, DW_AT_macros, &macoff) != 0)
628 return -1;
629 offset = gnu_macros_getmacros_off (cudie->cu->dbg, macoff,
630 callback, arg, offset, accept_0xff,
631 cudie);
632 }
633
634 return token_from_offset (offset, accept_0xff);
635 }
636