Ejemplo n.º 1
0
int
dump_dynamic(Elf *elf)
{
	Elf32_Dyn	* dyn;
	Elf32_Phdr	* phdr;
	Elf32_Ehdr	* ehdr;
	char		* raw;
	int		  i;

	if ((phdr = elf32_getphdr(elf)) == NULL) {
		fprintf(stderr, "phdr == NULL");
		return (2);
	}

	if ((raw = elf_rawfile(elf, NULL)) == NULL) {
		fprintf(stderr, "raw == NULL");
		return (2);
	}

	for (;phdr->p_type != PT_DYNAMIC; phdr++)
		;

	dyn = (Elf32_Dyn *)(raw + phdr->p_offset);

	i = 0;
	while (dyn->d_tag != DT_NULL) {
		printf("[%d] ", i);

		if (dyn->d_tag < DT_NUM) 
			printf(" %s ", elf_dyn[dyn->d_tag]);
		else if (dyn->d_tag >= DT_LOPROC &&
				dyn->d_tag <= DT_LOPROC + DT_PROCNUM)
			printf(" LOPROC ");
		else if ((Elf32_Word)DT_VERSIONTAGIDX(dyn->d_tag) <
				DT_VERSIONTAGNUM)
			printf(" DT_VERSIONTAGNUM ");
		else if ((Elf32_Word)DT_EXTRATAGIDX(dyn->d_tag) < 
				DT_EXTRANUM)
			printf(" DT_EXTRANUM ");
		else
			printf(" b0rken ");

		printf("(%#x)\n", i * sizeof(Elf32_Dyn));

		dyn++;
		i++;
	}

	return 0;
}
Ejemplo n.º 2
0
static void processProgHeaders(elfInfo *ei, GElf_Ehdr *ehdr)
{
    for (size_t i = 0; i < ehdr->e_phnum; i++) {
	GElf_Phdr mem;
	GElf_Phdr *phdr = gelf_getphdr(ei->elf, i, &mem);

	if (phdr && phdr->p_type == PT_INTERP) {
	    size_t maxsize;
	    char * filedata = elf_rawfile(ei->elf, &maxsize);

	    if (filedata && phdr->p_offset < maxsize) {
		ei->interp = rstrdup(filedata + phdr->p_offset);
		break;
	    }
	}
    }
}
Ejemplo n.º 3
0
/*
 * Parse individual note entries inside a PT_NOTE segment.
 */
