Print this page
file: support DT_SUNW_KMOD usefully
@@ -77,10 +77,11 @@
#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,11 +140,11 @@
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_CAP && type != ELF_T_DYN)
return (ELF_READ_FAIL);
src.d_buf = (Elf_Void *)hdr;
src.d_type = type;
src.d_version = version;
@@ -413,21 +414,16 @@
* in Elf_Info with corresponding flags.
*/
static int
process_shdr(Elf_Info *EI)
{
- int capn, mac;
+ int 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);
@@ -455,13 +451,19 @@
if (shdr->sh_type == SHT_NULL) {
idx--;
continue;
}
- cap_off = shdr->sh_offset;
if (shdr->sh_type == SHT_SUNW_cap) {
char capstr[128];
+ Elf_Cap Chdr;
+ FILE_ELF_OFF_T cap_off;
+ FILE_ELF_SIZE_T csize;
+ int 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,12 +471,12 @@
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 ||
+ 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,10 +503,43 @@
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;
+ int 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