1 /* $NetBSD: exec_sub.c,v 1.5 2009/03/14 15:36:15 dsl Exp $ */
10 void B_PRINT(const unsigned char *p
);
13 static inline void bzero4(void *ptr
, size_t siz
);
14 static void xk_aout(struct execkern_arg
*xarg
, struct exec
*hdr
);
15 static void xk_elf(struct execkern_arg
*xarg
, Elf32_Ehdr
*hdr
);
18 static void DPRINT_SEC(const char *ident
,
19 const struct execkern_section
*sec
);
21 extern const char *kernel_fn
;
24 DPRINT_SEC(const char *ident
, const struct execkern_section
*sec
)
28 xwarnx("section (%s): img %p, sz %d, pad %d", ident
,
29 sec
->sec_image
, sec
->sec_size
, sec
->sec_pad
);
32 #define ERRX(arg) xerrx arg
35 #define DPRINT_SEC(ident, sec) /**/
36 #define ERRX(arg) return 1
40 * This code is size-hacked version of
42 * sec->sec_image = (image);
43 * sec->sec_size = (size);
44 * sec->sec_pad = (pad);
45 * DPRINT_SEC((ident), sec);
48 #define SECTION(sec, ident, image, size, pad) \
50 u_long *wp = (void *) sec; \
51 *(void **)wp++ = (image); \
54 DPRINT_SEC((ident), sec); \
58 #define SECTION_NOPAD(sec, ident, image, size) \
59 SECTION(sec, (ident), (image), (size), 0)
62 bzero4(void *ptr
, size_t siz
)
75 * fill in loading information from an a.out executable
78 xk_aout(struct execkern_arg
*xarg
, struct exec
*hdr
)
82 struct execkern_section
*sec
;
84 xarg
->entry_addr
= hdr
->a_entry
;
87 /* text section and padding between data section */
88 s
= (void *) (hdr
+ 1);
89 SECTION(sec
, "text", s
, hdr
->a_text
, -hdr
->a_text
& (AOUT_LDPGSZ
-1));
91 /* data and bss sections */
93 SECTION(sec
, "data/bss", s
, hdr
->a_data
, hdr
->a_bss
);
95 /* size of symbol table */
96 SECTION_NOPAD(sec
, "symtab size", &sec
[1].sec_size
, sizeof(u_long
));
98 /* symbol table section */
100 SECTION_NOPAD(sec
, "symbol", s
, u
= hdr
->a_syms
);
102 /* string table section */
106 xwarnx("symbol table found");
109 SECTION_NOPAD(sec
, "string", s
, *(u_long
*) s
);
114 * fill in loading information from an ELF executable
117 xk_elf(struct execkern_arg
*xarg
, Elf32_Ehdr
*hdr
)
119 char *top
= (void *) hdr
;
120 struct execkern_section
*sec
;
122 Elf32_Shdr
*sh
, *sym
, *str
, *stab
, *shstr
;
123 const char *shstrtab
, *shname
;
124 unsigned u
, dpos
, pd
;
125 const char *const shstrtab_new
= SHSTRTAB_FAKE
;
127 xarg
->entry_addr
= hdr
->e_entry
;
132 ph
= (void *) (top
+ hdr
->e_phoff
);
133 xarg
->load_addr
= ph
->p_vaddr
;
136 sec
->sec_image
= top
+ ph
->p_offset
;
137 sec
->sec_size
= ph
->p_filesz
;
139 if (hdr
->e_phnum
!= 1) {
140 sec
->sec_pad
= ph
[1].p_vaddr
- (ph
->p_vaddr
+ ph
->p_filesz
);
141 DPRINT_SEC("program (text)", sec
);
144 sec
->sec_image
= top
+ ph
->p_offset
;
145 sec
->sec_size
= ph
->p_filesz
;
148 sec
->sec_pad
= ph
->p_memsz
- ph
->p_filesz
;
149 DPRINT_SEC("program (data/bss)", sec
);
155 xarg
->elfsymsiz
= 0; /* no symbol */
156 SECTION_NOPAD(sec
, "symtab size", &xarg
->elfsymsiz
, sizeof(int));
162 xarg
->ehdr
.e_shstrndx
= 0; /* .shstrtab will be the 1st section */
163 SECTION_NOPAD(sec
, "ELF header", &xarg
->ehdr
, sizeof(Elf32_Ehdr
));
165 sh
= (void *) (top
+ hdr
->e_shoff
); /* section header */
166 shstr
= sh
+ hdr
->e_shstrndx
; /* .shstrtab */
167 shstrtab
= top
+ shstr
->sh_offset
;
169 sym
= str
= stab
= 0;
170 for (u
= 0; sh
++, ++u
< hdr
->e_shnum
; ) {
171 shname
= shstrtab
+ sh
->sh_name
;
172 if (!strcmp(shname
, shstrtab_new
+ SHNAME_OFF_SYMTAB
))
173 sym
= sh
; /* .symtab */
174 if (!strcmp(shname
, shstrtab_new
+ SHNAME_OFF_STRTAB
))
175 str
= sh
; /* .strtab */
176 if (!strcmp(shname
, shstrtab_new
+ SHNAME_OFF_STAB
))
177 stab
= sh
; /* .stab */
180 if (shstr
== 0 || sym
== 0 || str
== 0)
181 xarg
->ehdr
.e_shnum
= 0; /* no symbol */
185 xwarnx("symbol table found");
187 xwarnx("debugging information found");
190 xarg
->elfsymsiz
= 1; /* has symbol */
191 xarg
->ehdr
.e_shnum
= 3;
192 xarg
->ehdr
.e_shoff
= sizeof(Elf32_Ehdr
);
194 SECTION_NOPAD(sec
, "section header (shstrtab)",
195 shstr
, sizeof(Elf32_Shdr
));
197 SECTION_NOPAD(sec
, "section header (symbol)",
198 sym
, sizeof(Elf32_Shdr
));
200 SECTION_NOPAD(sec
, "section header (string)",
201 str
, sizeof(Elf32_Shdr
));
203 dpos
= sizeof(Elf32_Ehdr
) + sizeof(Elf32_Shdr
) * 3;
204 u
= SIZE_SHSTRTAB_FAKE
;
207 xarg
->ehdr
.e_shnum
++;
208 SECTION_NOPAD(sec
, "section header (stab)",
209 stab
, sizeof(Elf32_Shdr
));
210 dpos
+= sizeof(Elf32_Shdr
);
211 u
= SIZE_SHSTRTAB_FAKE_WITH_STAB
;
214 /* new .shstrtab section */
215 memcpy(xarg
->shstrtab_fake
, shstrtab_new
, u
);
217 * DDB requires symtab be aligned.
219 pd
= -u
& ALIGNBYTES
;
220 SECTION(sec
, "shstrtab", &xarg
->shstrtab_fake
, u
, pd
);
221 shstr
->sh_name
= SHNAME_OFF_SHSTRTAB
;
222 shstr
->sh_offset
= dpos
;
225 SECTION_NOPAD(sec
, "symtab",
226 top
+ sym
->sh_offset
, sym
->sh_size
);
227 sym
->sh_name
= SHNAME_OFF_SYMTAB
;
228 sym
->sh_offset
= dpos
;
229 dpos
+= sym
->sh_size
;
231 SECTION_NOPAD(sec
, "strtab",
232 top
+ str
->sh_offset
, str
->sh_size
);
233 str
->sh_name
= SHNAME_OFF_STRTAB
;
234 str
->sh_offset
= dpos
;
235 dpos
+= str
->sh_size
;
238 SECTION_NOPAD(sec
, "stab",
239 top
+ stab
->sh_offset
, stab
->sh_size
);
240 stab
->sh_name
= SHNAME_OFF_STAB
;
241 stab
->sh_offset
= dpos
;
248 xk_load(struct execkern_arg
*xarg
, void *buf
, u_long loadaddr
)
249 /* loadaddr: for a.out */
255 /* Unused section entries should be cleared to zero. */
256 bzero4(xarg
->sec
, sizeof xarg
->sec
);
258 xarg
->load_addr
= loadaddr
;
266 if (N_GETMAGIC(*ahdr
) == NMAGIC
) {
272 xwarnx("%s: is an a.out", kernel_fn
);
275 B_PRINT("This is an a.out\r\n");
278 if ((u
= N_GETMID(*ahdr
)) != MID_M68K
)
279 ERRX((1, "%s: Wrong architecture (mid %u)",
283 * fill in loading information
292 if (*(u_int32_t
*)&ehdr
->e_ident
[EI_MAG0
] !=
293 (ELFMAG0
<<24 | ELFMAG1
<<16 | ELFMAG2
<<8 | ELFMAG3
) ||
294 *(u_int16_t
*)&ehdr
->e_ident
[EI_CLASS
] !=
295 (ELFCLASS32
<< 8 | ELFDATA2MSB
))
296 ERRX((1, "%s: Not an NMAGIC a.out or a 32bit BE ELF",
304 xwarnx("%s: is an ELF", kernel_fn
);
307 B_PRINT("This is an ELF\r\n");
310 if (ehdr
->e_ident
[EI_VERSION
] != EV_CURRENT
||
311 ehdr
->e_version
!= EV_CURRENT
)
312 ERRX((1, "%s: Unsupported ELF version", kernel_fn
));
314 if ((u
= ehdr
->e_machine
) != EM_68K
)
315 ERRX((1, "%s: Wrong architecture (mid %u)",
317 if (ehdr
->e_type
!= ET_EXEC
)
318 ERRX((1, "%s: Not an executable", kernel_fn
));
319 if ((u
= ehdr
->e_phnum
) != 1 && u
!= 2)
320 ERRX((1, "%s: Wrong number (%u) of loading sections",
324 * fill in loading information