Changeset bdca26a in mainline
- Timestamp:
- 2019-05-26T13:21:50Z (5 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 8aea932
- Parents:
- 967e7a1
- git-author:
- Matthieu Riolo <matthieu.riolo@…> (2019-05-17 14:27:34)
- git-committer:
- Jakub Jermář <jakub@…> (2019-05-26 13:21:50)
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/lib/elf_load.h
r967e7a1 rbdca26a 38 38 #include <abi/elf.h> 39 39 40 /** 41 * ELF error return codes 42 */ 43 #define EE_OK 0 /* No error */ 44 #define EE_INVALID 1 /* Invalid ELF image */ 45 #define EE_MEMORY 2 /* Cannot allocate address space */ 46 #define EE_INCOMPATIBLE 3 /* ELF image is not compatible with current architecture */ 47 #define EE_UNSUPPORTED 4 /* Non-supported ELF (e.g. dynamic ELFs) */ 48 #define EE_IRRECOVERABLE 5 /* Irrecoverable error. */ 49 50 extern unsigned int elf_load(elf_header_t *, as_t *); 51 extern const char *elf_error(unsigned int rc); 40 extern errno_t elf_load(elf_header_t *, as_t *); 52 41 53 42 #endif -
kernel/generic/include/proc/program.h
r967e7a1 rbdca26a 50 50 struct task *task; /**< Program task */ 51 51 struct thread *main_thread; /**< Program main thread */ 52 unsigned int loader_status; /**< Binary loader error status */52 errno_t loader_status; /**< Binary loader error status */ 53 53 } program_t; 54 54 -
kernel/generic/src/lib/elf.c
r967e7a1 rbdca26a 50 50 #include <lib/elf_load.h> 51 51 52 static const char *error_codes[] = { 53 "no error", 54 "invalid image", 55 "address space error", 56 "incompatible image", 57 "unsupported image type", 58 "irrecoverable error" 59 }; 60 61 static int load_segment(elf_segment_header_t *, elf_header_t *, as_t *); 52 static errno_t load_segment(elf_segment_header_t *, elf_header_t *, as_t *); 62 53 63 54 /** ELF loader … … 67 58 * @param flags A combination of ELD_F_* 68 59 * 69 * @return E E_OK on success60 * @return EOK on success 70 61 * 71 62 */ 72 unsigned int elf_load(elf_header_t *header, as_t *as)63 errno_t elf_load(elf_header_t *header, as_t *as) 73 64 { 74 65 /* Identify ELF */ … … 77 68 (header->e_ident[EI_MAG2] != ELFMAG2) || 78 69 (header->e_ident[EI_MAG3] != ELFMAG3)) 79 return E E_INVALID;70 return EINVAL; 80 71 81 72 /* Identify ELF compatibility */ … … 85 76 (header->e_version != EV_CURRENT) || 86 77 (header->e_ident[EI_CLASS] != ELF_CLASS)) 87 return E E_INCOMPATIBLE;78 return EINVAL; 88 79 89 80 if (header->e_phentsize != sizeof(elf_segment_header_t)) 90 return E E_INCOMPATIBLE;81 return EINVAL; 91 82 92 83 /* Check if the object type is supported. */ 93 84 if (header->e_type != ET_EXEC) 94 return E E_UNSUPPORTED;85 return ENOTSUP; 95 86 96 87 /* Check if the ELF image starts on a page boundary */ 97 88 if (ALIGN_UP((uintptr_t) header, PAGE_SIZE) != (uintptr_t) header) 98 return E E_UNSUPPORTED;89 return ENOTSUP; 99 90 100 91 /* Walk through all segment headers and process them. */ … … 108 99 continue; 109 100 110 int rc = load_segment(seghdr, header, as);111 if (rc != E E_OK)101 errno_t rc = load_segment(seghdr, header, as); 102 if (rc != EOK) 112 103 return rc; 113 104 } 114 105 115 return EE_OK; 116 } 117 118 /** Print error message according to error code. 119 * 120 * @param rc Return code returned by elf_load(). 121 * 122 * @return NULL terminated description of error. 123 * 124 */ 125 const char *elf_error(unsigned int rc) 126 { 127 assert(rc < sizeof(error_codes) / sizeof(char *)); 128 129 return error_codes[rc]; 106 return EOK; 130 107 } 131 108 … … 136 113 * @param as Address space into wich the ELF is being loaded. 137 114 * 138 * @return E E_OK on success, error code otherwise.115 * @return EOK on success, error code otherwise. 139 116 * 140 117 */ 141 int load_segment(elf_segment_header_t *entry, elf_header_t *elf, as_t *as)118 errno_t load_segment(elf_segment_header_t *entry, elf_header_t *elf, as_t *as) 142 119 { 143 120 mem_backend_data_t backend_data; … … 146 123 if ((entry->p_offset % entry->p_align) != 147 124 (entry->p_vaddr % entry->p_align)) 148 return E E_INVALID;125 return EINVAL; 149 126 } 150 127 … … 177 154 AS_AREA_ATTR_NONE, &elf_backend, &backend_data, &base, 0); 178 155 if (!area) 179 return E E_MEMORY;156 return ENOMEM; 180 157 181 158 /* … … 184 161 */ 185 162 186 return E E_OK;163 return EOK; 187 164 } 188 165 -
kernel/generic/src/main/kinit.c
r967e7a1 rbdca26a 291 291 log(LF_OTHER, LVL_ERROR, 292 292 "init[%zu]: Init binary load failed " 293 "(error %s, loader status % u)", i,294 str_error_name(rc), programs[i].loader_status);293 "(error %s, loader status %s)", i, 294 str_error_name(rc), str_error_name(programs[i].loader_status)); 295 295 } 296 296 } -
kernel/generic/src/proc/program.c
r967e7a1 rbdca26a 48 48 #include <security/perm.h> 49 49 #include <lib/elf_load.h> 50 #include < errno.h>50 #include <str.h> 51 51 #include <log.h> 52 52 #include <syscall/copy.h> … … 76 76 return ENOMEM; 77 77 78 prg->loader_status = E E_OK;78 prg->loader_status = EOK; 79 79 prg->task = task_create(as, name); 80 80 if (!prg->task) { … … 149 149 150 150 prg->loader_status = elf_load((elf_header_t *) image_addr, as); 151 if (prg->loader_status != E E_OK) {151 if (prg->loader_status != EOK) { 152 152 as_release(as); 153 153 prg->task = NULL; … … 183 183 184 184 prg->loader_status = elf_load((elf_header_t *) program_loader, as); 185 if (prg->loader_status != E E_OK) {185 if (prg->loader_status != EOK) { 186 186 as_release(as); 187 187 log(LF_OTHER, LVL_ERROR, "Cannot spawn loader (%s)", 188 elf_error(prg->loader_status));188 str_error(prg->loader_status)); 189 189 return ENOENT; 190 190 } -
uspace/lib/c/generic/elf/elf_load.c
r967e7a1 rbdca26a 53 53 * @param file File handle 54 54 * @param info Place to store ELF program information 55 * @return E E_OK on success or an EE_xerror code55 * @return EOK on success or an error code 56 56 */ 57 int elf_load(int file, elf_info_t *info)57 errno_t elf_load(int file, elf_info_t *info) 58 58 { 59 59 #ifdef CONFIG_RTLD 60 60 rtld_t *env; 61 61 #endif 62 int rc;62 errno_t rc; 63 63 64 64 rc = elf_load_file(file, 0, &info->finfo); 65 if (rc != E E_OK) {65 if (rc != EOK) { 66 66 DPRINTF("Failed to load executable '%s'.\n", file_name); 67 67 return rc; … … 72 72 DPRINTF("Binary is statically linked.\n"); 73 73 info->env = NULL; 74 return E E_OK;74 return EOK; 75 75 } 76 76 … … 79 79 DPRINTF("- prog dynamic: %p\n", info->finfo.dynamic); 80 80 81 errno_t rc2 = rtld_prog_process(&info->finfo, &env); 82 switch (rc2) { 83 case EOK: 84 rc = EE_OK; 85 break; 86 case ENOMEM: 87 rc = EE_MEMORY; 88 break; 89 default: 90 DPRINTF("Unexpected error code from rtld_prog_process(): %s\n", str_error_name(rc2)); 91 rc = EE_INVALID; 92 } 93 81 rc = rtld_prog_process(&info->finfo, &env); 94 82 info->env = env; 95 83 #else 96 rc = E E_UNSUPPORTED;84 rc = ENOTSUP; 97 85 #endif 98 86 return rc; -
uspace/lib/c/generic/elf/elf_mod.c
r967e7a1 rbdca26a 64 64 #define DPRINTF(...) 65 65 66 static const char *error_codes[] = { 67 "no error", 68 "invalid image", 69 "address space error", 70 "incompatible image", 71 "unsupported image type", 72 "irrecoverable error", 73 "file io error" 74 }; 75 76 static unsigned int elf_load_module(elf_ld_t *elf); 77 static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry); 78 static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry); 66 static errno_t elf_load_module(elf_ld_t *elf); 67 static errno_t segment_header(elf_ld_t *elf, elf_segment_header_t *entry); 68 static errno_t load_segment(elf_ld_t *elf, elf_segment_header_t *entry); 79 69 80 70 /** Load ELF binary from a file. … … 90 80 * extracted from the binary. 91 81 * 92 * @return E E_OK on success or EE_xxerror code.93 * 94 */ 95 int elf_load_file(int file, eld_flags_t flags, elf_finfo_t *info)82 * @return EOK on success or an error code. 83 * 84 */ 85 errno_t elf_load_file(int file, eld_flags_t flags, elf_finfo_t *info) 96 86 { 97 87 elf_ld_t elf; … … 103 93 } 104 94 if (rc != EOK) { 105 return EE_IO;95 return rc; 106 96 } 107 97 … … 110 100 elf.flags = flags; 111 101 112 int ret= elf_load_module(&elf);102 rc = elf_load_module(&elf); 113 103 114 104 vfs_put(ofile); 115 return r et;116 } 117 118 int elf_load_file_name(const char *path, eld_flags_t flags, elf_finfo_t *info)105 return rc; 106 } 107 108 errno_t elf_load_file_name(const char *path, eld_flags_t flags, elf_finfo_t *info) 119 109 { 120 110 int file; 121 111 errno_t rc = vfs_lookup(path, 0, &file); 122 112 if (rc == EOK) { 123 int ret= elf_load_file(file, flags, info);113 rc = elf_load_file(file, flags, info); 124 114 vfs_put(file); 125 return r et;115 return rc; 126 116 } else { 127 return E E_IO;117 return EIO; 128 118 } 129 119 } … … 136 126 * 137 127 * @param elf Pointer to loader state buffer. 138 * @return E E_OK on success or EE_xxerror code.139 */ 140 static unsigned int elf_load_module(elf_ld_t *elf)128 * @return EOK on success or an error code. 129 */ 130 static errno_t elf_load_module(elf_ld_t *elf) 141 131 { 142 132 elf_header_t header_buf; … … 144 134 aoff64_t pos = 0; 145 135 size_t nr; 146 int i , ret;136 int i; 147 137 errno_t rc; 148 138 … … 150 140 if (rc != EOK || nr != sizeof(elf_header_t)) { 151 141 DPRINTF("Read error.\n"); 152 return E E_IO;142 return EIO; 153 143 } 154 144 … … 159 149 header->e_ident[EI_MAG3] != ELFMAG3) { 160 150 DPRINTF("Invalid header.\n"); 161 return E E_INVALID;151 return EINVAL; 162 152 } 163 153 … … 169 159 header->e_ident[EI_CLASS] != ELF_CLASS) { 170 160 DPRINTF("Incompatible data/version/class.\n"); 171 return E E_INCOMPATIBLE;161 return EINVAL; 172 162 } 173 163 … … 175 165 DPRINTF("e_phentsize: %u != %zu\n", header->e_phentsize, 176 166 sizeof(elf_segment_header_t)); 177 return E E_INCOMPATIBLE;167 return EINVAL; 178 168 } 179 169 … … 181 171 if (header->e_type != ET_EXEC && header->e_type != ET_DYN) { 182 172 DPRINTF("Object type %d is not supported\n", header->e_type); 183 return E E_UNSUPPORTED;173 return ENOTSUP; 184 174 } 185 175 186 176 if (header->e_phoff == 0) { 187 177 DPRINTF("Program header table is not present!\n"); 188 return E E_UNSUPPORTED;178 return ENOTSUP; 189 179 } 190 180 … … 203 193 if (phdr_len > sizeof(phdr)) { 204 194 DPRINTF("more than %d program headers\n", phdr_cap); 205 return E E_UNSUPPORTED;195 return ENOTSUP; 206 196 } 207 197 … … 210 200 if (rc != EOK || nr != phdr_len) { 211 201 DPRINTF("Read error.\n"); 212 return E E_IO;202 return EIO; 213 203 } 214 204 … … 231 221 if (base_offset != 0) { 232 222 DPRINTF("ELF headers not present in the text segment.\n"); 233 return E E_INVALID;223 return EINVAL; 234 224 } 235 225 … … 240 230 if (module_base != 0) { 241 231 DPRINTF("Unexpected shared object format.\n"); 242 return E E_INVALID;232 return EINVAL; 243 233 } 244 234 … … 258 248 if (area == AS_MAP_FAILED) { 259 249 DPRINTF("Can't find suitable memory area.\n"); 260 return E E_MEMORY;250 return ENOMEM; 261 251 } 262 252 … … 270 260 continue; 271 261 272 r et= load_segment(elf, &phdr[i]);273 if (r et != EE_OK)274 return r et;262 rc = load_segment(elf, &phdr[i]); 263 if (rc != EOK) 264 return rc; 275 265 } 276 266 … … 292 282 continue; 293 283 294 r et= segment_header(elf, &phdr[i]);295 if (r et != EE_OK)296 return r et;284 rc = segment_header(elf, &phdr[i]); 285 if (rc != EOK) 286 return rc; 297 287 } 298 288 … … 302 292 DPRINTF("Done.\n"); 303 293 304 return EE_OK; 305 } 306 307 /** Print error message according to error code. 308 * 309 * @param rc Return code returned by elf_load(). 310 * 311 * @return NULL terminated description of error. 312 */ 313 const char *elf_error(unsigned int rc) 314 { 315 assert(rc < sizeof(error_codes) / sizeof(char *)); 316 317 return error_codes[rc]; 294 return EOK; 318 295 } 319 296 … … 338 315 * @param entry Segment header. 339 316 * 340 * @return E E_OK on success, error code otherwise.341 */ 342 static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry)317 * @return EOK on success, error code otherwise. 318 */ 319 static errno_t segment_header(elf_ld_t *elf, elf_segment_header_t *entry) 343 320 { 344 321 switch (entry->p_type) { … … 358 335 if (entry->p_filesz == 0) { 359 336 DPRINTF("Zero-sized ELF interp string.\n"); 360 return E E_INVALID;337 return EINVAL; 361 338 } 362 339 if (elf->info->interp[entry->p_filesz - 1] != '\0') { 363 340 DPRINTF("Unterminated ELF interp string.\n"); 364 return E E_INVALID;341 return EINVAL; 365 342 } 366 343 DPRINTF("interpreter: \"%s\"\n", elf->info->interp); … … 389 366 default: 390 367 DPRINTF("Segment p_type %d unknown.\n", entry->p_type); 391 return E E_UNSUPPORTED;392 break; 393 } 394 return E E_OK;368 return ENOTSUP; 369 break; 370 } 371 return EOK; 395 372 } 396 373 … … 400 377 * @param entry Program header entry describing segment to be loaded. 401 378 * 402 * @return E E_OK on success, error code otherwise.403 */ 404 int load_segment(elf_ld_t *elf, elf_segment_header_t *entry)379 * @return EOK on success, error code otherwise. 380 */ 381 errno_t load_segment(elf_ld_t *elf, elf_segment_header_t *entry) 405 382 { 406 383 void *a; … … 435 412 entry->p_offset % entry->p_align, 436 413 seg_addr % entry->p_align, entry->p_align); 437 return E E_INVALID;414 return EINVAL; 438 415 } 439 416 } … … 466 443 DPRINTF("memory mapping failed (%p, %zu)\n", 467 444 (void *) (base + bias), mem_sz); 468 return E E_MEMORY;445 return ENOMEM; 469 446 } 470 447 … … 479 456 if (rc != EOK || nr != entry->p_filesz) { 480 457 DPRINTF("read error\n"); 481 return E E_IO;458 return EIO; 482 459 } 483 460 … … 487 464 */ 488 465 if ((elf->flags & ELDF_RW) != 0) 489 return E E_OK;466 return EOK; 490 467 491 468 DPRINTF("as_area_change_flags(%p, %x)\n", … … 494 471 if (rc != EOK) { 495 472 DPRINTF("Failed to set memory area flags.\n"); 496 return E E_MEMORY;473 return ENOMEM; 497 474 } 498 475 … … 500 477 /* Enforce SMC coherence for the segment */ 501 478 if (smc_coherence(seg_ptr, entry->p_filesz)) 502 return E E_MEMORY;503 } 504 505 return E E_OK;479 return ENOMEM; 480 } 481 482 return EOK; 506 483 } 507 484 -
uspace/lib/c/generic/rtld/module.c
r967e7a1 rbdca26a 65 65 66 66 module = calloc(1, sizeof(module_t)); 67 if (module == NULL) 67 if (module == NULL) { 68 DPRINTF("malloc failed\n"); 68 69 return ENOMEM; 70 } 69 71 70 72 module->id = rtld_get_next_id(rtld); … … 182 184 char name_buf[NAME_BUF_SIZE]; 183 185 module_t *m; 184 int rc;186 errno_t rc; 185 187 186 188 m = calloc(1, sizeof(module_t)); 187 189 if (m == NULL) { 188 printf("malloc failed\n");190 DPRINTF("malloc failed\n"); 189 191 goto error; 190 192 } … … 197 199 198 200 if (str_size(name) > NAME_BUF_SIZE - 2) { 199 printf("soname too long. increase NAME_BUF_SIZE\n");201 DPRINTF("soname too long. increase NAME_BUF_SIZE\n"); 200 202 goto error; 201 203 } … … 208 210 209 211 rc = elf_load_file_name(name_buf, RTLD_MODULE_LDF, &info); 210 if (rc != E E_OK) {211 printf("Failed to load '%s'\n", name_buf);212 if (rc != EOK) { 213 DPRINTF("Failed to load '%s'\n", name_buf); 212 214 goto error; 213 215 } … … 218 220 219 221 if (info.dynamic == NULL) { 220 printf("Error: '%s' is not a dynamically-linked object.\n",222 DPRINTF("Error: '%s' is not a dynamically-linked object.\n", 221 223 name_buf); 222 224 goto error; … … 285 287 m->deps = malloc(n * sizeof(module_t *)); 286 288 if (!m->deps) { 287 printf("malloc failed\n");289 DPRINTF("malloc failed\n"); 288 290 return ENOMEM; 289 291 } -
uspace/lib/c/include/elf/elf_load.h
r967e7a1 rbdca26a 45 45 } elf_info_t; 46 46 47 extern int elf_load(int, elf_info_t *);47 extern errno_t elf_load(int, elf_info_t *); 48 48 extern void elf_set_pcb(elf_info_t *, pcb_t *); 49 49 -
uspace/lib/c/include/elf/elf_mod.h
r967e7a1 rbdca26a 42 42 #include <stdint.h> 43 43 #include <loader/pcb.h> 44 45 /**46 * ELF error return codes47 */48 #define EE_OK 0 /* No error */49 #define EE_INVALID 1 /* Invalid ELF image */50 #define EE_MEMORY 2 /* Cannot allocate address space */51 #define EE_INCOMPATIBLE 3 /* ELF image is not compatible with current architecture */52 #define EE_UNSUPPORTED 4 /* Non-supported ELF (e.g. dynamic ELFs) */53 #define EE_IRRECOVERABLE 554 #define EE_IO 6 /* Could not read file. */55 44 56 45 typedef enum { … … 110 99 } elf_ld_t; 111 100 112 extern const char *elf_error(unsigned int); 113 extern int elf_load_file(int, eld_flags_t, elf_finfo_t *); 114 extern int elf_load_file_name(const char *, eld_flags_t, elf_finfo_t *); 101 extern errno_t elf_load_file(int, eld_flags_t, elf_finfo_t *); 102 extern errno_t elf_load_file_name(const char *, eld_flags_t, elf_finfo_t *); 115 103 116 104 #endif -
uspace/srv/loader/main.c
r967e7a1 rbdca26a 290 290 DPRINTF("LOADER_LOAD()\n"); 291 291 292 int rc = elf_load(program_fd, &prog_info);293 if (rc != E E_OK) {292 errno_t rc = elf_load(program_fd, &prog_info); 293 if (rc != EOK) { 294 294 DPRINTF("Failed to load executable for '%s'.\n", progname); 295 295 async_answer_0(req, EINVAL);
Note:
See TracChangeset
for help on using the changeset viewer.