Changes in kernel/generic/src/lib/elf.c [d99c1d2:da1bafb] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/lib/elf.c
rd99c1d2 rda1bafb 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 … … 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. 135 * 138 136 */ 139 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)154 as_t *as, unsigned int flags) 156 155 { 157 156 switch (entry->p_type) { … … 170 169 return EE_UNSUPPORTED; 171 170 } */ 172 if ((flags & ELD_F_LOADER) == 0) {171 if ((flags & ELD_F_LOADER) == 0) 173 172 return EE_LOADER; 174 }175 173 break; 176 174 case PT_SHLIB: … … 187 185 * 188 186 * @param entry Program header entry describing segment to be loaded. 189 * @param elf ELF header.190 * @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. 191 189 * 192 190 * @return EE_OK on success, error code otherwise. 191 * 193 192 */ 194 193 int load_segment(elf_segment_header_t *entry, elf_header_t *elf, as_t *as) 195 194 { 196 as_area_t *a;197 int flags = 0;198 195 mem_backend_data_t backend_data; 199 uintptr_t base;200 size_t mem_sz;201 202 196 backend_data.elf = elf; 203 197 backend_data.segment = entry; 204 198 205 199 if (entry->p_align > 1) { 206 200 if ((entry->p_offset % entry->p_align) != 207 (entry->p_vaddr % entry->p_align)) {201 (entry->p_vaddr % entry->p_align)) 208 202 return EE_INVALID; 209 } 210 } 211 203 } 204 205 unsigned int flags = 0; 206 212 207 if (entry->p_flags & PF_X) 213 208 flags |= AS_AREA_EXEC; 209 214 210 if (entry->p_flags & PF_W) 215 211 flags |= AS_AREA_WRITE; 212 216 213 if (entry->p_flags & PF_R) 217 214 flags |= AS_AREA_READ; 215 218 216 flags |= AS_AREA_CACHEABLE; 219 220 /* 217 218 /* 221 219 * Align vaddr down, inserting a little "gap" at the beginning. 222 220 * Adjust area size, so that its end remains in place. 221 * 223 222 */ 224 base = ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE);225 mem_sz = entry->p_memsz + (entry->p_vaddr - base);226 227 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, 228 227 AS_AREA_ATTR_NONE, &elf_backend, &backend_data); 229 if (!a )228 if (!area) 230 229 return EE_MEMORY; 231 230 232 231 /* 233 232 * The segment will be mapped on demand by elf_page_fault(). 233 * 234 234 */ 235 235 236 236 return EE_OK; 237 237 } … … 240 240 * 241 241 * @param entry Segment header. 242 * @param elf ELF header.243 * @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. 244 244 * 245 245 * @return EE_OK on success, error code otherwise. 246 * 246 247 */ 247 248 static int section_header(elf_section_header_t *entry, elf_header_t *elf,
Note:
See TracChangeset
for help on using the changeset viewer.