static void
handle_core_note(Elf *elf, GElf_Ehdr *elfhdr, GElf_Phdr *phdr,
    char **cmd_line)
{
	size_t max_size;
	uint64_t raw_size;
	GElf_Off offset;
	static pid_t pid;
	uintptr_t ver;
	Elf32_Nhdr *nhdr, nhdr_l;
	static int reg_pseudo = 0, reg2_pseudo = 0 /*, regxfp_pseudo = 0*/;
	char buf[BUF_SIZE], *data, *name;

 	if (elf == NULL || elfhdr == NULL || phdr == NULL)
		return;

	data = elf_rawfile(elf, &max_size);
	offset = phdr->p_offset;
	while (data != NULL && offset < phdr->p_offset + phdr->p_filesz) {
		nhdr = (Elf32_Nhdr *)(uintptr_t)((char*)data + offset);
		memset(&nhdr_l, 0, sizeof(Elf32_Nhdr));
		if (!xlatetom(elf, elfhdr, &nhdr->n_type, &nhdr_l.n_type,
			ELF_T_WORD, sizeof(Elf32_Word)) ||
		    !xlatetom(elf, elfhdr, &nhdr->n_descsz, &nhdr_l.n_descsz,
			ELF_T_WORD, sizeof(Elf32_Word)) ||
		    !xlatetom(elf, elfhdr, &nhdr->n_namesz, &nhdr_l.n_namesz,
			ELF_T_WORD, sizeof(Elf32_Word)))
			break;

		name = (char *)((char *)nhdr + sizeof(Elf32_Nhdr));
		switch (nhdr_l.n_type) {
		case NT_PRSTATUS: {
			raw_size = 0;
			if (elfhdr->e_ident[EI_OSABI] == ELFOSABI_FREEBSD &&
			    nhdr_l.n_namesz == 0x8 &&
			    !strcmp(name,"FreeBSD")) {
				if (elfhdr->e_ident[EI_CLASS] == ELFCLASS32) {
					raw_size = (uint64_t)*((uint32_t *)
					    (uintptr_t)(name +
						ELF_ALIGN((int32_t)
						nhdr_l.n_namesz, 4) + 8));
					ver = (uintptr_t)NOTE_OFFSET_32(nhdr,
					    nhdr_l.n_namesz,0);
					if (*((int *)ver) == 1)
						pid = PID32(nhdr,
						    nhdr_l.n_namesz, 24);
				} else {
					raw_size = *((uint64_t *)(uintptr_t)
					    (name + ELF_ALIGN((int32_t)
						nhdr_l.n_namesz, 8) + 16));
					ver = (uintptr_t)NOTE_OFFSET_64(nhdr,
					    nhdr_l.n_namesz,0);
					if (*((int *)ver) == 1)
						pid = PID64(nhdr,
						    nhdr_l.n_namesz, 40);
				}
				xlatetom(elf, elfhdr, &raw_size, &raw_size,
				    ELF_T_WORD, sizeof(uint64_t));
				xlatetom(elf, elfhdr, &pid, &pid, ELF_T_WORD,
				    sizeof(pid_t));
			}

			if (raw_size != 0 && style == STYLE_SYSV) {
				(void) snprintf(buf, BUF_SIZE, "%s/%d",
				    ".reg", pid);
				tbl_append();
				tbl_print(buf, 0);
				tbl_print_num(raw_size, radix, 1);
				tbl_print_num(0, radix, 2);
				if (!reg_pseudo) {
					tbl_append();
					tbl_print(".reg", 0);
					tbl_print_num(raw_size, radix, 1);
					tbl_print_num(0, radix, 2);
					reg_pseudo = 1;
					text_size_total += raw_size;
				}
				text_size_total += raw_size;
			}
		}
		break;
		case NT_FPREGSET:	/* same as NT_PRFPREG */
			if (style == STYLE_SYSV) {
				(void) snprintf(buf, BUF_SIZE,
				    "%s/%d", ".reg2", pid);
				tbl_append();
				tbl_print(buf, 0);
				tbl_print_num(nhdr_l.n_descsz, radix, 1);
				tbl_print_num(0, radix, 2);
				if (!reg2_pseudo) {
					tbl_append();
					tbl_print(".reg2", 0);
					tbl_print_num(nhdr_l.n_descsz, radix,
					    1);
					tbl_print_num(0, radix, 2);
					reg2_pseudo = 1;
					text_size_total += nhdr_l.n_descsz;
				}
				text_size_total += nhdr_l.n_descsz;
			}
			break;
#if 0
		case NT_AUXV:
			if (style == STYLE_SYSV) {
				tbl_append();
				tbl_print(".auxv", 0);
				tbl_print_num(nhdr_l.n_descsz, radix, 1);
				tbl_print_num(0, radix, 2);
				text_size_total += nhdr_l.n_descsz;
			}
			break;
		case NT_PRXFPREG:
			if (style == STYLE_SYSV) {
				(void) snprintf(buf, BUF_SIZE, "%s/%d",
				    ".reg-xfp", pid);
				tbl_append();
				tbl_print(buf, 0);
				tbl_print_num(nhdr_l.n_descsz, radix, 1);
				tbl_print_num(0, radix, 2);
				if (!regxfp_pseudo) {
					tbl_append();
					tbl_print(".reg-xfp", 0);
					tbl_print_num(nhdr_l.n_descsz, radix,
					    1);
					tbl_print_num(0, radix, 2);
					regxfp_pseudo = 1;
					text_size_total += nhdr_l.n_descsz;
				}
				text_size_total += nhdr_l.n_descsz;
			}
			break;
		case NT_PSINFO:
#endif
		case NT_PRPSINFO: {
			/* FreeBSD 64-bit */
			if (nhdr_l.n_descsz == 0x78 &&
				!strcmp(name,"FreeBSD")) {
				*cmd_line = strdup(NOTE_OFFSET_64(nhdr,
				    nhdr_l.n_namesz, 33));
			/* FreeBSD 32-bit */
			} else if (nhdr_l.n_descsz == 0x6c &&
				!strcmp(name,"FreeBSD")) {
				*cmd_line = strdup(NOTE_OFFSET_32(nhdr,
				    nhdr_l.n_namesz, 25));
			}
			/* Strip any trailing spaces */
			if (*cmd_line != NULL) {
				char *s;

				s = *cmd_line + strlen(*cmd_line);
				while (s > *cmd_line) {
					if (*(s-1) != 0x20) break;
					s--;
				}
				*s = 0;
			}
			break;
		}
#if 0
		case NT_PSTATUS:
		case NT_LWPSTATUS:
#endif
		default:
			break;
		}
		NEXT_NOTE(elfhdr, nhdr_l.n_descsz, nhdr_l.n_namesz, offset);
	}
}
Ejemplo n.º 4
0
int
main (int argc, char *argv[])
{
  Elf *elf;
  int fd;
  GElf_Ehdr ehdr;
  int cnt;

  fd = open (argv[1], O_RDONLY);
  if (fd == -1)
    {
      printf ("cannot open \"%s\": %s\n", argv[1], strerror (errno));
      exit (1);
    }

  elf_version (EV_CURRENT);

  elf = elf_begin (fd, ELF_C_READ, NULL);
  if (elf == NULL)
    {
      printf ("cannot open ELF file: %s\n", elf_errmsg (-1));
      exit (1);
    }

  if (elf_kind (elf) != ELF_K_ELF)
    {
      printf ("\"%s\" is not an ELF file\n", argv[1]);
      exit (1);
    }

  if (gelf_getehdr (elf, &ehdr) == NULL)
    {
      printf ("cannot get the ELF header: %s\n", elf_errmsg (-1));
      exit (1);
    }

  printf ("idx type    %*s %*s %*s %*s %*s  align flags\n",
	  gelf_getclass (elf) == ELFCLASS32 ? 9 : 17, "offset",
	  gelf_getclass (elf) == ELFCLASS32 ? 10 : 18, "vaddr",
	  gelf_getclass (elf) == ELFCLASS32 ? 10 : 18, "paddr",
	  gelf_getclass (elf) == ELFCLASS32 ? 9 : 12, "filesz",
	  gelf_getclass (elf) == ELFCLASS32 ? 9 : 12, "memsz");

  for (cnt = 0; cnt < ehdr.e_phnum; ++cnt)
    {
      static const char *typenames[] =
      {
	[PT_NULL] = "NULL",
	[PT_LOAD] = "LOAD",
	[PT_DYNAMIC] = "DYNAMIC",
	[PT_INTERP] = "INTERP",
	[PT_NOTE] = "NOTE",
	[PT_SHLIB] = "SHLIB",
	[PT_PHDR] = "PHDR"
      };
      GElf_Phdr mem;
      GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &mem);
      char buf[19];
      const char *p_type = typenames[phdr->p_type];

      /* If we don't know the name of the type we use the number value.  */
      if (phdr->p_type >= PT_NUM)
	{
	  snprintf (buf, sizeof (buf), "%x", phdr->p_type);
	  p_type = buf;
	}

      printf ("%3d %-7s %#0*llx %#0*llx %#0*llx %#0*llx %#0*llx %#6llx ",
	      cnt, p_type,
	      gelf_getclass (elf) == ELFCLASS32 ? 9 : 17,
	      (unsigned long long int) phdr->p_offset,
	      gelf_getclass (elf) == ELFCLASS32 ? 10 : 18,
	      (unsigned long long int) phdr->p_vaddr,
	      gelf_getclass (elf) == ELFCLASS32 ? 10 : 18,
	      (unsigned long long int) phdr->p_paddr,
	      gelf_getclass (elf) == ELFCLASS32 ? 9 : 12,
	      (unsigned long long int) phdr->p_filesz,
	      gelf_getclass (elf) == ELFCLASS32 ? 9 : 12,
	      (unsigned long long int) phdr->p_memsz,
	      (unsigned long long int) phdr->p_align);

      putc_unlocked ((phdr->p_flags & PF_X) ? 'X' : ' ', stdout);
      putc_unlocked ((phdr->p_flags & PF_W) ? 'W' : ' ', stdout);
      putc_unlocked ((phdr->p_flags & PF_R) ? 'R' : ' ', stdout);

      putc_unlocked ('\n', stdout);

      if (phdr->p_type == PT_INTERP)
	{
	  /* We can show the user the name of the interpreter.  */
	  size_t maxsize;
	  char *filedata = elf_rawfile (elf, &maxsize);

	  if (filedata != NULL && phdr->p_offset < maxsize)
	    printf ("\t[Requesting program interpreter: %s]\n",
		    filedata + phdr->p_offset);
	}
    }

  if (elf_end (elf) != 0)
    {
      printf ("error while freeing ELF descriptor: %s\n", elf_errmsg (-1));
      exit (1);
    }

  return 0;
}
Ejemplo n.º 5
0
static const uint8_t *
parse_eh_frame_hdr (const uint8_t *hdr, size_t hdr_size, GElf_Addr hdr_vaddr,
		    const GElf_Ehdr *ehdr, GElf_Addr *eh_frame_vaddr,
		    size_t *table_entries, uint8_t *table_encoding)
{
  const uint8_t *h = hdr;

  if (*h++ != 1)		/* version */
    return (void *) -1l;

  uint8_t eh_frame_ptr_encoding = *h++;
  uint8_t fde_count_encoding = *h++;
  uint8_t fde_table_encoding = *h++;

  if (eh_frame_ptr_encoding == DW_EH_PE_omit)
    return (void *) -1l;

  /* Dummy used by read_encoded_value.  */
  Elf_Data_Scn dummy_cfi_hdr_data =
    {
      .d = { .d_buf = (void *) hdr, .d_size = hdr_size }
    };
  Dwarf_CFI dummy_cfi =
    {
      .e_ident = ehdr->e_ident,
      .datarel = hdr_vaddr,
      .frame_vaddr = hdr_vaddr,
      .data = &dummy_cfi_hdr_data,
    };

  if (unlikely (read_encoded_value (&dummy_cfi, eh_frame_ptr_encoding, &h,
				    eh_frame_vaddr)))
    return (void *) -1l;

  if (fde_count_encoding != DW_EH_PE_omit)
    {
      Dwarf_Word fde_count;
      if (unlikely (read_encoded_value (&dummy_cfi, fde_count_encoding, &h,
					&fde_count)))
	return (void *) -1l;
      if (fde_count != 0 && (size_t) fde_count == fde_count
	  && fde_table_encoding != DW_EH_PE_omit
	  && (fde_table_encoding &~ DW_EH_PE_signed) != DW_EH_PE_uleb128)
	{
	  *table_entries = fde_count;
	  *table_encoding = fde_table_encoding;
	  return h;
	}
    }

  return NULL;
}

