diff options
| author | Joseph Koshy <jkoshy@FreeBSD.org> | 2005-10-18 05:13:27 +0000 |
|---|---|---|
| committer | Joseph Koshy <jkoshy@FreeBSD.org> | 2005-10-18 05:13:27 +0000 |
| commit | 887a8d04dc4e83e1d57ec49cfe92c9391e870f1e (patch) | |
| tree | dc596a6dfb2fc2bb13956ecdeaf8d19feefdaea4 /usr.sbin | |
| parent | 9f8adcef84f37437d7a5af5fb821ef10a3715d95 (diff) | |
Notes
Diffstat (limited to 'usr.sbin')
| -rw-r--r-- | usr.sbin/pmcstat/pmcstat_log.c | 99 |
1 files changed, 69 insertions, 30 deletions
diff --git a/usr.sbin/pmcstat/pmcstat_log.c b/usr.sbin/pmcstat/pmcstat_log.c index d4def0e29e1c..a7bb4efe5290 100644 --- a/usr.sbin/pmcstat/pmcstat_log.c +++ b/usr.sbin/pmcstat/pmcstat_log.c @@ -328,6 +328,11 @@ pmcstat_image_get_elf_params(struct pmcstat_image *image) const Elf_Ehdr *h; const Elf_Phdr *ph; const Elf_Shdr *sh; +#if defined(__amd64__) + const Elf32_Ehdr *h32; + const Elf32_Phdr *ph32; + const Elf32_Shdr *sh32; +#endif const char *path; assert(image->pi_type == PMCSTAT_IMAGE_UNKNOWN); @@ -352,47 +357,81 @@ pmcstat_image_get_elf_params(struct pmcstat_image *image) if (!IS_ELF(*h)) err(EX_SOFTWARE, "ERROR: \"%s\" not an ELF file", path); - sh = (const Elf_Shdr *)((uintptr_t) mapbase + h->e_shoff); - - if (h->e_type == ET_EXEC || h->e_type == ET_DYN) { - /* - * Some kind of executable object: find the min,max va - * for its executable sections. - */ - for (i = 0; i < h->e_shnum; i++) - if (sh[i].sh_flags & SHF_EXECINSTR) { /* code */ - minva = min(minva, sh[i].sh_addr); - maxva = max(maxva, sh[i].sh_addr + - sh[i].sh_size); - } - } else + /* we only handle executable objects */ + if (h->e_type != ET_EXEC && h->e_type != ET_DYN) err(EX_DATAERR, "ERROR: Unknown file type for \"%s\"", image->pi_internedpath); +#define GET_VA(H, SH, MINVA, MAXVA) do { \ + for (i = 0; i < (H)->e_shnum; i++) \ + if ((SH)[i].sh_flags & SHF_EXECINSTR) { \ + (MINVA) = min((MINVA),(SH)[i].sh_addr); \ + (MAXVA) = max((MAXVA),(SH)[i].sh_addr + \ + (SH)[i].sh_size); \ + } \ + } while (0) + + +#define GET_PHDR_INFO(H, PH, IMAGE) do { \ + for (i = 0; i < (H)->e_phnum; i++) { \ + switch ((PH)[i].p_type) { \ + case PT_DYNAMIC: \ + image->pi_isdynamic = 1; \ + break; \ + case PT_INTERP: \ + image->pi_dynlinkerpath = \ + pmcstat_string_intern( \ + (char *) mapbase + \ + (PH)[i].p_offset); \ + break; \ + } \ + } \ + } while (0) + image->pi_type = PMCSTAT_IMAGE_ELF; - image->pi_start = minva; - image->pi_entry = h->e_entry; - image->pi_end = maxva; image->pi_isdynamic = 0; image->pi_dynlinkerpath = NULL; + switch (h->e_machine) { + case EM_386: + case EM_486: +#if defined(__amd64__) + /* a 32 bit executable */ + h32 = (const Elf32_Ehdr *) h; + sh32 = (const Elf32_Shdr *)((uintptr_t) mapbase + h32->e_shoff); - if (h->e_type == ET_EXEC) { - ph = (const Elf_Phdr *)((uintptr_t) mapbase + h->e_phoff); - for (i = 0; i < h->e_phnum; i++) { - switch (ph[i].p_type) { - case PT_DYNAMIC: - image->pi_isdynamic = 1; - break; - case PT_INTERP: - image->pi_dynlinkerpath = - pmcstat_string_intern((char *) mapbase + - ph[i].p_offset); - break; - } + GET_VA(h32, sh32, minva, maxva); + + image->pi_entry = h32->e_entry; + + if (h32->e_type == ET_EXEC) { + ph32 = (const Elf32_Phdr *)((uintptr_t) mapbase + + h32->e_phoff); + GET_PHDR_INFO(h32, ph32, image); + } + break; +#endif + default: + sh = (const Elf_Shdr *)((uintptr_t) mapbase + h->e_shoff); + + GET_VA(h, sh, minva, maxva); + + image->pi_entry = h->e_entry; + + if (h->e_type == ET_EXEC) { + ph = (const Elf_Phdr *)((uintptr_t) mapbase + + h->e_phoff); + GET_PHDR_INFO(h, ph, image); } + break; } +#undef GET_PHDR_INFO +#undef GET_VA + + image->pi_start = minva; + image->pi_end = maxva; + if (munmap(mapbase, st.st_size) < 0) err(EX_OSERR, "ERROR: Cannot unmap \"%s\"", path); |
