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