Changes in kernel/generic/src/lib/elf.c [1ea99cc:1e00216] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/lib/elf.c
r1ea99cc r1e00216 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 < 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: 161 158 case PT_PHDR: 159 case PT_NOTE: 162 160 break; 163 161 case PT_LOAD: 164 162 return load_segment(entry, elf, as); 165 break;166 163 case PT_DYNAMIC: 167 164 case PT_INTERP: 168 interp = (char *)elf + entry->p_offset; 169 /* DO NOT COMMIT ME */ 170 /*if (memcmp((uintptr_t)interp, (uintptr_t)ELF_INTERP_ZSTR, 165 // FIXME 166 /* 167 char *interp = (char *) elf + entry->p_offset; 168 if (memcmp((uintptr_t) interp, (uintptr_t) ELF_INTERP_ZSTR, 171 169 ELF_INTERP_ZLEN) != 0) { 172 170 return EE_UNSUPPORTED; 173 } */174 if ((flags & ELD_F_LOADER) == 0) {171 } */ 172 if ((flags & ELD_F_LOADER) == 0) 175 173 return EE_LOADER; 176 }177 174 break; 178 175 case PT_SHLIB: 179 case PT_NOTE:180 176 case PT_LOPROC: 181 177 case PT_HIPROC: 182 178 default: 183 179 return EE_UNSUPPORTED; 184 break;185 180 } 186 181 return EE_OK; … … 190 185 * 191 186 * @param entry Program header entry describing segment to be loaded. 192 * @param elf ELF header.193 * @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. 194 189 * 195 190 * @return EE_OK on success, error code otherwise. 191 * 196 192 */ 197 193 int load_segment(elf_segment_header_t *entry, elf_header_t *elf, as_t *as) 198 194 { 199 as_area_t *a;200 int flags = 0;201 195 mem_backend_data_t backend_data; 202 uintptr_t base;203 size_t mem_sz;204 205 196 backend_data.elf = elf; 206 197 backend_data.segment = entry; 207 198 208 199 if (entry->p_align > 1) { 209 200 if ((entry->p_offset % entry->p_align) != 210 (entry->p_vaddr % entry->p_align)) {201 (entry->p_vaddr % entry->p_align)) 211 202 return EE_INVALID; 212 } 213 } 214 203 } 204 205 unsigned int flags = 0; 206 215 207 if (entry->p_flags & PF_X) 216 208 flags |= AS_AREA_EXEC; 209 217 210 if (entry->p_flags & PF_W) 218 211 flags |= AS_AREA_WRITE; 212 219 213 if (entry->p_flags & PF_R) 220 214 flags |= AS_AREA_READ; 215 221 216 flags |= AS_AREA_CACHEABLE; 222 223 /* 217 218 /* 224 219 * Align vaddr down, inserting a little "gap" at the beginning. 225 220 * Adjust area size, so that its end remains in place. 221 * 226 222 */ 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,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, 231 227 AS_AREA_ATTR_NONE, &elf_backend, &backend_data); 232 if (!a )228 if (!area) 233 229 return EE_MEMORY; 234 230 235 231 /* 236 232 * The segment will be mapped on demand by elf_page_fault(). 233 * 237 234 */ 238 235 239 236 return EE_OK; 240 237 } … … 243 240 * 244 241 * @param entry Segment header. 245 * @param elf ELF header.246 * @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. 247 244 * 248 245 * @return EE_OK on success, error code otherwise. 246 * 249 247 */ 250 248 static int section_header(elf_section_header_t *entry, elf_header_t *elf,
Note:
See TracChangeset
for help on using the changeset viewer.