Print this page
10476 file(1) could be smatch clean
10366 ld(1) should support GNU-style linker sets
10581 ld(1) should know kernel modules are a thing

*** 77,86 **** --- 77,87 ---- #include <procfs.h> #include <sys/param.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/elf.h> + #include <sys/link.h> #include <elfcap.h> #include "file.h" #include "elf_read.h" extern const char *File;
*** 139,149 **** format = get_format(); /* will convert only these types */ if (type != ELF_T_EHDR && type != ELF_T_PHDR && type != ELF_T_SHDR && type != ELF_T_WORD && ! type != ELF_T_CAP) return (ELF_READ_FAIL); src.d_buf = (Elf_Void *)hdr; src.d_type = type; src.d_version = version; --- 140,150 ---- format = get_format(); /* will convert only these types */ if (type != ELF_T_EHDR && type != ELF_T_PHDR && type != ELF_T_SHDR && type != ELF_T_WORD && ! type != ELF_T_CAP && type != ELF_T_DYN) return (ELF_READ_FAIL); src.d_buf = (Elf_Void *)hdr; src.d_type = type; src.d_version = version;
*** 413,433 **** * in Elf_Info with corresponding flags. */ static int process_shdr(Elf_Info *EI) { ! int capn, mac; ! int i, j, idx; ! FILE_ELF_OFF_T cap_off; ! FILE_ELF_SIZE_T csize; char *strtab; size_t strtab_sz; ! Elf_Cap Chdr; Elf_Shdr *shdr = &EI_Shdr; - - csize = sizeof (Elf_Cap); mac = EI_Ehdr.e_machine; /* if there are no sections, return success anyway */ if (EI_Ehdr.e_shoff == 0 && EI_Ehdr_shnum == 0) return (ELF_READ_OKAY); --- 414,430 ---- * in Elf_Info with corresponding flags. */ static int process_shdr(Elf_Info *EI) { ! int mac; ! int i, idx; char *strtab; size_t strtab_sz; ! uint64_t j; Elf_Shdr *shdr = &EI_Shdr; mac = EI_Ehdr.e_machine; /* if there are no sections, return success anyway */ if (EI_Ehdr.e_shoff == 0 && EI_Ehdr_shnum == 0) return (ELF_READ_OKAY);
*** 455,467 **** if (shdr->sh_type == SHT_NULL) { idx--; continue; } - cap_off = shdr->sh_offset; if (shdr->sh_type == SHT_SUNW_cap) { char capstr[128]; if (shdr->sh_size == 0 || shdr->sh_entsize == 0) { (void) fprintf(stderr, ELF_ERR_ELFCAP1, File, EI->file); return (ELF_READ_FAIL); --- 452,470 ---- if (shdr->sh_type == SHT_NULL) { idx--; continue; } if (shdr->sh_type == SHT_SUNW_cap) { char capstr[128]; + Elf_Cap Chdr; + FILE_ELF_OFF_T cap_off; + FILE_ELF_SIZE_T csize; + uint64_t capn; + + cap_off = shdr->sh_offset; + csize = sizeof (Elf_Cap); if (shdr->sh_size == 0 || shdr->sh_entsize == 0) { (void) fprintf(stderr, ELF_ERR_ELFCAP1, File, EI->file); return (ELF_READ_FAIL);
*** 469,480 **** capn = (shdr->sh_size / shdr->sh_entsize); for (j = 0; j < capn; j++) { /* * read cap and xlate the values */ ! if (pread64(EI->elffd, &Chdr, csize, cap_off) ! != csize || file_xlatetom(ELF_T_CAP, (char *)&Chdr) == 0) { (void) fprintf(stderr, ELF_ERR_ELFCAP2, File, EI->file); return (ELF_READ_FAIL); --- 472,483 ---- capn = (shdr->sh_size / shdr->sh_entsize); for (j = 0; j < capn; j++) { /* * read cap and xlate the values */ ! if ((pread64(EI->elffd, &Chdr, csize, cap_off) ! != csize) || file_xlatetom(ELF_T_CAP, (char *)&Chdr) == 0) { (void) fprintf(stderr, ELF_ERR_ELFCAP2, File, EI->file); return (ELF_READ_FAIL);
*** 501,510 **** --- 504,546 ---- sizeof (EI->cap_str)); (void) strlcat(EI->cap_str, capstr, sizeof (EI->cap_str)); } + } else if (shdr->sh_type == SHT_DYNAMIC) { + Elf_Dyn dyn; + FILE_ELF_SIZE_T dsize; + FILE_ELF_OFF_T doff; + uint64_t dynn; + + doff = shdr->sh_offset; + dsize = sizeof (Elf_Dyn); + + if (shdr->sh_size == 0 || shdr->sh_entsize == 0) { + (void) fprintf(stderr, ELF_ERR_DYNAMIC1, + File, EI->file); + return (ELF_READ_FAIL); + } + + dynn = (shdr->sh_size / shdr->sh_entsize); + for (j = 0; j < dynn; j++) { + if (pread64(EI->elffd, &dyn, dsize, doff) + != dsize || + file_xlatetom(ELF_T_DYN, (char *)&dyn) + == 0) { + (void) fprintf(stderr, ELF_ERR_DYNAMIC2, + File, EI->file); + return (ELF_READ_FAIL); + } + + doff += dsize; + + if ((dyn.d_tag == DT_SUNW_KMOD) && + (dyn.d_un.d_val == 1)) { + EI->kmod = B_TRUE; + } + } } /* * Definition time: * - "not stripped" means that an executable file