static Dwarf_CFI *
getcfi_gnu_eh_frame (Elf *elf, const GElf_Ehdr *ehdr, const GElf_Phdr *phdr)
{
  if (unlikely (phdr->p_filesz < 4))
    goto invalid;

  Elf_Data *data = elf_getdata_rawchunk (elf, phdr->p_offset, phdr->p_filesz,
					 ELF_T_BYTE);
  if (data == NULL)
    {
    invalid_hdr:
    invalid:
      /* XXX might be read error or corrupt phdr */
      __libdw_seterrno (DWARF_E_INVALID_CFI);
      return NULL;
    }

  Dwarf_Addr eh_frame_ptr;
  size_t search_table_entries;
  uint8_t search_table_encoding;
  const uint8_t *search_table = parse_eh_frame_hdr (data->d_buf, phdr->p_filesz,
						    phdr->p_vaddr, ehdr,
						    &eh_frame_ptr,
						    &search_table_entries,
						    &search_table_encoding);
  if (search_table == (void *) -1l)
    goto invalid_hdr;

  Dwarf_Off eh_frame_offset = eh_frame_ptr - phdr->p_vaddr + phdr->p_offset;
  Dwarf_Word eh_frame_size = 0;

  /* XXX we have no way without section headers to know the size
     of the .eh_frame data.  Calculate the largest it might possibly be.
     This won't be wasteful if the file is already mmap'd, but if it isn't
     it might be quite excessive.  */
  size_t filesize;
  if (elf_rawfile (elf, &filesize) != NULL)
    eh_frame_size = filesize - eh_frame_offset;

  data = elf_getdata_rawchunk (elf, eh_frame_offset, eh_frame_size, ELF_T_BYTE);
  if (data == NULL)
    {
      __libdw_seterrno (DWARF_E_INVALID_ELF); /* XXX might be read error */
      return NULL;
    }
  Dwarf_CFI *cfi = allocate_cfi (elf, eh_frame_ptr);
  if (cfi != NULL)
    {
      cfi->data = (Elf_Data_Scn *) data;

      if (search_table != NULL)
	{
	  cfi->search_table = search_table;
	  cfi->search_table_vaddr = phdr->p_vaddr;
	  cfi->search_table_encoding = search_table_encoding;
	  cfi->search_table_entries = search_table_entries;
	}
    }
  return cfi;
}

