740368ef09aa0cceaf2b2397beebd69422a3efc8
[platform/upstream/elfutils.git] / libdw / dwarf_getmacros.c
1 /* Get macro information.
2    Copyright (C) 2002-2009, 2014 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 <assert.h>
35 #include <dwarf.h>
36 #include <search.h>
37 #include <stdlib.h>
38 #include <string.h>
39
40 #include <libdwP.h>
41
42 static int
43 get_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
54 static int
55 macro_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
73 static void
74 build_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
91 enum { macinfo_data_size = offsetof (Dwarf_Macro_Op_Table, table[5]) };
92 static unsigned char macinfo_data[macinfo_data_size]
93         __attribute__ ((aligned (__alignof (Dwarf_Macro_Op_Table))));
94
95 static __attribute__ ((constructor)) void
96 init_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
119 static Dwarf_Macro_Op_Table *
120 get_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
143 static Dwarf_Macro_Op_Table *
144 get_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           if (readp >= endp)
219             goto invalid;
220           get_uleb128 (e.nforms, readp, endp);
221           e.forms = readp;
222           op_protos[opcode - 1] = e;
223
224           readp += e.nforms;
225           if (readp > endp)
226             {
227             invalid:
228               __libdw_seterrno (DWARF_E_INVALID_DWARF);
229               return NULL;
230             }
231         }
232     }
233
234   size_t ct = 0;
235   for (unsigned i = 1; i < 256; ++i)
236     if (op_protos[i - 1].forms != NULL)
237       ++ct;
238
239   /* We support at most 0xfe opcodes defined in the table, as 0xff is
240      a value that means that given opcode is not stored at all.  But
241      that should be fine, as opcode 0 is not allocated.  */
242   assert (ct < 0xff);
243
244   size_t macop_table_size = offsetof (Dwarf_Macro_Op_Table, table[ct]);
245
246   Dwarf_Macro_Op_Table *table = libdw_alloc (dbg, Dwarf_Macro_Op_Table,
247                                              macop_table_size, 1);
248
249   *table = (Dwarf_Macro_Op_Table) {
250     .offset = macoff,
251     .sec_index = IDX_debug_macro,
252     .line_offset = line_offset,
253     .header_len = readp - startp,
254     .version = version,
255     .is_64bit = is_64bit,
256
257     /* NULL if CUDIE is NULL or DW_AT_comp_dir is absent.  */
258     .comp_dir = __libdw_getcompdir (cudie),
259   };
260   build_table (table, op_protos);
261
262   return table;
263 }
264
265 static Dwarf_Macro_Op_Table *
266 cache_op_table (Dwarf *dbg, int sec_index, Dwarf_Off macoff,
267                 const unsigned char *startp,
268                 const unsigned char *const endp,
269                 Dwarf_Die *cudie)
270 {
271   Dwarf_Macro_Op_Table fake = { .offset = macoff, .sec_index = sec_index };
272   Dwarf_Macro_Op_Table **found = tfind (&fake, &dbg->macro_ops,
273                                         macro_op_compare);
274   if (found != NULL)
275     return *found;
276
277   Dwarf_Macro_Op_Table *table = sec_index == IDX_debug_macro
278     ? get_table_for_offset (dbg, macoff, startp, endp, cudie)
279     : get_macinfo_table (dbg, macoff, cudie);
280
281   if (table == NULL)
282     return NULL;
283
284   Dwarf_Macro_Op_Table **ret = tsearch (table, &dbg->macro_ops,
285                                         macro_op_compare);
286   if (unlikely (ret == NULL))
287     {
288       __libdw_seterrno (DWARF_E_NOMEM);
289       return NULL;
290     }
291
292   return *ret;
293 }
294
295 static ptrdiff_t
296 read_macros (Dwarf *dbg, int sec_index,
297              Dwarf_Off macoff, int (*callback) (Dwarf_Macro *, void *),
298              void *arg, ptrdiff_t offset, bool accept_0xff,
299              Dwarf_Die *cudie)
300 {
301   Elf_Data *d = dbg->sectiondata[sec_index];
302   if (unlikely (d == NULL || d->d_buf == NULL))
303     {
304       __libdw_seterrno (DWARF_E_NO_ENTRY);
305       return -1;
306     }
307
308   if (unlikely (macoff >= d->d_size))
309     {
310       __libdw_seterrno (DWARF_E_INVALID_DWARF);
311       return -1;
312     }
313
314   const unsigned char *const startp = d->d_buf + macoff;
315   const unsigned char *const endp = d->d_buf + d->d_size;
316
317   Dwarf_Macro_Op_Table *table = cache_op_table (dbg, sec_index, macoff,
318                                                 startp, endp, cudie);
319   if (table == NULL)
320     return -1;
321
322   if (offset == 0)
323     offset = table->header_len;
324
325   assert (offset >= 0);
326   assert (offset < endp - startp);
327   const unsigned char *readp = startp + offset;
328
329   while (readp < endp)
330     {
331       unsigned int opcode = *readp++;
332       if (opcode == 0)
333         /* Nothing more to do.  */
334         return 0;
335
336       if (unlikely (opcode == 0xff && ! accept_0xff))
337         {
338           /* See comment below at dwarf_getmacros for explanation of
339              why we are doing this.  */
340           __libdw_seterrno (DWARF_E_INVALID_OPCODE);
341           return -1;
342         }
343
344       unsigned int idx = table->opcodes[opcode - 1];
345       if (idx == 0xff)
346         {
347           __libdw_seterrno (DWARF_E_INVALID_OPCODE);
348           return -1;
349         }
350
351       Dwarf_Macro_Op_Proto *proto = &table->table[idx];
352
353       /* A fake CU with bare minimum data to fool dwarf_formX into
354          doing the right thing with the attributes that we put out.
355          We arbitrarily pretend it's version 4.  */
356       Dwarf_CU fake_cu = {
357         .dbg = dbg,
358         .version = 4,
359         .offset_size = table->is_64bit ? 8 : 4,
360         .startp = (void *) startp + offset,
361         .endp = (void *) endp,
362       };
363
364       Dwarf_Attribute *attributes;
365       Dwarf_Attribute *attributesp = NULL;
366       Dwarf_Attribute nattributes[8];
367       if (unlikely (proto->nforms > 8))
368         {
369           attributesp = malloc (sizeof (Dwarf_Attribute) * proto->nforms);
370           if (attributesp == NULL)
371             {
372               __libdw_seterrno (DWARF_E_NOMEM);
373               return -1;
374             }
375           attributes = attributesp;
376         }
377       else
378         attributes = &nattributes[0];
379
380       for (Dwarf_Word i = 0; i < proto->nforms; ++i)
381         {
382           /* We pretend this is a DW_AT_GNU_macros attribute so that
383              DW_FORM_sec_offset forms get correctly interpreted as
384              offset into .debug_macro.  */
385           attributes[i].code = DW_AT_GNU_macros;
386           attributes[i].form = proto->forms[i];
387           attributes[i].valp = (void *) readp;
388           attributes[i].cu = &fake_cu;
389
390           size_t len = __libdw_form_val_len (&fake_cu, proto->forms[i], readp);
391           if (unlikely (len == (size_t) -1))
392             {
393               free (attributesp);
394               return -1;
395             }
396
397           readp += len;
398         }
399
400       Dwarf_Macro macro = {
401         .table = table,
402         .opcode = opcode,
403         .attributes = attributes,
404       };
405
406       int res = callback (&macro, arg);
407       if (unlikely (attributesp != NULL))
408         free (attributesp);
409
410       if (res != DWARF_CB_OK)
411         return readp - startp;
412     }
413
414   return 0;
415 }
416
417 /* Token layout:
418
419    - The highest bit is used for distinguishing between callers that
420      know that opcode 0xff may have one of two incompatible meanings.
421      The mask that we use for selecting this bit is
422      DWARF_GETMACROS_START.
423
424    - The rest of the token (31 or 63 bits) encodes address inside the
425      macro unit.
426
427    Besides, token value of 0 signals end of iteration and -1 is
428    reserved for signaling errors.  That means it's impossible to
429    represent maximum offset of a .debug_macro unit to new-style
430    callers (which in practice decreases the permissible macro unit
431    size by another 1 byte).  */
432
433 static ptrdiff_t
434 token_from_offset (ptrdiff_t offset, bool accept_0xff)
435 {
436   if (offset == -1 || offset == 0)
437     return offset;
438
439   /* Make sure the offset didn't overflow into the flag bit.  */
440   if ((offset & DWARF_GETMACROS_START) != 0)
441     {
442       __libdw_seterrno (DWARF_E_TOO_BIG);
443       return -1;
444     }
445
446   if (accept_0xff)
447     offset |= DWARF_GETMACROS_START;
448
449   return offset;
450 }
451
452 static ptrdiff_t
453 offset_from_token (ptrdiff_t token, bool *accept_0xffp)
454 {
455   *accept_0xffp = (token & DWARF_GETMACROS_START) != 0;
456   token &= ~DWARF_GETMACROS_START;
457
458   return token;
459 }
460
461 static ptrdiff_t
462 gnu_macros_getmacros_off (Dwarf *dbg, Dwarf_Off macoff,
463                           int (*callback) (Dwarf_Macro *, void *),
464                           void *arg, ptrdiff_t offset, bool accept_0xff,
465                           Dwarf_Die *cudie)
466 {
467   assert (offset >= 0);
468
469   if (macoff >= dbg->sectiondata[IDX_debug_macro]->d_size)
470     {
471       __libdw_seterrno (DWARF_E_INVALID_OFFSET);
472       return -1;
473     }
474
475   return read_macros (dbg, IDX_debug_macro, macoff,
476                       callback, arg, offset, accept_0xff, cudie);
477 }
478
479 static ptrdiff_t
480 macro_info_getmacros_off (Dwarf *dbg, Dwarf_Off macoff,
481                           int (*callback) (Dwarf_Macro *, void *),
482                           void *arg, ptrdiff_t offset, Dwarf_Die *cudie)
483 {
484   assert (offset >= 0);
485
486   return read_macros (dbg, IDX_debug_macinfo, macoff,
487                       callback, arg, offset, true, cudie);
488 }
489
490 ptrdiff_t
491 dwarf_getmacros_off (Dwarf *dbg, Dwarf_Off macoff,
492                      int (*callback) (Dwarf_Macro *, void *),
493                      void *arg, ptrdiff_t token)
494 {
495   if (dbg == NULL)
496     {
497       __libdw_seterrno (DWARF_E_NO_DWARF);
498       return -1;
499     }
500
501   bool accept_0xff;
502   ptrdiff_t offset = offset_from_token (token, &accept_0xff);
503   assert (accept_0xff);
504
505   offset = gnu_macros_getmacros_off (dbg, macoff, callback, arg, offset,
506                                      accept_0xff, NULL);
507
508   return token_from_offset (offset, accept_0xff);
509 }
510
511 ptrdiff_t
512 dwarf_getmacros (cudie, callback, arg, token)
513      Dwarf_Die *cudie;
514      int (*callback) (Dwarf_Macro *, void *);
515      void *arg;
516      ptrdiff_t token;
517 {
518   if (cudie == NULL)
519     {
520       __libdw_seterrno (DWARF_E_NO_DWARF);
521       return -1;
522     }
523
524   /* This function might be called from a code that expects to see
525      DW_MACINFO_* opcodes, not DW_MACRO_{GNU_,}* ones.  It is fine to
526      serve most DW_MACRO_{GNU_,}* opcodes to such code, because those
527      whose values are the same as DW_MACINFO_* ones also have the same
528      behavior.  It is not very likely that a .debug_macro section
529      would only use the part of opcode space that it shares with
530      .debug_macinfo, but it is possible.  Serving the opcodes that are
531      only valid in DW_MACRO_{GNU_,}* domain is OK as well, because
532      clients in general need to be ready that newer standards define
533      more opcodes, and have coping mechanisms for unfamiliar opcodes.
534
535      The one exception to the above rule is opcode 0xff, which has
536      concrete semantics in .debug_macinfo, but falls into vendor block
537      in .debug_macro, and can be assigned to do whatever.  There is
538      some small probability that the two opcodes would look
539      superficially similar enough that a client would be confused and
540      misbehave as a result.  For this reason, we refuse to serve
541      through this interface 0xff's originating from .debug_macro
542      unless the TOKEN that we obtained indicates the call originates
543      from a new-style caller.  See above for details on what
544      information is encoded into tokens.  */
545
546   bool accept_0xff;
547   ptrdiff_t offset = offset_from_token (token, &accept_0xff);
548
549   /* DW_AT_macro_info */
550   if (dwarf_hasattr (cudie, DW_AT_macro_info))
551     {
552       Dwarf_Word macoff;
553       if (get_offset_from (cudie, DW_AT_macro_info, &macoff) != 0)
554         return -1;
555       offset = macro_info_getmacros_off (cudie->cu->dbg, macoff,
556                                          callback, arg, offset, cudie);
557     }
558   else
559     {
560       /* DW_AT_GNU_macros, DW_AT_macros */
561       Dwarf_Word macoff;
562       if (get_offset_from (cudie, DW_AT_GNU_macros, &macoff) != 0)
563         return -1;
564       offset = gnu_macros_getmacros_off (cudie->cu->dbg, macoff,
565                                          callback, arg, offset, accept_0xff,
566                                          cudie);
567     }
568
569   return token_from_offset (offset, accept_0xff);
570 }