62 */
63 #define _LARGEFILE64_SOURCE
64 #define FILE_ELF_OFF_T off64_t
65 #define FILE_ELF_SIZE_T uint64_t
66
67 #include <ctype.h>
68 #include <unistd.h>
69 #include <fcntl.h>
70 #include <stdio.h>
71 #include <libelf.h>
72 #include <stdlib.h>
73 #include <limits.h>
74 #include <locale.h>
75 #include <string.h>
76 #include <errno.h>
77 #include <procfs.h>
78 #include <sys/param.h>
79 #include <sys/types.h>
80 #include <sys/stat.h>
81 #include <sys/elf.h>
82 #include <elfcap.h>
83 #include "file.h"
84 #include "elf_read.h"
85
86 extern const char *File;
87
88 static int get_class(void);
89 static int get_version(void);
90 static int get_format(void);
91 static int process_shdr(Elf_Info *);
92 static int process_phdr(Elf_Info *);
93 static int file_xlatetom(Elf_Type, char *);
94 static int xlatetom_nhdr(Elf_Nhdr *);
95 static int get_phdr(Elf_Info *, int);
96 static int get_shdr(Elf_Info *, int);
97
98 static Elf_Ehdr EI_Ehdr; /* Elf_Ehdr to be stored */
99 static Elf_Word EI_Ehdr_shnum; /* # section headers */
100 static Elf_Word EI_Ehdr_phnum; /* # program headers */
101 static Elf_Word EI_Ehdr_shstrndx; /* Index of section hdr string table */
124 }
125
126 /*
127 * file_xlatetom: translate different headers from file
128 * representation to memory representaion.
129 */
130 #define HDRSZ 512
131 static int
132 file_xlatetom(Elf_Type type, char *hdr)
133 {
134 Elf_Data src, dst;
135 char *hbuf[HDRSZ];
136 int version, format;
137
138 version = get_version();
139 format = get_format();
140
141 /* will convert only these types */
142 if (type != ELF_T_EHDR && type != ELF_T_PHDR &&
143 type != ELF_T_SHDR && type != ELF_T_WORD &&
144 type != ELF_T_CAP)
145 return (ELF_READ_FAIL);
146
147 src.d_buf = (Elf_Void *)hdr;
148 src.d_type = type;
149 src.d_version = version;
150
151 dst.d_buf = (Elf_Void *)&hbuf;
152 dst.d_version = EV_CURRENT;
153
154 src.d_size = elf_fsize(type, 1, version);
155 dst.d_size = elf_fsize(type, 1, EV_CURRENT);
156 if (elf_xlatetom(&dst, &src, format) == NULL)
157 return (ELF_READ_FAIL);
158
159 (void) memcpy(hdr, &hbuf, dst.d_size);
160 return (ELF_READ_OKAY);
161 }
162
163 /*
164 * xlatetom_nhdr: There is no routine to convert Note header
398 free(psinfo);
399 }
400 if (phdr->p_type == PT_DYNAMIC) {
401 EI->dynamic = B_TRUE;
402 }
403 }
404 return (ELF_READ_OKAY);
405 }
406
407 /*
408 * process_shdr: Read Section Headers to attempt to get HW/SW
409 * capabilities by looking at the SUNW_cap
410 * section and set string in Elf_Info.
411 * Also look for symbol tables and debug
412 * information sections. Set the "stripped" field
413 * in Elf_Info with corresponding flags.
414 */
415 static int
416 process_shdr(Elf_Info *EI)
417 {
418 int capn, mac;
419 int i, j, idx;
420 FILE_ELF_OFF_T cap_off;
421 FILE_ELF_SIZE_T csize;
422 char *strtab;
423 size_t strtab_sz;
424 Elf_Cap Chdr;
425 Elf_Shdr *shdr = &EI_Shdr;
426
427
428 csize = sizeof (Elf_Cap);
429 mac = EI_Ehdr.e_machine;
430
431 /* if there are no sections, return success anyway */
432 if (EI_Ehdr.e_shoff == 0 && EI_Ehdr_shnum == 0)
433 return (ELF_READ_OKAY);
434
435 /* read section names from String Section */
436 if (get_shdr(EI, EI_Ehdr_shstrndx) == ELF_READ_FAIL)
437 return (ELF_READ_FAIL);
438
439 if ((strtab = malloc(shdr->sh_size)) == NULL)
440 return (ELF_READ_FAIL);
441
442 if (pread64(EI->elffd, strtab, shdr->sh_size, shdr->sh_offset)
443 != shdr->sh_size)
444 return (ELF_READ_FAIL);
445
446 strtab_sz = shdr->sh_size;
447
448 /* read all the sections and process them */
449 for (idx = 1, i = 0; i < EI_Ehdr_shnum; idx++, i++) {
450 char *shnam;
451
452 if (get_shdr(EI, i) == ELF_READ_FAIL)
453 return (ELF_READ_FAIL);
454
455 if (shdr->sh_type == SHT_NULL) {
456 idx--;
457 continue;
458 }
459
460 cap_off = shdr->sh_offset;
461 if (shdr->sh_type == SHT_SUNW_cap) {
462 char capstr[128];
463
464 if (shdr->sh_size == 0 || shdr->sh_entsize == 0) {
465 (void) fprintf(stderr, ELF_ERR_ELFCAP1,
466 File, EI->file);
467 return (ELF_READ_FAIL);
468 }
469 capn = (shdr->sh_size / shdr->sh_entsize);
470 for (j = 0; j < capn; j++) {
471 /*
472 * read cap and xlate the values
473 */
474 if (pread64(EI->elffd, &Chdr, csize, cap_off)
475 != csize ||
476 file_xlatetom(ELF_T_CAP, (char *)&Chdr)
477 == 0) {
478 (void) fprintf(stderr, ELF_ERR_ELFCAP2,
479 File, EI->file);
480 return (ELF_READ_FAIL);
481 }
482
483 cap_off += csize;
484
485 /*
486 * Each capatibility group is terminated with
487 * CA_SUNW_NULL. Groups other than the first
488 * represent symbol capabilities, and aren't
489 * interesting here.
490 */
491 if (Chdr.c_tag == CA_SUNW_NULL)
492 break;
493
494 (void) elfcap_tag_to_str(ELFCAP_STYLE_UC,
495 Chdr.c_tag, Chdr.c_un.c_val, capstr,
496 sizeof (capstr), ELFCAP_FMT_SNGSPACE,
497 mac);
498
499 if ((*EI->cap_str != '\0') && (*capstr != '\0'))
500 (void) strlcat(EI->cap_str, " ",
501 sizeof (EI->cap_str));
502
503 (void) strlcat(EI->cap_str, capstr,
504 sizeof (EI->cap_str));
505 }
506 }
507
508 /*
509 * Definition time:
510 * - "not stripped" means that an executable file
511 * contains a Symbol Table (.symtab)
512 * - "stripped" means that an executable file
513 * does not contain a Symbol Table.
514 * When strip -l or strip -x is run, it strips the
515 * debugging information (.line section name (strip -l),
516 * .line, .debug*, .stabs*, .dwarf* section names
517 * and SHT_SUNW_DEBUGSTR and SHT_SUNW_DEBUG
518 * section types (strip -x), however the Symbol
519 * Table will still be present.
520 * Therefore, if
521 * - No Symbol Table present, then report
522 * "stripped"
523 * - Symbol Table present with debugging
524 * information (line number or debug section names,
|
62 */
63 #define _LARGEFILE64_SOURCE
64 #define FILE_ELF_OFF_T off64_t
65 #define FILE_ELF_SIZE_T uint64_t
66
67 #include <ctype.h>
68 #include <unistd.h>
69 #include <fcntl.h>
70 #include <stdio.h>
71 #include <libelf.h>
72 #include <stdlib.h>
73 #include <limits.h>
74 #include <locale.h>
75 #include <string.h>
76 #include <errno.h>
77 #include <procfs.h>
78 #include <sys/param.h>
79 #include <sys/types.h>
80 #include <sys/stat.h>
81 #include <sys/elf.h>
82 #include <sys/link.h>
83 #include <elfcap.h>
84 #include "file.h"
85 #include "elf_read.h"
86
87 extern const char *File;
88
89 static int get_class(void);
90 static int get_version(void);
91 static int get_format(void);
92 static int process_shdr(Elf_Info *);
93 static int process_phdr(Elf_Info *);
94 static int file_xlatetom(Elf_Type, char *);
95 static int xlatetom_nhdr(Elf_Nhdr *);
96 static int get_phdr(Elf_Info *, int);
97 static int get_shdr(Elf_Info *, int);
98
99 static Elf_Ehdr EI_Ehdr; /* Elf_Ehdr to be stored */
100 static Elf_Word EI_Ehdr_shnum; /* # section headers */
101 static Elf_Word EI_Ehdr_phnum; /* # program headers */
102 static Elf_Word EI_Ehdr_shstrndx; /* Index of section hdr string table */
125 }
126
127 /*
128 * file_xlatetom: translate different headers from file
129 * representation to memory representaion.
130 */
131 #define HDRSZ 512
132 static int
133 file_xlatetom(Elf_Type type, char *hdr)
134 {
135 Elf_Data src, dst;
136 char *hbuf[HDRSZ];
137 int version, format;
138
139 version = get_version();
140 format = get_format();
141
142 /* will convert only these types */
143 if (type != ELF_T_EHDR && type != ELF_T_PHDR &&
144 type != ELF_T_SHDR && type != ELF_T_WORD &&
145 type != ELF_T_CAP && type != ELF_T_DYN)
146 return (ELF_READ_FAIL);
147
148 src.d_buf = (Elf_Void *)hdr;
149 src.d_type = type;
150 src.d_version = version;
151
152 dst.d_buf = (Elf_Void *)&hbuf;
153 dst.d_version = EV_CURRENT;
154
155 src.d_size = elf_fsize(type, 1, version);
156 dst.d_size = elf_fsize(type, 1, EV_CURRENT);
157 if (elf_xlatetom(&dst, &src, format) == NULL)
158 return (ELF_READ_FAIL);
159
160 (void) memcpy(hdr, &hbuf, dst.d_size);
161 return (ELF_READ_OKAY);
162 }
163
164 /*
165 * xlatetom_nhdr: There is no routine to convert Note header
399 free(psinfo);
400 }
401 if (phdr->p_type == PT_DYNAMIC) {
402 EI->dynamic = B_TRUE;
403 }
404 }
405 return (ELF_READ_OKAY);
406 }
407
408 /*
409 * process_shdr: Read Section Headers to attempt to get HW/SW
410 * capabilities by looking at the SUNW_cap
411 * section and set string in Elf_Info.
412 * Also look for symbol tables and debug
413 * information sections. Set the "stripped" field
414 * in Elf_Info with corresponding flags.
415 */
416 static int
417 process_shdr(Elf_Info *EI)
418 {
419 int mac;
420 int i, idx;
421 char *strtab;
422 size_t strtab_sz;
423 uint64_t j;
424 Elf_Shdr *shdr = &EI_Shdr;
425
426 mac = EI_Ehdr.e_machine;
427
428 /* if there are no sections, return success anyway */
429 if (EI_Ehdr.e_shoff == 0 && EI_Ehdr_shnum == 0)
430 return (ELF_READ_OKAY);
431
432 /* read section names from String Section */
433 if (get_shdr(EI, EI_Ehdr_shstrndx) == ELF_READ_FAIL)
434 return (ELF_READ_FAIL);
435
436 if ((strtab = malloc(shdr->sh_size)) == NULL)
437 return (ELF_READ_FAIL);
438
439 if (pread64(EI->elffd, strtab, shdr->sh_size, shdr->sh_offset)
440 != shdr->sh_size)
441 return (ELF_READ_FAIL);
442
443 strtab_sz = shdr->sh_size;
444
445 /* read all the sections and process them */
446 for (idx = 1, i = 0; i < EI_Ehdr_shnum; idx++, i++) {
447 char *shnam;
448
449 if (get_shdr(EI, i) == ELF_READ_FAIL)
450 return (ELF_READ_FAIL);
451
452 if (shdr->sh_type == SHT_NULL) {
453 idx--;
454 continue;
455 }
456
457 if (shdr->sh_type == SHT_SUNW_cap) {
458 char capstr[128];
459 Elf_Cap Chdr;
460 FILE_ELF_OFF_T cap_off;
461 FILE_ELF_SIZE_T csize;
462 uint64_t capn;
463
464 cap_off = shdr->sh_offset;
465 csize = sizeof (Elf_Cap);
466
467 if (shdr->sh_size == 0 || shdr->sh_entsize == 0) {
468 (void) fprintf(stderr, ELF_ERR_ELFCAP1,
469 File, EI->file);
470 return (ELF_READ_FAIL);
471 }
472 capn = (shdr->sh_size / shdr->sh_entsize);
473 for (j = 0; j < capn; j++) {
474 /*
475 * read cap and xlate the values
476 */
477 if ((pread64(EI->elffd, &Chdr, csize, cap_off)
478 != csize) ||
479 file_xlatetom(ELF_T_CAP, (char *)&Chdr)
480 == 0) {
481 (void) fprintf(stderr, ELF_ERR_ELFCAP2,
482 File, EI->file);
483 return (ELF_READ_FAIL);
484 }
485
486 cap_off += csize;
487
488 /*
489 * Each capatibility group is terminated with
490 * CA_SUNW_NULL. Groups other than the first
491 * represent symbol capabilities, and aren't
492 * interesting here.
493 */
494 if (Chdr.c_tag == CA_SUNW_NULL)
495 break;
496
497 (void) elfcap_tag_to_str(ELFCAP_STYLE_UC,
498 Chdr.c_tag, Chdr.c_un.c_val, capstr,
499 sizeof (capstr), ELFCAP_FMT_SNGSPACE,
500 mac);
501
502 if ((*EI->cap_str != '\0') && (*capstr != '\0'))
503 (void) strlcat(EI->cap_str, " ",
504 sizeof (EI->cap_str));
505
506 (void) strlcat(EI->cap_str, capstr,
507 sizeof (EI->cap_str));
508 }
509 } else if (shdr->sh_type == SHT_DYNAMIC) {
510 Elf_Dyn dyn;
511 FILE_ELF_SIZE_T dsize;
512 FILE_ELF_OFF_T doff;
513 uint64_t dynn;
514
515 doff = shdr->sh_offset;
516 dsize = sizeof (Elf_Dyn);
517
518 if (shdr->sh_size == 0 || shdr->sh_entsize == 0) {
519 (void) fprintf(stderr, ELF_ERR_DYNAMIC1,
520 File, EI->file);
521 return (ELF_READ_FAIL);
522 }
523
524 dynn = (shdr->sh_size / shdr->sh_entsize);
525 for (j = 0; j < dynn; j++) {
526 if (pread64(EI->elffd, &dyn, dsize, doff)
527 != dsize ||
528 file_xlatetom(ELF_T_DYN, (char *)&dyn)
529 == 0) {
530 (void) fprintf(stderr, ELF_ERR_DYNAMIC2,
531 File, EI->file);
532 return (ELF_READ_FAIL);
533 }
534
535 doff += dsize;
536
537 if ((dyn.d_tag == DT_SUNW_KMOD) &&
538 (dyn.d_un.d_val == 1)) {
539 EI->kmod = B_TRUE;
540 }
541 }
542 }
543
544 /*
545 * Definition time:
546 * - "not stripped" means that an executable file
547 * contains a Symbol Table (.symtab)
548 * - "stripped" means that an executable file
549 * does not contain a Symbol Table.
550 * When strip -l or strip -x is run, it strips the
551 * debugging information (.line section name (strip -l),
552 * .line, .debug*, .stabs*, .dwarf* section names
553 * and SHT_SUNW_DEBUGSTR and SHT_SUNW_DEBUG
554 * section types (strip -x), however the Symbol
555 * Table will still be present.
556 * Therefore, if
557 * - No Symbol Table present, then report
558 * "stripped"
559 * - Symbol Table present with debugging
560 * information (line number or debug section names,
|