/* Search the phdrs for PT_GNU_EH_FRAME.  */
static Dwarf_CFI *
getcfi_phdr (Elf *elf, const GElf_Ehdr *ehdr)
{
  size_t phnum;
  if (unlikely (elf_getphdrnum (elf, &phnum) != 0))
    return NULL;

  for (size_t i = 0; i < phnum; ++i)
    {
      GElf_Phdr phdr_mem;
      GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem);
      if (unlikely (phdr == NULL))
	return NULL;
      if (phdr->p_type == PT_GNU_EH_FRAME)
	return getcfi_gnu_eh_frame (elf, ehdr, phdr);
    }

  __libdw_seterrno (DWARF_E_NO_DWARF);
  return NULL;
}
Ejemplo n.º 6
0
static int
dump_requires(char *filename, int fd)
{
	elf_version(EV_CURRENT);

	Elf *elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
	if (!elf) {
		fprintf(stderr, "Could not read \"%s\": %s\n", filename,
			elf_errmsg(elf_errno()));
		return -1;
	}

	size_t shstrndx = -1;
	int rc = elf_getshdrstrndx(elf, &shstrndx);

	int scn_no = 0;
	Elf_Scn *scn = NULL;
	do {
		scn = elf_getscn(elf, ++scn_no);
		if (!scn)
			break;

		int rc;

		GElf_Shdr *shdrp, shdr;
		shdrp = gelf_getshdr(scn, &shdr);

		if (!shdrp) {
			fprintf(stderr, "Malformed ELF file \"%s\": %s\n",
				filename, elf_errmsg(elf_errno()));
			elf_end(elf);
			return -1;
		}

		char *name = elf_strptr(elf, shstrndx, shdr.sh_name);
		if (!strcmp(name, ".plugin.filenames")) {
			Elf_Data *datap;

			datap = elf_rawdata(scn, NULL);
			if (!datap) {
				fprintf(stderr, "ELF Error: %s\n",
					elf_errmsg(elf_errno()));
				elf_end(elf);
				return -1;
			}

			size_t fsize;

			char *rawfile = elf_rawfile(elf, &fsize);

			char *scndata = rawfile + shdr.sh_offset + datap->d_off;

			plugin_callback_fn cb;
			rc = get_callback_function(filename, &cb);
			if (rc < 0) {
				fprintf(stderr, "could not get callback\n");
				elf_end(elf);
				return rc;
			}

			rc = cb(filename, scndata, datap->d_size);
			elf_end(elf);
			return rc;
		}
	} while (scn != NULL);
}
Ejemplo n.º 7
0
void
pmcstat_image_get_elf_params(struct pmcstat_image *image,
    struct pmcstat_args *args)
{
	int fd;
	size_t i, nph, nsh;
	const char *path, *elfbase;
	char *p, *endp;
	uintfptr_t minva, maxva;
	Elf *e;
	Elf_Scn *scn;
	GElf_Ehdr eh;
	GElf_Phdr ph;
	GElf_Shdr sh;
	enum pmcstat_image_type image_type;
	char buffer[PATH_MAX];

