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
31 static unsigned int find_sec(Elf_Ehdr
*hdr
,
33 const char *secstrings
,
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
))
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)
66 static unsigned long resolve_symbol(Elf32_Shdr
*sechdrs
,
69 const struct kernel_symbol
*ks
;
71 debug("%s: %s\n", __FUNCTION__
, name
);
72 ks
= lookup_symbol(name
, __usymtab_start
,
80 /* Change all symbols so that sh_value encodes the pointer directly. */
81 static int simplify_symbols(Elf32_Shdr
*sechdrs
,
82 unsigned int symindex
,
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
);
90 for (i
= 1; i
< n
; i
++) {
91 switch (sym
[i
].st_shndx
) {
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");
101 /* Don't need to do anything */
102 debug("Absolute symbol: 0x%08lx\n",
103 (long)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)
116 if (ELF32_ST_BIND(sym
[i
].st_info
) == STB_WEAK
)
119 printf("Unknown symbol %s\n",
120 strtab
+ sym
[i
].st_name
);
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
;
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
)
143 ret
= ALIGN(*size
, sechdr
->sh_addralign
?: 1);
144 *size
= ret
+ sechdr
->sh_size
;
148 static void layout_sections( struct module
*mod
,
149 const Elf32_Ehdr
*hdr
,
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
},
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
,
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 */
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
;
204 if (len
< sizeof(*ehdr
))
207 ehdr
= (Elf32_Ehdr
*)mod_image
;
209 if (len
< ehdr
->e_shoff
+ ehdr
->e_shnum
* sizeof(Elf_Shdr
))
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
231 sechdrs
[i
].sh_addr
= (size_t)ehdr
+ sechdrs
[i
].sh_offset
;
233 if (sechdrs
[i
].sh_type
== SHT_SYMTAB
) {
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");
243 printf("No module found in object\n");
247 module
= (void *)sechdrs
[modindex
].sh_addr
;
250 printf("module has no symbols (stripped?)\n");
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
++) {
268 if (!(sechdrs
[i
].sh_flags
& SHF_ALLOC
))
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
,
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
);
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");
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
);
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
);