Changes in kernel/generic/src/lib/elf.c [1e00216:1ea99cc] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/lib/elf.c
r1e00216 r1ea99cc 28 28 */ 29 29 30 /** @addtogroup generic 30 /** @addtogroup generic 31 31 * @{ 32 32 */ … … 34 34 /** 35 35 * @file 36 * @brief 36 * @brief Kernel ELF loader. 37 37 */ 38 38 39 39 #include <lib/elf.h> 40 40 #include <debug.h> 41 #include < typedefs.h>41 #include <arch/types.h> 42 42 #include <mm/as.h> 43 43 #include <mm/frame.h> … … 48 48 #include <arch.h> 49 49 50 static c onst char *error_codes[] = {50 static char *error_codes[] = { 51 51 "no error", 52 52 "invalid image", … … 57 57 }; 58 58 59 static int segment_header(elf_segment_header_t *, elf_header_t *, as_t *, 60 unsigned int); 61 static int section_header(elf_section_header_t *, elf_header_t *, as_t *); 62 static int load_segment(elf_segment_header_t *, elf_header_t *, as_t *); 59 static int segment_header(elf_segment_header_t *entry, elf_header_t *elf, 60 as_t *as, int flags); 61 static int section_header(elf_section_header_t *entry, elf_header_t *elf, 62 as_t *as); 63 static int load_segment(elf_segment_header_t *entry, elf_header_t *elf, 64 as_t *as); 63 65 64 66 /** ELF loader 65 67 * 66 68 * @param header Pointer to ELF header in memory 67 * @param as Created and properly mapped address space 68 * @param flags A combination of ELD_F_* 69 * 69 * @param as Created and properly mapped address space 70 * @param flags A combination of ELD_F_* 70 71 * @return EE_OK on success 71 * 72 */ 73 unsigned int elf_load(elf_header_t *header, as_t *as, unsigned int flags) 74 { 72 */ 73 unsigned int elf_load(elf_header_t *header, as_t * as, int flags) 74 { 75 int i, rc; 76 75 77 /* Identify ELF */ 76 if ( (header->e_ident[EI_MAG0] != ELFMAG0)||77 (header->e_ident[EI_MAG1] != ELFMAG1) ||78 (header->e_ident[EI_MAG2] != ELFMAG2)||79 (header->e_ident[EI_MAG3] != ELFMAG3))78 if (header->e_ident[EI_MAG0] != ELFMAG0 || 79 header->e_ident[EI_MAG1] != ELFMAG1 || 80 header->e_ident[EI_MAG2] != ELFMAG2 || 81 header->e_ident[EI_MAG3] != ELFMAG3) { 80 82 return EE_INVALID; 83 } 81 84 82 85 /* Identify ELF compatibility */ 83 if ( (header->e_ident[EI_DATA] != ELF_DATA_ENCODING)||84 (header->e_machine != ELF_MACHINE) ||85 (header->e_ident[EI_VERSION] != EV_CURRENT)||86 (header->e_version != EV_CURRENT)||87 (header->e_ident[EI_CLASS] != ELF_CLASS))86 if (header->e_ident[EI_DATA] != ELF_DATA_ENCODING || 87 header->e_machine != ELF_MACHINE || 88 header->e_ident[EI_VERSION] != EV_CURRENT || 89 header->e_version != EV_CURRENT || 90 header->e_ident[EI_CLASS] != ELF_CLASS) { 88 91 return EE_INCOMPATIBLE; 89 92 } 93 90 94 if (header->e_phentsize != sizeof(elf_segment_header_t)) 91 95 return EE_INCOMPATIBLE; 92 96 93 97 if (header->e_shentsize != sizeof(elf_section_header_t)) 94 98 return EE_INCOMPATIBLE; 95 99 96 100 /* Check if the object type is supported. */ 97 101 if (header->e_type != ET_EXEC) 98 102 return EE_UNSUPPORTED; 99 103 100 104 /* Check if the ELF image starts on a page boundary */ 101 if (ALIGN_UP((uintptr_t) header, PAGE_SIZE) != (uintptr_t)header)105 if (ALIGN_UP((uintptr_t)header, PAGE_SIZE) != (uintptr_t)header) 102 106 return EE_UNSUPPORTED; 103 107 104 108 /* Walk through all segment headers and process them. */ 105 elf_half i;106 109 for (i = 0; i < header->e_phnum; i++) { 107 elf_segment_header_t *seghdr = 108 &((elf_segment_header_t *)(((uint8_t *) header) + 110 elf_segment_header_t *seghdr; 111 112 seghdr = &((elf_segment_header_t *)(((uint8_t *) header) + 109 113 header->e_phoff))[i]; 110 111 int rc = segment_header(seghdr, header, as, flags); 114 rc = segment_header(seghdr, header, as, flags); 112 115 if (rc != EE_OK) 113 116 return rc; 114 117 } 115 118 116 119 /* Inspect all section headers and proccess them. */ 117 120 for (i = 0; i < header->e_shnum; i++) { 118 elf_section_header_t *sechdr = 119 &((elf_section_header_t *)(((uint8_t *) header) + 121 elf_section_header_t *sechdr; 122 123 sechdr = &((elf_section_header_t *)(((uint8_t *) header) + 120 124 header->e_shoff))[i]; 121 122 int rc = section_header(sechdr, header, as); 125 rc = section_header(sechdr, header, as); 123 126 if (rc != EE_OK) 124 127 return rc; 125 128 } 126 129 127 130 return EE_OK; 128 131 } … … 133 136 * 134 137 * @return NULL terminated description of error. 135 * 136 */ 137 const char *elf_error(unsigned int rc) 138 */ 139 char *elf_error(unsigned int rc) 138 140 { 139 141 ASSERT(rc < sizeof(error_codes) / sizeof(char *)); 140 142 141 143 return error_codes[rc]; 142 144 } … … 145 147 * 146 148 * @param entry Segment header. 147 * @param elf 148 * @param as 149 * @param elf ELF header. 150 * @param as Address space into wich the ELF is being loaded. 149 151 * 150 152 * @return EE_OK on success, error code otherwise. 151 *152 153 */ 153 154 static int segment_header(elf_segment_header_t *entry, elf_header_t *elf, 154 as_t *as, unsigned int flags) 155 { 155 as_t *as, int flags) 156 { 157 char *interp; 158 156 159 switch (entry->p_type) { 157 160 case PT_NULL: 158 161 case PT_PHDR: 159 case PT_NOTE:160 162 break; 161 163 case PT_LOAD: 162 164 return load_segment(entry, elf, as); 165 break; 163 166 case PT_DYNAMIC: 164 167 case PT_INTERP: 165 // FIXME 166 /* 167 char *interp = (char *) elf + entry->p_offset; 168 if (memcmp((uintptr_t) interp, (uintptr_t) ELF_INTERP_ZSTR, 168 interp = (char *)elf + entry->p_offset; 169 /* DO NOT COMMIT ME */ 170 /*if (memcmp((uintptr_t)interp, (uintptr_t)ELF_INTERP_ZSTR, 169 171 ELF_INTERP_ZLEN) != 0) { 170 172 return EE_UNSUPPORTED; 171 } 172 if ((flags & ELD_F_LOADER) == 0) 173 }*/ 174 if ((flags & ELD_F_LOADER) == 0) { 173 175 return EE_LOADER; 176 } 174 177 break; 175 178 case PT_SHLIB: 179 case PT_NOTE: 176 180 case PT_LOPROC: 177 181 case PT_HIPROC: 178 182 default: 179 183 return EE_UNSUPPORTED; 184 break; 180 185 } 181 186 return EE_OK; … … 185 190 * 186 191 * @param entry Program header entry describing segment to be loaded. 187 * @param elf 188 * @param as 192 * @param elf ELF header. 193 * @param as Address space into wich the ELF is being loaded. 189 194 * 190 195 * @return EE_OK on success, error code otherwise. 191 *192 196 */ 193 197 int load_segment(elf_segment_header_t *entry, elf_header_t *elf, as_t *as) 194 198 { 199 as_area_t *a; 200 int flags = 0; 195 201 mem_backend_data_t backend_data; 202 uintptr_t base; 203 size_t mem_sz; 204 196 205 backend_data.elf = elf; 197 206 backend_data.segment = entry; 198 207 199 208 if (entry->p_align > 1) { 200 209 if ((entry->p_offset % entry->p_align) != 201 (entry->p_vaddr % entry->p_align)) 210 (entry->p_vaddr % entry->p_align)) { 202 211 return EE_INVALID; 203 } 204 205 unsigned int flags = 0; 206 212 } 213 } 214 207 215 if (entry->p_flags & PF_X) 208 216 flags |= AS_AREA_EXEC; 209 210 217 if (entry->p_flags & PF_W) 211 218 flags |= AS_AREA_WRITE; 212 213 219 if (entry->p_flags & PF_R) 214 220 flags |= AS_AREA_READ; 215 216 221 flags |= AS_AREA_CACHEABLE; 217 218 /* 222 223 /* 219 224 * Align vaddr down, inserting a little "gap" at the beginning. 220 225 * Adjust area size, so that its end remains in place. 221 *222 226 */ 223 uintptr_tbase = ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE);224 size_tmem_sz = entry->p_memsz + (entry->p_vaddr - base);225 226 a s_area_t *area= as_area_create(as, flags, mem_sz, base,227 base = ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE); 228 mem_sz = entry->p_memsz + (entry->p_vaddr - base); 229 230 a = as_area_create(as, flags, mem_sz, base, 227 231 AS_AREA_ATTR_NONE, &elf_backend, &backend_data); 228 if (!a rea)232 if (!a) 229 233 return EE_MEMORY; 230 234 231 235 /* 232 236 * The segment will be mapped on demand by elf_page_fault(). 233 *234 237 */ 235 238 236 239 return EE_OK; 237 240 } … … 240 243 * 241 244 * @param entry Segment header. 242 * @param elf 243 * @param as 245 * @param elf ELF header. 246 * @param as Address space into wich the ELF is being loaded. 244 247 * 245 248 * @return EE_OK on success, error code otherwise. 246 *247 249 */ 248 250 static int section_header(elf_section_header_t *entry, elf_header_t *elf,
Note:
See TracChangeset
for help on using the changeset viewer.