	assert(image->pi_type == PMCSTAT_IMAGE_UNKNOWN);

	image->pi_start = minva = ~(uintfptr_t) 0;
	image->pi_end = maxva = (uintfptr_t) 0;
	image->pi_type = image_type = PMCSTAT_IMAGE_INDETERMINABLE;
	image->pi_isdynamic = 0;
	image->pi_dynlinkerpath = NULL;
	image->pi_vaddr = 0;

	path = pmcstat_string_unintern(image->pi_execpath);
	assert(path != NULL);

	/*
	 * Look for kernel modules under FSROOT/KERNELPATH/NAME,
	 * and user mode executable objects under FSROOT/PATHNAME.
	 */
	if (image->pi_iskernelmodule)
		(void) snprintf(buffer, sizeof(buffer), "%s%s/%s",
		    args->pa_fsroot, args->pa_kernel, path);
	else
		(void) snprintf(buffer, sizeof(buffer), "%s%s",
		    args->pa_fsroot, path);

	e = NULL;
	if ((fd = open(buffer, O_RDONLY, 0)) < 0) {
		warnx("WARNING: Cannot open \"%s\".",
		    buffer);
		goto done;
	}

	if (elf_version(EV_CURRENT) == EV_NONE) {
		warnx("WARNING: failed to init elf\n");
		goto done;
	}

