Fixed possible memory corruption in commands exec and netexec; fixed command netcp...
[ZeXOS.git] / kernel / core / elf.c
blobcd9a8954e338b5b653cc4841c2a7cbe1509582e3
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 + file->shtab_ent_size * s);
46 if(sect->type != 8) /* NOBITS */
47 continue;
49 r = sect->size;
51 if (r < 1) {
52 DPRINT (DBG_ELF, "ELF .bss section is too small (%d bytes)", r);
53 continue;
56 *elf_bss = (unsigned) sect->virt_adr;
58 if (!*elf_bss) {
59 DPRINT (DBG_ELF, "Section .bss obtain wrong address: 0x%x", *elf_bss);
60 continue;
63 /* clean memory for bss section */
64 memset (image+sect->offset, 0, sect->size);
66 break;
69 elf_sect_t *rodata = 0;
71 /* for each section... */
72 for (s = 0; s < file->num_sects; s ++) {
73 sect = (elf_sect_t *) (image + file->shtab_offset + file->shtab_ent_size * s);
75 if (sect->type == 1) {
76 if (sect->sect_name == 0x17 || sect->sect_name == 0x27) {
77 rodata = sect;
78 break;
82 /* is it a relocation section?
83 xxx - we don't handle the extra addend for RELA relocations */
84 if(sect->type == 4) /* RELA */
85 reloc_size = 12;
86 else if(sect->type == 9)/* REL */
87 reloc_size = 8;
88 else
89 continue;
92 /* rodata section is not required */
93 if (!rodata)
94 DPRINT (DBG_ELF, "rodata section does not exist");
96 /* find start of .text and make it the entry point */
97 (*entry) = 0;
99 for (s = 0; s < file->num_sects; s ++) {
100 sect = (elf_sect_t *) (image + file->shtab_offset + file->shtab_ent_size * s);
102 if (sect->sect_name != 0x0b && sect->sect_name != 0x1b)
103 continue;
105 (*entry) = (unsigned) sect->virt_adr;
107 break;
110 /* copy rodata section to our memory area section */
111 if (rodata) {
112 *elf_data = (unsigned) rodata->virt_adr;
113 *elf_data_off = (unsigned) rodata->offset;
114 } else {
115 *elf_data = (unsigned) 0;
116 *elf_data_off = (unsigned) 0;
119 if (!(*entry)) {
120 printf ("ELF -> Can't find section .text, so entry point is unknown\n");
121 return -1;
124 return 0;