Stylistic refactoring. No functional changes
[platform/upstream/ltrace.git] / dwarf_prototypes.c
1 /* Copyright Dima Kogan <dima@secretsauce.net>
2  *
3  * This program is free software; you can redistribute it and/or modify it under
4  * the terms of version 2 of the GNU General Public License as published by the
5  * Free Software Foundation.
6  *
7  */
8 #include <stdio.h>
9 #include <elfutils/libdwfl.h>
10 #include <dwarf.h>
11 #include <stdlib.h>
12 #include <errno.h>
13 #include <string.h>
14
15 #include "config.h"
16 #include "prototype.h"
17 #include "type.h"
18 #include "param.h"
19 #include "dict.h"
20 #include "lens.h"
21 #include "lens_enum.h"
22 #include "value.h"
23 #include "expr.h"
24 #include "library.h"
25 #include "options.h"
26 #include "filter.h"
27
28
29 //#define DUMP_PROTOTYPES
30
31 #if 1
32 #define complain( die, format, ... )                                                    \
33         fprintf(stderr, "%s() die '%s' @ 0x%lx: " format "\n",          \
34                         __func__, dwarf_diename(die), dwarf_dieoffset(die),     \
35                         ##__VA_ARGS__ )
36 #else
37 #define complain( die, format, ... )
38 #endif
39
40 #define NEXT_SIBLING(die)                                                               \
41         int res = dwarf_siblingof(die, die);                            \
42         if (res == 0) continue;     /* sibling exists    */     \
43         if (res < 0)  return false; /* error             */     \
44         break                       /* no sibling exists */
45
46 // A map from DIE addresses (Dwarf_Off) to type structures (struct
47 // arg_type_info*). This is created and filled in at the start of each import,
48 // and deleted when the import is complete
49 static struct dict type_hash;
50
51
52 static bool get_type(struct arg_type_info** info, Dwarf_Die* type_die);
53
54
55 #if 0
56 static bool _dump_dwarf_tree(Dwarf_Die* die, int indent)
57 {
58     while (1) {
59         fprintf(stderr, "%*sprocessing unit: 0x%02x/'%s'\n", indent*4, "",
60                dwarf_tag(die), dwarf_diename(die));
61
62         Dwarf_Die child;
63         if (dwarf_child(die, &child) == 0) {
64                         if (!_dump_dwarf_tree(&child, indent+1))
65                                 return false;
66         }
67
68         SIBLING(die);
69     }
70
71     return true;
72 }
73
74 static bool dump_dwarf_tree(Dwarf_Die* die)
75 {
76     return _dump_dwarf_tree( die, 0 );
77 }
78 #endif
79
80 #ifdef DUMP_PROTOTYPES
81 static bool _dump_ltrace_tree(const struct arg_type_info* info, int indent)
82 {
83         if (indent > 7) {
84                 fprintf(stderr, "%*s%p ...\n", indent*4, "", (void*)info);
85                 return true;
86         }
87
88         if (info == NULL) {
89                 fprintf(stderr, "%*s%p NULL\n", indent*4, "", (void*)info);
90                 return true;
91         }
92
93         switch (info->type) {
94         case ARGTYPE_VOID:
95                 fprintf(stderr, "%*s%p void\n", indent*4, "", (void*)info);
96                 break;
97
98         case ARGTYPE_INT:
99         case ARGTYPE_UINT:
100         case ARGTYPE_LONG:
101         case ARGTYPE_ULONG:
102         case ARGTYPE_CHAR:
103         case ARGTYPE_SHORT:
104         case ARGTYPE_USHORT:
105         case ARGTYPE_FLOAT:
106         case ARGTYPE_DOUBLE:
107                 fprintf(stderr, "%*s%p base\n", indent*4, "", (void*)info);
108                 break;
109
110         case ARGTYPE_ARRAY:
111                 fprintf(stderr, "%*s%p array. elements not printed\n", indent*4, "",
112                                 (void*)info);
113                 break;
114
115         case ARGTYPE_POINTER:
116                 fprintf(stderr, "%*s%p pointer to...\n", indent*4, "", (void*)info);
117                 _dump_ltrace_tree( info->u.ptr_info.info, indent+1 );
118                 break;
119
120         case ARGTYPE_STRUCT:
121                 fprintf(stderr, "%*s%p struct...\n", indent*4, "", (void*)info);
122                 struct struct_field
123                 {
124                         struct arg_type_info *info;
125                         int own_info;
126                 }* elements = (struct struct_field*)info->u.entries.data;
127                 unsigned int i;
128                 for(i=0; i<info->u.entries.size; i++)
129                         _dump_ltrace_tree( elements[i].info, indent+1 );
130                 break;
131
132         default:
133                 fprintf(stderr, "%*s%p unknown type\n", indent*4, "", (void*)info);
134                 return false;;
135         }
136
137         return true;
138 }
139
140 static bool dump_ltrace_tree(const struct arg_type_info* info)
141 {
142         return _dump_ltrace_tree( info, 0 );
143 }
144 #endif
145
146
147 // pulls a numerical value out of a particular attribute in a die. Returns true
148 // if successful. The result is returned in *result. Note that this is cast to
149 // (uint64_t), regardless of the actual type of the input
150 static bool get_die_numeric(uint64_t* result,
151                                                         Dwarf_Die *die, unsigned int attr_name)
152 {
153         Dwarf_Attribute attr ;
154
155         union {
156                 Dwarf_Word              udata;
157                 Dwarf_Sword     sdata;
158                 Dwarf_Addr              addr;
159                 bool                    flag;
160         } u;
161
162         if (dwarf_attr(die, attr_name, &attr) == NULL)
163                 return false;
164
165         unsigned int form = dwarf_whatform(&attr);
166
167 #define PROCESS_NUMERIC(type)                                           \
168         if (dwarf_form ## type(&attr, &u.type) != 0)    \
169                 return false;                                                           \
170         *result = (uint64_t)u.type;                                             \
171         return true
172
173
174         switch (form) {
175         case DW_FORM_addr:
176                 PROCESS_NUMERIC(addr);
177
178         case DW_FORM_data1:
179         case DW_FORM_data2:
180         case DW_FORM_data4:
181         case DW_FORM_data8:
182         case DW_FORM_udata:
183                 PROCESS_NUMERIC(udata);
184
185         case DW_FORM_sdata:
186                 PROCESS_NUMERIC(sdata);
187
188         case DW_FORM_flag:
189                 PROCESS_NUMERIC(flag);
190
191         default:
192                 complain(die, "Unknown numeric form %d for attr_name: %d", form, attr_name);
193                 return false;
194         }
195 #undef PROCESS_NUMERIC
196 }
197
198 static bool get_integer_base_type(enum arg_type* type, int byte_size, bool is_signed)
199 {
200         switch (byte_size) {
201         case sizeof(char):
202                 *type = ARGTYPE_CHAR;
203                 return true;
204
205         case sizeof(short):
206                 *type = is_signed ? ARGTYPE_SHORT : ARGTYPE_USHORT;
207                 return true;
208
209         case sizeof(int):
210                 *type = is_signed ? ARGTYPE_INT : ARGTYPE_UINT;
211                 return true;
212
213         case sizeof(long):
214                 *type = is_signed ? ARGTYPE_LONG : ARGTYPE_ULONG;
215                 return true;
216
217         default:
218                 return false;
219         }
220 }
221
222 static enum arg_type get_base_type(Dwarf_Die* die)
223 {
224         int64_t encoding;
225         if( !get_die_numeric((uint64_t*)&encoding, die, DW_AT_encoding))
226                 return ARGTYPE_VOID;
227
228         if (encoding == DW_ATE_void)
229                 return ARGTYPE_VOID;
230
231         if (encoding == DW_ATE_signed_char || encoding == DW_ATE_unsigned_char)
232                 return ARGTYPE_CHAR;
233
234                 uint64_t byte_size;
235                 if (!get_die_numeric(&byte_size, die, DW_AT_byte_size))
236                         return ARGTYPE_VOID;
237
238         if (encoding == DW_ATE_signed   ||
239                 encoding == DW_ATE_unsigned ||
240                 encoding == DW_ATE_boolean) {
241
242                 bool is_signed = (encoding == DW_ATE_signed);
243
244                 enum arg_type type;
245                 if(!get_integer_base_type(&type, (int)byte_size, is_signed)) {
246                         complain(die, "Unknown integer base type. Using 'void'");
247                         return ARGTYPE_VOID;
248                 }
249                 return type;
250         }
251
252         if (encoding == DW_ATE_float) {
253                 switch (byte_size) {
254                 case sizeof(float):
255                         return ARGTYPE_FLOAT;
256
257                 case sizeof(double):
258                         return ARGTYPE_DOUBLE;
259
260                 default:
261                         // things like long doubles. ltrace has no support yet, so I just
262                         // say "void"
263                         return ARGTYPE_VOID;
264                 }
265         }
266
267 #if 0
268         if (encoding == DW_ATE_complex_float) {
269                 switch (byte_size) {
270                 case 2*sizeof(float):
271                         return ARGTYPE_FLOAT;
272
273                 case 2*sizeof(double):
274                         return ARGTYPE_DOUBLE;
275
276                 default:
277                         // things like long doubles. ltrace has no support yet, so I just
278                         // say "void"
279                         return ARGTYPE_VOID;
280                 }
281         }
282 #endif
283
284         // Unknown encoding. I just say void
285         complain(die, "Unknown base type. Returning 'void'");
286         return ARGTYPE_VOID;
287 }
288
289 static bool get_type_die(Dwarf_Die* type_die, Dwarf_Die* die)
290 {
291         Dwarf_Attribute attr;
292         return
293                 dwarf_attr(die, DW_AT_type, &attr) != NULL &&
294                 dwarf_formref_die(&attr, type_die) != NULL;
295 }
296
297 static size_t dwarf_die_hash(const void* x)
298 {
299         return *(const Dwarf_Off*)x;
300 }
301 static int dwarf_die_eq(const void* a, const void* b)
302 {
303         return *(const Dwarf_Off*)a == *(const Dwarf_Off*)b;
304 }
305
306 static bool get_enum(struct arg_type_info* enum_info, Dwarf_Die* parent)
307 {
308         uint64_t byte_size;
309         if (!get_die_numeric(&byte_size, parent, DW_AT_byte_size)) {
310                 // No byte size given, assume 'int'
311                 enum_info->type = ARGTYPE_INT;
312         } else {
313                 if(!get_integer_base_type(&enum_info->type, (int)byte_size, true)) {
314                         complain(parent, "Unknown integer base type. Using 'int'");
315                         enum_info->type = ARGTYPE_INT;
316                 }
317         }
318
319         struct enum_lens *lens = calloc(1, sizeof(struct enum_lens));
320         if (lens == NULL) {
321                 complain(parent, "alloc error");
322                 return false;
323         }
324         lens_init_enum(lens);
325         enum_info->lens = &lens->super;
326
327         Dwarf_Die die;
328         if (dwarf_child(parent, &die) != 0) {
329                 // empty enum. we're done
330                 return true;
331         }
332
333         while(1) {
334                 complain(&die, "enum element: 0x%02x/'%s'", dwarf_tag(&die),
335                                  dwarf_diename(&die));
336
337                 if (dwarf_tag(&die) != DW_TAG_enumerator) {
338                         complain(&die, "Enums can have ONLY DW_TAG_enumerator elements");
339                         return false;
340                 }
341
342                 if (!dwarf_hasattr(&die, DW_AT_const_value)) {
343                         complain(&die, "Enums MUST have DW_AT_const_value values");
344                         return false;
345                 }
346
347                 const char* key = dwarf_diename(&die);
348                 if (key == NULL) {
349                         complain(&die, "Enums must have a DW_AT_name key");
350                         return false;
351                 }
352                 const char* dupkey = strdup(key);
353                 if (dupkey == NULL) {
354                         complain(&die, "Couldn't duplicate enum key");
355                         return false;
356                 }
357
358                 struct value* value = calloc( 1, sizeof(struct value));
359                 if (value == NULL) {
360                         complain(&die, "Couldn't alloc enum value");
361                         return false;
362                 }
363
364                 value_init_detached(value, NULL, type_get_simple( enum_info->type ), 0);
365                 uint64_t enum_value;
366                 if (!get_die_numeric(&enum_value, &die, DW_AT_const_value)) {
367                         complain(&die, "Couldn't get enum value");
368                         return false;
369                 }
370
371                 value_set_word(value, (long)enum_value);
372
373                 if (lens_enum_add( lens, dupkey, 0, value, 0 )) {
374                         complain(&die, "Couldn't add enum element");
375                         return false;
376                 }
377
378                 NEXT_SIBLING(&die);
379         }
380
381         return true;
382 }
383
384 static bool get_array(struct arg_type_info* array_info, Dwarf_Die* parent)
385 {
386         Dwarf_Die type_die;
387         if (!get_type_die( &type_die, parent )) {
388                 complain( parent, "Array has unknown type" );
389                 return false;
390         }
391
392         struct arg_type_info* info;
393         if (!get_type( &info, &type_die )) {
394                 complain( parent, "Couldn't figure out array's type" );
395                 return false;
396         }
397
398         Dwarf_Die subrange;
399         if (dwarf_child(parent, &subrange) != 0) {
400                 complain(parent,
401                                  "Array must have a DW_TAG_subrange_type child, but has none");
402                 return false;
403         }
404
405         Dwarf_Die next_subrange;
406         if (dwarf_siblingof(&subrange, &next_subrange) <= 0) {
407                 complain(parent,
408                                  "Array must have exactly one DW_TAG_subrange_type child");
409                 return false;
410         }
411
412         if (dwarf_hasattr(&subrange, DW_AT_lower_bound)) {
413                 uint64_t lower_bound;
414                 if (!get_die_numeric(&lower_bound, &subrange, DW_AT_lower_bound)) {
415                         complain( parent, "Couldn't read lower bound");
416                         return false;
417                 }
418
419                 if (lower_bound != 0) {
420                         complain( parent,
421                                           "Array subrange has a nonzero lower bound. Don't know what to do");
422                         return false;
423                 }
424         }
425
426         uint64_t N;
427         if (!dwarf_hasattr(&subrange, DW_AT_upper_bound)) {
428                 // no upper bound is defined. This is probably a variable-width array,
429                 // and I don't know how long it is. Let's say 0 to be safe
430                 N = 0;
431         }
432         else
433         {
434                 if (!get_die_numeric(&N, &subrange, DW_AT_upper_bound)) {
435                         complain( parent, "Couldn't read upper bound");
436                         return false;
437                 }
438                 N++;
439         }
440
441         // I'm not checking the subrange type. It should be some sort of integer,
442         // and I don't know what it would mean for it to be something else
443
444         struct value* value = calloc( 1, sizeof(struct value));
445         if (value == NULL) {
446                 complain(&subrange, "Couldn't alloc length value");
447                 return false;
448         }
449         value_init_detached(value, NULL, type_get_simple( ARGTYPE_INT ), 0);
450         value_set_word(value, N );
451
452         struct expr_node* length = calloc( 1, sizeof(struct expr_node));
453         if (length == NULL) {
454                 complain(&subrange, "Couldn't alloc length expr");
455                 return false;
456         }
457         expr_init_const(length, value);
458
459         type_init_array(array_info, info, 0, length, 0 );
460
461         return true;
462 }
463
464 static bool get_structure(struct arg_type_info* struct_info, Dwarf_Die* parent)
465 {
466         type_init_struct(struct_info);
467
468         Dwarf_Die die;
469         if (dwarf_child(parent, &die) != 0) {
470                 // no elements; we're done
471                 return true;
472         }
473
474         while(1) {
475                 complain(&die, "member: 0x%02x", dwarf_tag(&die));
476
477                 if (dwarf_tag(&die) != DW_TAG_member) {
478                         complain(&die, "Structure can have ONLY DW_TAG_member");
479                         return false;
480                 }
481
482                 Dwarf_Die type_die;
483                 if (!get_type_die( &type_die, &die )) {
484                         complain( &die, "Couldn't get type of element");
485                         return false;
486                 }
487
488                 struct arg_type_info* member_info = NULL;
489                 if (!get_type( &member_info, &type_die )) {
490                         complain(&die, "Couldn't parse type from DWARF data");
491                         return false;
492                 }
493                 type_struct_add( struct_info, member_info, 0 );
494
495                 NEXT_SIBLING(&die);
496         }
497
498         return true;
499 }
500
501 // Reads the type in the die into the given structure
502 // Returns true on sucess
503 static bool get_type(struct arg_type_info** info, Dwarf_Die* type_die)
504 {
505         Dwarf_Off die_offset = dwarf_dieoffset(type_die);
506         struct arg_type_info** found_type = dict_find(&type_hash, &die_offset );
507         if (found_type != NULL) {
508                 *info = *found_type;
509                 complain(type_die, "Read pre-computed type: %p", *info);
510                 return true;
511         }
512
513         Dwarf_Die next_die;
514
515         switch (dwarf_tag(type_die)) {
516         case DW_TAG_base_type:
517                 *info = type_get_simple( get_base_type( type_die ));
518                 complain(type_die, "Storing base type: %p", *info);
519                 dict_insert( &type_hash, &die_offset, info );
520                 return true;
521
522         case DW_TAG_subroutine_type:
523         case DW_TAG_inlined_subroutine:
524                 // function pointers are stored as void*. If ltrace tries to dereference
525                 // these, it'll get a segfault
526                 *info = type_get_simple( ARGTYPE_VOID );
527                 complain(type_die, "Storing subroutine type: %p", *info);
528                 dict_insert( &type_hash, &die_offset, info );
529                 return true;
530
531         case DW_TAG_pointer_type:
532
533                 if (!get_type_die(&next_die, type_die )) {
534                         // the pointed-to type isn't defined, so I report a void*
535                         *info = type_get_simple( ARGTYPE_VOID );
536                         complain(type_die, "Storing void-pointer type: %p", *info);
537                         dict_insert( &type_hash, &die_offset, info );
538                         return true;
539                 }
540
541                 *info = calloc( 1, sizeof(struct arg_type_info));
542                 if (*info == NULL) {
543                         complain(type_die, "alloc error");
544                         return false;
545                 }
546                 type_init_pointer(*info, NULL, 0);
547
548                 complain(type_die, "Storing pointer type: %p", *info);
549                 dict_insert( &type_hash, &die_offset, info );
550                 return get_type( &(*info)->u.ptr_info.info, &next_die );
551
552         case DW_TAG_structure_type:
553                 *info = calloc( 1, sizeof(struct arg_type_info));
554                 if (*info == NULL) {
555                         complain(type_die, "alloc error");
556                         return false;
557                 }
558
559                 complain(type_die, "Storing struct type: %p", *info);
560                 dict_insert( &type_hash, &die_offset, info );
561                 return get_structure( *info, type_die );
562
563
564         case DW_TAG_typedef:
565         case DW_TAG_const_type:
566         case DW_TAG_volatile_type: {
567                 // Various tags are simply pass-through, so I just keep going
568                 bool res = true;
569                 if (get_type_die(&next_die, type_die )) {
570                         complain(type_die, "Storing const/typedef type: %p", *info);
571                         res = get_type( info, &next_die );
572                 } else {
573                         // no type. Use 'void'. Normally I'd think this is bogus, but stdio
574                         // typedefs something to void
575                         *info = type_get_simple( ARGTYPE_VOID );
576                         complain(type_die, "Storing void type: %p", *info);
577                 }
578                 if (res)
579                         dict_insert( &type_hash, &die_offset, info );
580                 return res;
581         }
582
583         case DW_TAG_enumeration_type:
584                 // We have an enumeration. This has type "int", but has a particular
585                 // lens to handle the enum
586                 *info = calloc( 1, sizeof(struct arg_type_info));
587                 if (*info == NULL) {
588                         complain(type_die, "alloc error");
589                         return false;
590                 }
591
592                 complain(type_die, "Storing enum int: %p", *info);
593                 dict_insert( &type_hash, &die_offset, info );
594                 return get_enum( *info, type_die );
595
596         case DW_TAG_array_type:
597                 *info = calloc( 1, sizeof(struct arg_type_info));
598                 if (*info == NULL) {
599                         complain(type_die, "alloc error");
600                         return false;
601                 }
602
603                 complain(type_die, "Storing array: %p", *info);
604                 dict_insert( &type_hash, &die_offset, info );
605                 return get_array( *info, type_die );
606
607         case DW_TAG_union_type:
608                 *info = type_get_simple( ARGTYPE_VOID );
609                 complain(type_die, "Storing union-as-void type: %p", *info);
610                 return true;
611
612         default:
613                 complain(type_die, "Unknown type tag 0x%x", dwarf_tag(type_die));
614                 break;
615         }
616
617         return false;
618 }
619
620 static bool get_prototype(struct prototype* proto, Dwarf_Die* subroutine)
621 {
622         // First, look at the return type. This is stored in a DW_AT_type tag in the
623         // subroutine DIE. If there is no such tag, this function returns void
624         Dwarf_Die return_type_die;
625         if (!get_type_die(&return_type_die, subroutine )) {
626                 proto->return_info = type_get_simple( ARGTYPE_VOID );
627                 proto->own_return_info = 0;
628         } else {
629                 proto->return_info = calloc( 1, sizeof( struct arg_type_info ));
630                 if (proto->return_info == NULL) {
631                         complain(subroutine, "Couldn't alloc return type");
632                         return false;
633                 }
634                 proto->own_return_info = 0;
635
636                 if (!get_type( &proto->return_info, &return_type_die )) {
637                         complain(subroutine, "Couldn't get return type");
638                         return false;
639                 }
640         }
641
642
643         // Now look at the arguments
644         Dwarf_Die arg_die;
645         if (dwarf_child(subroutine, &arg_die) != 0) {
646                 // no args. We're done
647                 return true;
648         }
649
650         while(1) {
651                 if (dwarf_tag(&arg_die) == DW_TAG_formal_parameter) {
652
653                         complain(&arg_die, "arg: 0x%02x", dwarf_tag(&arg_die));
654
655                         Dwarf_Die type_die;
656                         if (!get_type_die(&type_die, &arg_die )) {
657                                 complain(&arg_die, "Couldn't get the argument type die");
658                                 return false;
659                         }
660
661                         struct arg_type_info* arg_type_info = NULL;
662                         if (!get_type( &arg_type_info, &type_die )) {
663                                 complain(&arg_die, "Couldn't parse arg type from DWARF data");
664                                 return false;
665                         }
666
667                         struct param param;
668                         param_init_type(&param, arg_type_info, 0);
669                         if (prototype_push_param(proto, &param) <0) {
670                                 complain(&arg_die, "couldn't add argument to the prototype");
671                                 return false;
672                         }
673
674 #ifdef DUMP_PROTOTYPES
675                         fprintf(stderr, "Adding argument:\n");
676                         dump_ltrace_tree(arg_type_info);
677 #endif
678                 }
679
680                 NEXT_SIBLING(&arg_die);
681         }
682
683         return true;
684 }
685
686 static bool import_subprogram(struct protolib* plib, struct library* lib,
687                                                           Dwarf_Die* die)
688 {
689         // I use the linkage function name if there is one, otherwise the
690         // plain name
691         const char* function_name = NULL;
692         Dwarf_Attribute attr;
693         if (dwarf_attr(die, DW_AT_linkage_name, &attr) != NULL)
694                 function_name = dwarf_formstring(&attr);
695         if (function_name == NULL)
696                 function_name = dwarf_diename(die);
697         if (function_name == NULL) {
698                 complain(die, "Function has no name. Not importing" );
699                 return true;
700         }
701
702
703         complain(die, "subroutine_type: 0x%02x; function '%s'",
704                          dwarf_tag(die), function_name);
705
706         struct prototype* proto =
707                 protolib_lookup_prototype(plib, function_name, false );
708
709         if (proto != NULL) {
710                 complain(die, "Prototype already exists. Skipping");
711                 return true;
712         }
713
714         if (!filter_matches_symbol(options.plt_filter,    function_name, lib) &&
715                 !filter_matches_symbol(options.static_filter, function_name, lib) &&
716                 !filter_matches_symbol(options.export_filter, function_name, lib)) {
717                 complain(die, "Prototype not requested by any filter");
718                 return true;
719         }
720
721         proto = malloc(sizeof(struct prototype));
722         if (proto == NULL) {
723                 complain(die, "couldn't alloc prototype");
724                 return false;
725         }
726         prototype_init( proto );
727
728         if (!get_prototype(proto, die )) {
729                 complain(die, "couldn't get prototype");
730                 return false;
731         }
732
733         protolib_add_prototype(plib, function_name, 0, proto);
734         return true;
735 }
736
737 static bool process_die_compileunit(struct protolib* plib, struct library* lib,
738                                                                         Dwarf_Die* parent)
739 {
740         Dwarf_Die die;
741         if (dwarf_child(parent, &die) != 0) {
742                 // no child nodes, so nothing to do
743                 return true;
744         }
745
746         while (1) {
747                 if (dwarf_tag(&die) == DW_TAG_subprogram)
748                         if(!import_subprogram(plib, lib, &die))
749                                 return false;
750
751                 NEXT_SIBLING(&die);
752         }
753
754         return true;
755 }
756
757 static bool import(struct protolib* plib, struct library* lib, Dwfl* dwfl)
758 {
759         dict_init(&type_hash, sizeof(Dwarf_Off), sizeof(struct arg_type_info*),
760                           dwarf_die_hash, dwarf_die_eq, NULL );
761
762         Dwarf_Addr bias;
763     Dwarf_Die* die = NULL;
764     while ((die = dwfl_nextcu(dwfl, die, &bias)) != NULL) {
765         if (dwarf_tag(die) == DW_TAG_compile_unit) {
766             if (!process_die_compileunit(plib, lib, die)) {
767                 complain(die, "Error reading compile unit");
768                                 exit(1);
769                                 return false;
770             }
771         } else {
772             complain(die, "DW_TAG_compile_unit expected");
773                         exit(1);
774             return false;
775         }
776     }
777
778         dict_destroy( &type_hash, NULL, NULL, NULL );
779         return true;
780 }
781
782 bool import_DWARF_prototypes(struct protolib* plib, struct library* lib,
783                                                          Dwfl *dwfl)
784 {
785         if (plib == NULL) {
786                 plib = protolib_cache_default(&g_protocache, lib->soname, 0);
787                 if (plib == NULL) {
788                         fprintf(stderr, "Error loading protolib %s: %s.\n",
789                                         lib->soname, strerror(errno));
790                 }
791         }
792
793         return import(plib, lib, dwfl);
794 }
795
796 /*
797 - I handle static functions now. Should I? Those do not have DW_AT_external==1
798
799 - should process existing prototypes to make sure they match
800
801 - what do function pointers look like? I'm doing void*
802
803 - unions
804
805 - all my *allocs leak
806
807
808 */