driver: add dev_name inline
[barebox-mini2440.git] / common / module.c
blobe45c9928232853163806b3c2707b9017967b44a9
1 /*
2 * Copyright (C) 2002 Richard Henderson
3 * Copyright (C) 2001 Rusty Russell, 2002 Rusty Russell IBM.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include <common.h>
21 #include <errno.h>
22 #include <module.h>
23 #include <elf.h>
24 #include <malloc.h>
25 #include <xfuncs.h>
26 #include <command.h>
27 #include <fs.h>
28 #include <kallsyms.h>
29 #include <list.h>
31 static unsigned int find_sec(Elf_Ehdr *hdr,
32 Elf_Shdr *sechdrs,
33 const char *secstrings,
34 const char *name)
36 unsigned int i;
38 for (i = 1; i < hdr->e_shnum; i++) {
39 debug("find_sec: %s %s\n", name, secstrings+sechdrs[i].sh_name);
40 /* Alloc bit cleared means "ignore it." */
41 if ((sechdrs[i].sh_flags & SHF_ALLOC) &&
42 !strcmp(secstrings+sechdrs[i].sh_name, name))
43 return i;
46 return 0;
49 /* Provided by the linker */
50 extern const struct kernel_symbol __usymtab_start[];
51 extern const struct kernel_symbol __usymtab_end[];
53 /* lookup symbol in given range of kernel_symbols */
54 static const struct kernel_symbol *lookup_symbol(const char *name,
55 const struct kernel_symbol *start,
56 const struct kernel_symbol *stop)
58 const struct kernel_symbol *ks = start;
59 for (; ks < stop; ks++) {
60 if (strcmp(ks->name, name) == 0)
61 return ks;
63 return NULL;
66 static unsigned long resolve_symbol(Elf32_Shdr *sechdrs,
67 const char *name)
69 const struct kernel_symbol *ks;
71 debug("%s: %s\n", __FUNCTION__, name);
72 ks = lookup_symbol(name, __usymtab_start,
73 __usymtab_end);
75 if (ks)
76 return ks->value;
77 return 0;
80 /* Change all symbols so that sh_value encodes the pointer directly. */
81 static int simplify_symbols(Elf32_Shdr *sechdrs,
82 unsigned int symindex,
83 const char *strtab)
85 Elf32_Sym *sym = (void *)sechdrs[symindex].sh_addr;
86 unsigned long secbase;
87 unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf32_Sym);
88 int ret = 0;
90 for (i = 1; i < n; i++) {
91 switch (sym[i].st_shndx) {
92 case SHN_COMMON:
93 /* We compiled with -fno-common. These are not
94 supposed to happen. */
95 printf("Common symbol: %s\n", strtab + sym[i].st_name);
96 printf("please compile with -fno-common\n");
97 ret = -1;
98 break;
100 case SHN_ABS:
101 /* Don't need to do anything */
102 debug("Absolute symbol: 0x%08lx\n",
103 (long)sym[i].st_value);
104 break;
106 case SHN_UNDEF:
107 sym[i].st_value
108 = resolve_symbol(sechdrs,
109 strtab + sym[i].st_name);
110 debug("undef : %20s 0x%08x 0x%08lx\n", strtab + sym[i].st_name, sym[i].st_value);
112 /* Ok if resolved. */
113 if (sym[i].st_value != 0)
114 break;
115 /* Ok if weak. */
116 if (ELF32_ST_BIND(sym[i].st_info) == STB_WEAK)
117 break;
119 printf("Unknown symbol %s\n",
120 strtab + sym[i].st_name);
121 ret = -1;
122 break;
124 default:
125 secbase = sechdrs[sym[i].st_shndx].sh_addr;
126 debug("default: %20s 0x%08x 0x%08lx\n", strtab + sym[i].st_name, sym[i].st_value, secbase);
127 sym[i].st_value += secbase;
128 break;
132 return ret;
135 #define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
136 #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
138 /* Update size with this section: return offset. */
139 static long get_offset(unsigned long *size, Elf32_Shdr *sechdr)
141 long ret;
143 ret = ALIGN(*size, sechdr->sh_addralign ?: 1);
144 *size = ret + sechdr->sh_size;
145 return ret;
148 static void layout_sections( struct module *mod,
149 const Elf32_Ehdr *hdr,
150 Elf32_Shdr *sechdrs,
151 const char *secstrings)
153 static unsigned long const masks[][2] = {
154 /* NOTE: all executable code must be the first section
155 * in this array; otherwise modify the text_size
156 * finder in the two loops below */
157 { SHF_EXECINSTR | SHF_ALLOC },
158 { SHF_ALLOC, SHF_WRITE },
159 { SHF_WRITE | SHF_ALLOC },
160 { SHF_ALLOC, 0 }
162 unsigned int m, i;
164 for (i = 0; i < hdr->e_shnum; i++)
165 sechdrs[i].sh_entsize = ~0UL;
167 debug("Core section allocation order:\n");
168 for (m = 0; m < ARRAY_SIZE(masks); ++m) {
169 for (i = 0; i < hdr->e_shnum; ++i) {
170 Elf32_Shdr *s = &sechdrs[i];
172 if ((s->sh_flags & masks[m][0]) != masks[m][0]
173 || (s->sh_flags & masks[m][1])
174 || s->sh_entsize != ~0UL
175 || strncmp(secstrings + s->sh_name,
176 ".init", 5) == 0)
177 continue;
178 s->sh_entsize = get_offset(&mod->core_size, s);
179 debug("\t%s 0x%08x\n", secstrings + s->sh_name, s->sh_entsize);
182 debug("core_size: %ld\n", mod->core_size);
185 LIST_HEAD(module_list);
187 struct module * load_module(void *mod_image, unsigned long len)
189 struct module *module = NULL;
190 Elf32_Ehdr *ehdr; /* Elf header structure pointer */
191 Elf32_Shdr *sechdrs; /* Section header structure pointer */
192 Elf32_Sym *sym;
193 unsigned int numsyms;
194 char *strtab = 0; /* String table pointer */
195 int i; /* Loop counter */
196 unsigned int strindex = 0;
197 unsigned int symindex = 0;
198 unsigned int modindex;
199 char *secstrings;
200 void *ptr = NULL;
201 int err;
202 int cmdindex;
204 if (len < sizeof(*ehdr))
205 return NULL;
207 ehdr = (Elf32_Ehdr *)mod_image;
209 if (len < ehdr->e_shoff + ehdr->e_shnum * sizeof(Elf_Shdr))
210 return NULL;
212 /* Find the section header string table for output info */
213 sechdrs = (Elf32_Shdr *) (mod_image + ehdr->e_shoff +
214 (ehdr->e_shstrndx * sizeof (Elf32_Shdr)));
216 if (sechdrs->sh_type == SHT_SYMTAB)
217 strtab = (char *) (mod_image + sechdrs->sh_offset);
219 /* Convenience variables */
220 sechdrs = (void *)ehdr + ehdr->e_shoff;
221 secstrings = (void *)ehdr + sechdrs[ehdr->e_shstrndx].sh_offset;
222 sechdrs[0].sh_addr = 0;
224 for (i = 0; i < ehdr->e_shnum; i++) {
226 debug("%d addr: 0x%08x size: 0x%08x ofs: 0x%08x\n",
227 i, sechdrs[i].sh_addr, sechdrs[i].sh_size, sechdrs[i].sh_offset);
229 /* Mark all sections sh_addr with their address in the
230 temporary image. */
231 sechdrs[i].sh_addr = (size_t)ehdr + sechdrs[i].sh_offset;
233 if (sechdrs[i].sh_type == SHT_SYMTAB) {
234 symindex = i;
235 strindex = sechdrs[i].sh_link;
236 strtab = mod_image + sechdrs[strindex].sh_offset;
240 modindex = find_sec(ehdr, sechdrs, secstrings,
241 ".gnu.linkonce.this_module");
242 if (!modindex) {
243 printf("No module found in object\n");
244 err = -ENOEXEC;
245 goto cleanup;
247 module = (void *)sechdrs[modindex].sh_addr;
249 if (symindex == 0) {
250 printf("module has no symbols (stripped?)\n");
251 err = -ENOEXEC;
252 goto cleanup;
255 /* Determine total sizes, and put offsets in sh_entsize. For now
256 this is done generically; there doesn't appear to be any
257 special cases for the architectures. */
258 layout_sections(module, ehdr, sechdrs, secstrings);
260 ptr = xzalloc(module->core_size);
261 module->module_core = ptr;
263 /* Transfer each section which specifies SHF_ALLOC */
264 debug("final section addresses:\n");
265 for (i = 0; i < ehdr->e_shnum; i++) {
266 void *dest;
268 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
269 continue;
271 dest = module->module_core + sechdrs[i].sh_entsize;
272 debug("0x%08x dest 0x%p\n", sechdrs[i].sh_addr, dest);
274 if (sechdrs[i].sh_type != SHT_NOBITS)
275 memcpy(dest, (void *)sechdrs[i].sh_addr,
276 sechdrs[i].sh_size);
277 /* Update sh_addr to point to copy in image. */
278 sechdrs[i].sh_addr = (unsigned long)dest;
281 /* Fix up syms, so that st_value is a pointer to location. */
282 err = simplify_symbols(sechdrs, symindex, strtab);
283 if (err < 0)
284 goto cleanup;
286 for (i = 0; i < ehdr->e_shnum; i++) {
287 if (sechdrs[i].sh_type == SHT_REL) {
288 apply_relocate(sechdrs, strtab, symindex, i, module);
290 if (sechdrs[i].sh_type == SHT_RELA)
291 apply_relocate_add(sechdrs, strtab, symindex, i, module);
294 numsyms = sechdrs[symindex].sh_size / sizeof(Elf32_Sym);
295 sym = (void *)sechdrs[symindex].sh_addr;
297 #ifdef CONFIG_COMMAND
298 cmdindex = find_sec(ehdr, sechdrs, secstrings, ".u_boot_cmd");
299 if (cmdindex) {
300 cmd_tbl_t *cmd = (cmd_tbl_t *)sechdrs[cmdindex].sh_addr;
301 for (i = 0; i < sechdrs[cmdindex].sh_size / sizeof(cmd_tbl_t); i++) {
302 register_command(cmd);
303 cmd++;
306 #endif
308 for (i = 0; i < numsyms; i++) {
309 if (!strcmp(strtab + sym[i].st_name, MODULE_SYMBOL_PREFIX "init_module")) {
310 printf("found init_module() at 0x%08x\n", sym[i].st_value);
311 module->init = (void *)sym[i].st_value;
315 list_add_tail(&module->list, &module_list);
317 return module;
319 cleanup:
320 if (ptr)
321 free(ptr);
322 if (module)
323 free(module);
325 return NULL;