diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2016-03-07 18:44:06 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2016-03-07 18:44:06 +0000 |
commit | 3cfce8e4df1ae10371b49d0c79e1fe03b24844ea (patch) | |
tree | d944368883b0c61b39a1bb7e3cb276709ba73cc3 | |
parent | 5e67bb7b192915e9508ce175a8961a760419751a (diff) |
Notes
-rw-r--r-- | sys/kern/link_elf_obj.c | 133 |
1 files changed, 92 insertions, 41 deletions
diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c index dfbcdfebe4c3..012d5b7695d8 100644 --- a/sys/kern/link_elf_obj.c +++ b/sys/kern/link_elf_obj.c @@ -140,7 +140,7 @@ static int link_elf_each_function_name(linker_file_t, static int link_elf_each_function_nameval(linker_file_t, linker_function_nameval_callback_t, void *); -static void link_elf_reloc_local(linker_file_t); +static int link_elf_reloc_local(linker_file_t); static long link_elf_symtab_get(linker_file_t, const Elf_Sym **); static long link_elf_strtab_get(linker_file_t, caddr_t *); @@ -405,15 +405,26 @@ link_elf_link_preload(linker_class_t cls, const char *filename, break; } } - if (pb != ef->nprogtab) - panic("lost progbits"); - if (rl != ef->nreltab) - panic("lost reltab"); - if (ra != ef->nrelatab) - panic("lost relatab"); + if (pb != ef->nprogtab) { + printf("%s: lost progbits\n", filename); + error = ENOEXEC; + goto out; + } + if (rl != ef->nreltab) { + printf("%s: lost reltab\n", filename); + error = ENOEXEC; + goto out; + } + if (ra != ef->nrelatab) { + printf("%s: lost relatab\n", filename); + error = ENOEXEC; + goto out; + } /* Local intra-module relocations */ - link_elf_reloc_local(lf); + error = link_elf_reloc_local(lf); + if (error != 0) + goto out; *result = lf; return (0); @@ -634,8 +645,11 @@ link_elf_load_file(linker_class_t cls, const char *filename, ef->relatab = malloc(ef->nrelatab * sizeof(*ef->relatab), M_LINKER, M_WAITOK | M_ZERO); - if (symtabindex == -1) - panic("lost symbol table index"); + if (symtabindex == -1) { + link_elf_error(filename, "lost symbol table index"); + error = ENOEXEC; + goto out; + } /* Allocate space for and load the symbol table */ ef->ddbsymcnt = shdr[symtabindex].sh_size / sizeof(Elf_Sym); ef->ddbsymtab = malloc(shdr[symtabindex].sh_size, M_LINKER, M_WAITOK); @@ -650,8 +664,11 @@ link_elf_load_file(linker_class_t cls, const char *filename, goto out; } - if (symstrindex == -1) - panic("lost symbol string index"); + if (symstrindex == -1) { + link_elf_error(filename, "lost symbol string index"); + error = ENOEXEC; + goto out; + } /* Allocate space for and load the symbol strings */ ef->ddbstrcnt = shdr[symstrindex].sh_size; ef->ddbstrtab = malloc(shdr[symstrindex].sh_size, M_LINKER, M_WAITOK); @@ -884,19 +901,35 @@ link_elf_load_file(linker_class_t cls, const char *filename, break; } } - if (pb != ef->nprogtab) - panic("lost progbits"); - if (rl != ef->nreltab) - panic("lost reltab"); - if (ra != ef->nrelatab) - panic("lost relatab"); - if (mapbase != (vm_offset_t)ef->address + mapsize) - panic("mapbase 0x%lx != address %p + mapsize 0x%lx (0x%lx)\n", + if (pb != ef->nprogtab) { + link_elf_error(filename, "lost progbits"); + error = ENOEXEC; + goto out; + } + if (rl != ef->nreltab) { + link_elf_error(filename, "lost reltab"); + error = ENOEXEC; + goto out; + } + if (ra != ef->nrelatab) { + link_elf_error(filename, "lost relatab"); + error = ENOEXEC; + goto out; + } + if (mapbase != (vm_offset_t)ef->address + mapsize) { + printf( + "%s: mapbase 0x%lx != address %p + mapsize 0x%lx (0x%lx)\n", + filename != NULL ? filename : "<none>", (u_long)mapbase, ef->address, (u_long)mapsize, (u_long)(vm_offset_t)ef->address + mapsize); + error = ENOMEM; + goto out; + } /* Local intra-module relocations */ - link_elf_reloc_local(lf); + error = link_elf_reloc_local(lf); + if (error != 0) + goto out; /* Pull in dependencies */ VOP_UNLOCK(nd.ni_vp, 0); @@ -1034,12 +1067,16 @@ relocate_file(elf_file_t ef) /* Perform relocations without addend if there are any: */ for (i = 0; i < ef->nreltab; i++) { rel = ef->reltab[i].rel; - if (rel == NULL) - panic("lost a reltab!"); + if (rel == NULL) { + link_elf_error(ef->lf.filename, "lost a reltab!"); + return (ENOEXEC); + } rellim = rel + ef->reltab[i].nrel; base = findbase(ef, ef->reltab[i].sec); - if (base == 0) - panic("lost base for reltab"); + if (base == 0) { + link_elf_error(ef->lf.filename, "lost base for reltab"); + return (ENOEXEC); + } for ( ; rel < rellim; rel++) { symidx = ELF_R_SYM(rel->r_info); if (symidx >= ef->ddbsymcnt) @@ -1053,7 +1090,7 @@ relocate_file(elf_file_t ef) symname = symbol_name(ef, rel->r_info); printf("link_elf_obj: symbol %s undefined\n", symname); - return ENOENT; + return (ENOENT); } } } @@ -1061,12 +1098,17 @@ relocate_file(elf_file_t ef) /* Perform relocations with addend if there are any: */ for (i = 0; i < ef->nrelatab; i++) { rela = ef->relatab[i].rela; - if (rela == NULL) - panic("lost a relatab!"); + if (rela == NULL) { + link_elf_error(ef->lf.filename, "lost a relatab!"); + return (ENOEXEC); + } relalim = rela + ef->relatab[i].nrela; base = findbase(ef, ef->relatab[i].sec); - if (base == 0) - panic("lost base for relatab"); + if (base == 0) { + link_elf_error(ef->lf.filename, + "lost base for relatab"); + return (ENOEXEC); + } for ( ; rela < relalim; rela++) { symidx = ELF_R_SYM(rela->r_info); if (symidx >= ef->ddbsymcnt) @@ -1080,7 +1122,7 @@ relocate_file(elf_file_t ef) symname = symbol_name(ef, rela->r_info); printf("link_elf_obj: symbol %s undefined\n", symname); - return ENOENT; + return (ENOENT); } } } @@ -1092,7 +1134,7 @@ relocate_file(elf_file_t ef) */ elf_obj_cleanup_globals_cache(ef); - return 0; + return (0); } static int @@ -1375,7 +1417,7 @@ link_elf_fix_link_set(elf_file_t ef) } } -static void +static int link_elf_reloc_local(linker_file_t lf) { elf_file_t ef = (elf_file_t)lf; @@ -1393,12 +1435,16 @@ link_elf_reloc_local(linker_file_t lf) /* Perform relocations without addend if there are any: */ for (i = 0; i < ef->nreltab; i++) { rel = ef->reltab[i].rel; - if (rel == NULL) - panic("lost a reltab!"); + if (rel == NULL) { + link_elf_error(ef->lf.filename, "lost a reltab"); + return (ENOEXEC); + } rellim = rel + ef->reltab[i].nrel; base = findbase(ef, ef->reltab[i].sec); - if (base == 0) - panic("lost base for reltab"); + if (base == 0) { + link_elf_error(ef->lf.filename, "lost base for reltab"); + return (ENOEXEC); + } for ( ; rel < rellim; rel++) { symidx = ELF_R_SYM(rel->r_info); if (symidx >= ef->ddbsymcnt) @@ -1415,12 +1461,16 @@ link_elf_reloc_local(linker_file_t lf) /* Perform relocations with addend if there are any: */ for (i = 0; i < ef->nrelatab; i++) { rela = ef->relatab[i].rela; - if (rela == NULL) - panic("lost a relatab!"); + if (rela == NULL) { + link_elf_error(ef->lf.filename, "lost a relatab!"); + return (ENOEXEC); + } relalim = rela + ef->relatab[i].nrela; base = findbase(ef, ef->relatab[i].sec); - if (base == 0) - panic("lost base for relatab"); + if (base == 0) { + link_elf_error(ef->lf.filename, "lost base for reltab"); + return (ENOEXEC); + } for ( ; rela < relalim; rela++) { symidx = ELF_R_SYM(rela->r_info); if (symidx >= ef->ddbsymcnt) @@ -1433,6 +1483,7 @@ link_elf_reloc_local(linker_file_t lf) elf_obj_lookup); } } + return (0); } static long |