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