collect-aros: Fix the BFD backend
[AROS.git] / tools / collect-aros / backend-bfd.c
blob44be1ca2d4882745670aa7eda55aa72ef2c04ee8
1 #include <bfd.h>
2 #include <string.h>
3 #include <malloc.h>
4 #include <stdlib.h>
6 #include "misc.h"
7 #include "backend.h"
9 static void bfd_fatal(const char *msg)
11 fatal(msg, bfd_errmsg(bfd_get_error()));
14 int check_and_print_undefined_symbols(const char *file)
16 bfd_byte *cur, *minisyms;
17 asymbol *store;
18 long symcount;
19 unsigned int size;
20 int there_are_undefined_syms = 0;
21 bfd *abfd;
23 bfd_init();
27 (abfd = bfd_openr(file, "default")) == NULL ||
28 !bfd_check_format(abfd, bfd_object)
31 bfd_fatal(file);
34 symcount = bfd_read_minisymbols(abfd, FALSE, (void **)&minisyms, &size);
35 if (symcount < 0)
36 bfd_fatal (bfd_get_filename (abfd));
38 if (symcount == 0)
39 return 0;
41 store = bfd_make_empty_symbol(abfd);
42 if (store == NULL)
43 bfd_fatal(bfd_get_filename(abfd));
45 for (cur = minisyms; cur < (minisyms + (symcount * size)); cur += size)
47 asymbol *sym;
49 sym = bfd_minisymbol_to_symbol(abfd, FALSE, (const void *)cur, store);
50 if (sym == NULL)
51 bfd_fatal(bfd_get_filename (abfd));
53 if (bfd_is_und_section (sym->section))
55 if (!there_are_undefined_syms)
57 there_are_undefined_syms = 1;
59 fprintf(stderr, "There are undefined symbols in '%s':\n", bfd_get_filename(abfd));
62 fprintf(stderr, "%s\n", sym->name);
66 bfd_close(abfd);
67 /* We should free() minisyms, but since we're called only once, we let the system
68 do it for us. */
70 return there_are_undefined_syms;
73 static void setfunc(bfd *exe, asection *sect, PTR setlist_ptr)
75 parse_secname(sect->name, (setnode **)setlist_ptr);
78 void collect_sets(const char *file, setnode **setlist_ptr)
80 bfd_init();
82 bfd *abfd;
86 (abfd = bfd_openr(file, "default")) == NULL ||
87 !bfd_check_format(abfd, bfd_object)
90 bfd_fatal(file);
93 parse_format(abfd->xvec->name);
94 bfd_map_over_sections(abfd, setfunc, setlist_ptr);
96 bfd_close(abfd);
99 static void collect_lib(asymbol *sym, setnode **liblist_ptr)
101 setnode *node;
102 char *cp, *name;
103 int pri;
105 if (strncmp(sym->name, "__aros_libreq_", 14) != 0)
106 return;
108 node = xmalloc(sizeof(*node)+strlen(sym->name)+1);
109 name = (char *)(&node[1]);
110 strcpy(name, sym->name);
112 cp = strchr(name + 14, '.');
113 if (cp != NULL) {
114 char *tmp;
115 pri = strtoul(cp+1, &tmp, 0);
117 if ((cp+1) == tmp) {
118 free(node);
119 return;
122 *(cp++) = 0;
124 } else {
125 pri = 0;
128 node->secname = name;
129 node->off_setname = 14;
130 node->pri = pri;
131 node->next = *liblist_ptr;
132 *liblist_ptr = node;
135 void collect_libs(const char *file, setnode **liblist_ptr)
137 long symtab_size;
138 bfd *abfd;
140 /* We assume bfd_init() has already been colled by
141 * collect_sets
146 (abfd = bfd_openr(file, "default")) == NULL ||
147 !bfd_check_format(abfd, bfd_object)
150 bfd_fatal(file);
153 symtab_size = bfd_get_symtab_upper_bound(abfd);
154 if (symtab_size > 0) {
155 asymbol **symtab;
156 long symbols;
158 symtab = (asymbol **)xmalloc(symtab_size);
159 symbols = bfd_canonicalize_symtab(abfd, symtab);
160 if (symbols > 0) {
161 long i;
163 for (i = 0; i < symbols; i++)
164 collect_lib(symtab[i], liblist_ptr);
167 free(symtab);
170 bfd_close(abfd);