New developer version 0.6.8; added select () function; added demonstrating example...
[ZeXOS.git] / kernel / core / elf.c
bloba7f0e9a9bb8e007a94c69df5eadd6d0b9745b2a4
1 /*
2 * ZeX/OS
3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
4 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
5 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
6 * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include <system.h>
24 #include <string.h>
25 #include <elf.h>
27 int exec_elf (unsigned char *image, unsigned *entry, unsigned *elf_data, unsigned *elf_data_off, unsigned *elf_bss)
29 unsigned s, r, reloc_size;
31 elf_reloc_t *reloc;
32 elf_sect_t *sect;
33 elf_file_t *file;
35 /* validate */
36 file = (elf_file_t *) image;
38 if (!arch_elf_detect (file))
39 return -1;
41 /* find the BSS and allocate memory for it
42 This must be done BEFORE doing any relocations */
43 for (s = 0; s < file->num_sects; s ++) {
44 sect = (elf_sect_t *)(image + file->shtab_offset +
45 file->shtab_ent_size * s);
47 if(sect->type != 8) /* NOBITS */
48 continue;
50 r = sect->size;
52 if (r < 1) {
53 DPRINT (DBG_ELF, "ELF .bss section is too small (%d bytes)", r);
54 continue;
57 *elf_bss = (unsigned) sect->virt_adr;
59 if (!*elf_bss) {
60 DPRINT (DBG_ELF, "Section .bss obtain wrong address: 0x%x", *elf_bss);
61 continue;
64 /* clean memory for bss section */
65 memset (image+sect->offset, 0, sect->size);
67 break;
70 elf_sect_t *rodata = 0;
72 /* for each section... */
73 for (s = 0; s < file->num_sects; s ++) {
74 sect = (elf_sect_t *)(image + file->shtab_offset + file->shtab_ent_size * s);
76 if (sect->type == 1) {
77 if (sect->sect_name == 0x17 || sect->sect_name == 0x27) {
78 rodata = sect;
79 break;
83 /* is it a relocation section?
84 xxx - we don't handle the extra addend for RELA relocations */
85 if(sect->type == 4) /* RELA */
86 reloc_size = 12;
87 else if(sect->type == 9)/* REL */
88 reloc_size = 8;
89 else
90 continue;
93 /* rodata section is not required */
94 if (!rodata)
95 DPRINT (DBG_ELF, "rodata section does not exist");
97 /* find start of .text and make it the entry point */
98 (*entry) = 0;
100 for (s = 0; s < file->num_sects; s ++) {
101 sect = (elf_sect_t *) (image + file->shtab_offset + file->shtab_ent_size * s);
103 if (sect->sect_name != 0x0b && sect->sect_name != 0x1b)
104 continue;
106 (*entry) = (unsigned) sect->virt_adr;
108 break;
111 /* copy rodata section to our memory area section */
112 if (rodata) {
113 *elf_data = (unsigned) rodata->virt_adr;
114 *elf_data_off = (unsigned) rodata->offset;
115 } else {
116 *elf_data = (unsigned) 0;
117 *elf_data_off = (unsigned) 0;
120 if (!(*entry)) {
121 printf ("ELF -> Can't find section .text, so entry point is unknown\n");
122 return -1;
125 return 0;