	if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
		warnx("WARNING: Cannot read \"%s\".",
		    buffer);
		goto done;
	}

	if (elf_kind(e) != ELF_K_ELF) {
		if (args->pa_verbosity >= 2)
			warnx("WARNING: Cannot determine the type of \"%s\".",
			    buffer);
		goto done;
	}

	if (gelf_getehdr(e, &eh) != &eh) {
		warnx(
		    "WARNING: Cannot retrieve the ELF Header for \"%s\": %s.",
		    buffer, elf_errmsg(-1));
		goto done;
	}

	if (eh.e_type != ET_EXEC && eh.e_type != ET_DYN &&
	    !(image->pi_iskernelmodule && eh.e_type == ET_REL)) {
		warnx("WARNING: \"%s\" is of an unsupported ELF type.",
		    buffer);
		goto done;
	}

	image_type = eh.e_ident[EI_CLASS] == ELFCLASS32 ?
	    PMCSTAT_IMAGE_ELF32 : PMCSTAT_IMAGE_ELF64;

	/*
	 * Determine the virtual address where an executable would be
	 * loaded.  Additionally, for dynamically linked executables,
	 * save the pathname to the runtime linker.
	 */
	if (eh.e_type == ET_EXEC) {
		if (elf_getphnum(e, &nph) == 0) {
			warnx(
"WARNING: Could not determine the number of program headers in \"%s\": %s.",
			    buffer,
			    elf_errmsg(-1));
			goto done;
		}
		for (i = 0; i < eh.e_phnum; i++) {
			if (gelf_getphdr(e, i, &ph) != &ph) {
				warnx(
"WARNING: Retrieval of PHDR entry #%ju in \"%s\" failed: %s.",
				    (uintmax_t) i, buffer, elf_errmsg(-1));
				goto done;
			}
			switch (ph.p_type) {
			case PT_DYNAMIC:
				image->pi_isdynamic = 1;
				break;
			case PT_INTERP:
				if ((elfbase = elf_rawfile(e, NULL)) == NULL) {
					warnx(
"WARNING: Cannot retrieve the interpreter for \"%s\": %s.",
					    buffer, elf_errmsg(-1));
					goto done;
				}
				image->pi_dynlinkerpath =
				    pmcstat_string_intern(elfbase +
				        ph.p_offset);
				break;
			case PT_LOAD:
				if ((ph.p_flags & PF_X) != 0 &&
				    (ph.p_offset & (-ph.p_align)) == 0)
					image->pi_vaddr = ph.p_vaddr & (-ph.p_align);
				break;
			}
		}
	}

	/*
	 * Get the min and max VA associated with this ELF object.
	 */
	if (elf_getshnum(e, &nsh) == 0) {
		warnx(
"WARNING: Could not determine the number of sections for \"%s\": %s.",
		    buffer, elf_errmsg(-1));
		goto done;
	}

	for (i = 0; i < nsh; i++) {
		if ((scn = elf_getscn(e, i)) == NULL ||
		    gelf_getshdr(scn, &sh) != &sh) {
			warnx(
"WARNING: Could not retrieve section header #%ju in \"%s\": %s.",
			    (uintmax_t) i, buffer, elf_errmsg(-1));
			goto done;
		}
		if (sh.sh_flags & SHF_EXECINSTR) {
			minva = min(minva, sh.sh_addr);
			maxva = max(maxva, sh.sh_addr + sh.sh_size);
		}
		if (sh.sh_type == SHT_SYMTAB || sh.sh_type == SHT_DYNSYM)
			pmcstat_image_add_symbols(image, e, scn, &sh);
	}

	image->pi_start = minva;
	image->pi_end   = maxva;
	image->pi_type  = image_type;
	image->pi_fullpath = pmcstat_string_intern(buffer);

	/* Build display name
	 */
	endp = buffer;
	for (p = buffer; *p; p++)
		if (*p == '/')
			endp = p+1;
	image->pi_name = pmcstat_string_intern(endp);

 done:
	(void) elf_end(e);
	if (fd >= 0)
		(void) close(fd);
	return;
}
Ejemplo n.º 8
0
void
main(int argc, char ** argv)
{
#if !defined(__osf__)
  Elf32_Ehdr *   ehdr;
  Elf32_Phdr *   phdr;
  Elf *          elf;
  Elf *          elf2;
  int       fd,fd2;
  int exf = 0;
  int i;
  size_t flen = 0;
  size_t flen2 = 0;
  time_t t;

  if (of == NULL) {
    of = stdout;
  }

  time(&t);

  if (argc != 4) {
    fprintf(of,"Core analysis %s needs three arguments: executable, core file, dest file\n",
	    reldate);
    exit(1);
  }
  
  ofname = argv[3];
  of = fopen(ofname,"a");
  
  fprintf(of,"Core analysis %s. Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.\nCopyright (C) 2005 Red Hat, Inc.\nAll rights reserved.\nCurrently %sOpening %s %s\n",reldate,ctime(&t),argv[1],argv[2]);

  if ((fd2 = open(argv[1], O_RDONLY)) == -1) {
    perror(argv[1]);
    exit(1);
  }
  (void) elf_version(EV_CURRENT);  
  /* Obtain the ELF descriptor */
  if ((elf2 = elf_begin(fd2, ELF_C_READ, NULL)) == NULL)
    failure("beginining");

  if ((erf2 = elf_rawfile(elf2,&flen2)) == NULL) {
    failure("elf_rawfile");
  }

  /* Obtain the .shstrtab data buffer */
  if ((ehdr = elf32_getehdr(elf2)) == NULL) {
    failure("reading header");
  }
  
  if (ehdr->e_type == ET_CORE) {
    fprintf(of,"Executable file should be given as the first argument.\n");
    exit(1);
  }
  
  if (ehdr->e_machine == EM_SPARC ||
      ehdr->e_machine == EM_SPARC32PLUS ||
      ehdr->e_machine == EM_SPARCV9) {
    fprintf(of,"architecture is SPARC\n");
    exf = EM_SPARC;
  } else if (ehdr->e_machine == EM_386) {
    fprintf(of,"architecture is x86\n");
    exf = ehdr->e_machine;
  } else {
    fprintf(of,"unknown architecture %d\n",ehdr->e_machine);
    exit(1);
  }
  

  if (ehdr->e_phnum == 0) {
    fprintf(of,"no program header in program file\n");
    exit(1);
  }

  load_segments(elf2,ehdr->e_phnum,erf2,flen2,0);

  /* Open the input file */
  if ((fd = open(argv[2], O_RDONLY)) == -1) {
    perror(argv[2]);
    exit(1);
  }
  
  /* Obtain the ELF descriptor */
  if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL)
    failure("beginining");

  if ((erf = elf_rawfile(elf,&flen)) == NULL) {
    failure("elf_rawfile");
  }

  /* Obtain the .shstrtab data buffer */
  if ((ehdr = elf32_getehdr(elf)) == NULL) {
    failure("reading header");
  }
  
  if (ehdr->e_type != ET_CORE) {
    fprintf(of,"second argument is ELF but not a core file\n");
    exit(1);
  }
  
  if (ehdr->e_machine != exf) {
    fprintf(of,"Architecture mismatch between executable and core file.\n");
    exit(1);
  }
  
  if (ehdr->e_phnum == 0) {
    fprintf(of,"no program header in core file\n");
    exit(1);
  }
  
  load_segments(elf,ehdr->e_phnum,erf,flen,1);
  

#ifdef notanymore
  fprintf(of,"Seeking debug information in core file.\n");

  phdr = elf32_getphdr(elf);
  
  for (i = 0; i < ehdr->e_phnum; i++) {
    if (phdr[i].p_type == PT_LOAD) {
      
      if (phdr[i].p_offset && phdr[i].p_filesz) {
	if (phdr[i].p_offset + phdr[i].p_filesz > flen) {
	  continue;
	}
	if (seek_debug(erf,phdr[i].p_offset,phdr[i].p_filesz)) {
	  break;
	}
      }
      
    }
  }
#endif

  if (of != stdout) {
    fclose(of);
  }

  try_adb(argv[1],argv[2]);

#endif  
}