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