collect-aros: Remove dependency on elfedit
[AROS.git] / tools / collect-aros / backend-bfd.c
blob7116c5165b8dc816cd94cf80410fb99a87151296
1 #include <bfd.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <errno.h>
6 #include <sys/param.h>
8 #include "misc.h"
9 #include "backend.h"
11 static void bfd_fatal(const char *msg)
13 fatal(msg, bfd_errmsg(bfd_get_error()));
16 int check_and_print_undefined_symbols(const char *file)
18 bfd_byte *cur, *minisyms;
19 asymbol *store;
20 long symcount;
21 unsigned int size;
22 int there_are_undefined_syms = 0;
23 bfd *abfd;
25 bfd_init();
29 (abfd = bfd_openr(file, "default")) == NULL ||
30 !bfd_check_format(abfd, bfd_object)
33 bfd_fatal(file);
36 symcount = bfd_read_minisymbols(abfd, FALSE, (void **)&minisyms, &size);
37 if (symcount < 0)
38 bfd_fatal (bfd_get_filename (abfd));
40 if (symcount == 0)
41 return 0;
43 store = bfd_make_empty_symbol(abfd);
44 if (store == NULL)
45 bfd_fatal(bfd_get_filename(abfd));
47 for (cur = minisyms; cur < (minisyms + (symcount * size)); cur += size)
49 asymbol *sym;
51 sym = bfd_minisymbol_to_symbol(abfd, FALSE, (const void *)cur, store);
52 if (sym == NULL)
53 bfd_fatal(bfd_get_filename (abfd));
55 if (bfd_is_und_section (sym->section))
57 if (!there_are_undefined_syms)
59 there_are_undefined_syms = 1;
61 fprintf(stderr, "There are undefined symbols in '%s':\n", bfd_get_filename(abfd));
64 fprintf(stderr, "%s\n", sym->name);
68 bfd_close(abfd);
69 /* We should free() minisyms, but since we're called only once, we let the system
70 do it for us. */
72 return there_are_undefined_syms;
75 static void setfunc(bfd *exe, asection *sect, PTR setlist_ptr)
77 parse_secname(sect->name, (setnode **)setlist_ptr);
80 void collect_sets(const char *file, setnode **setlist_ptr)
82 bfd_init();
84 bfd *abfd;
88 (abfd = bfd_openr(file, "default")) == NULL ||
89 !bfd_check_format(abfd, bfd_object)
92 bfd_fatal(file);
95 parse_format(abfd->xvec->name);
96 bfd_map_over_sections(abfd, setfunc, setlist_ptr);
98 bfd_close(abfd);
101 static void collect_lib(asymbol *sym, setnode **liblist_ptr)
103 setnode *node;
104 char *cp, *name;
105 int pri;
107 if (strncmp(sym->name, "__aros_libreq_", 14) != 0)
108 return;
110 node = xmalloc(sizeof(*node)+strlen(sym->name)+1);
111 name = (char *)(&node[1]);
112 strcpy(name, sym->name);
114 cp = strchr(name + 14, '.');
115 if (cp != NULL) {
116 char *tmp;
117 pri = strtoul(cp+1, &tmp, 0);
119 if ((cp+1) == tmp) {
120 free(node);
121 return;
124 *(cp++) = 0;
126 } else {
127 pri = 0;
130 node->secname = name;
131 node->off_setname = 14;
132 node->pri = pri;
133 node->next = *liblist_ptr;
134 *liblist_ptr = node;
137 void collect_libs(const char *file, setnode **liblist_ptr)
139 long symtab_size;
140 bfd *abfd;
142 /* We assume bfd_init() has already been colled by
143 * collect_sets
148 (abfd = bfd_openr(file, "default")) == NULL ||
149 !bfd_check_format(abfd, bfd_object)
152 bfd_fatal(file);
155 symtab_size = bfd_get_symtab_upper_bound(abfd);
156 if (symtab_size > 0) {
157 asymbol **symtab;
158 long symbols;
160 symtab = (asymbol **)xmalloc(symtab_size);
161 symbols = bfd_canonicalize_symtab(abfd, symtab);
162 if (symbols > 0) {
163 long i;
165 for (i = 0; i < symbols; i++)
166 collect_lib(symtab[i], liblist_ptr);
169 free(symtab);
172 bfd_close(abfd);