Beispiel #1
0
int
findelfsecidx(Elf *elf, const char *file, const char *tofind)
{
	Elf_Scn *scn = NULL;
	GElf_Ehdr ehdr;
	GElf_Shdr shdr;

	if (gelf_getehdr(elf, &ehdr) == NULL)
		elfterminate(file, "Couldn't read ehdr");

	while ((scn = elf_nextscn(elf, scn)) != NULL) {
		char *name;

		if (gelf_getshdr(scn, &shdr) == NULL) {
			elfterminate(file,
			    "Couldn't read header for section %d",
			    elf_ndxscn(scn));
		}

		if ((name = elf_strptr(elf, ehdr.e_shstrndx,
		    (size_t)shdr.sh_name)) == NULL) {
			elfterminate(file,
			    "Couldn't get name for section %d",
			    elf_ndxscn(scn));
		}

		if (strcmp(name, tofind) == 0)
			return (elf_ndxscn(scn));
	}

	return (-1);
}
Beispiel #2
0
static int
read_archive(int fd, Elf *elf, char *file, char *label, read_cb_f *func,
    void *arg, int require_ctf)
{
	Elf *melf;
	Elf_Cmd cmd = ELF_C_READ;
	Elf_Arhdr *arh;
	int secnum = 1, found = 0;

	while ((melf = elf_begin(fd, cmd, elf)) != NULL) {
		int rc = 0;

		if ((arh = elf_getarhdr(melf)) == NULL) {
			elfterminate(file, "Can't get archive header for "
			    "member %d", secnum);
		}

		/* skip special sections - their names begin with "/" */
		if (*arh->ar_name != '/') {
			size_t memlen = strlen(file) + 1 +
			    strlen(arh->ar_name) + 1 + 1;
			char *memname = xmalloc(memlen);

			snprintf(memname, memlen, "%s(%s)", file, arh->ar_name);

			switch (elf_kind(melf)) {
			case ELF_K_AR:
				rc = read_archive(fd, melf, memname, label,
				    func, arg, require_ctf);
				break;
			case ELF_K_ELF:
				rc = read_file(melf, memname, label,
				    func, arg, require_ctf);
				break;
			default:
				terminate("%s: Unknown elf kind %d\n",
				    memname, elf_kind(melf));
			}

			free(memname);
		}

		cmd = elf_next(melf);
		(void) elf_end(melf);
		secnum++;

		if (rc < 0)
			return (rc);
		else
			found += rc;
	}

	return (found);
}
Beispiel #3
0
static int
read_file(Elf *elf, char *file, char *label, read_cb_f *func, void *arg,
    int require_ctf)
{
	Elf_Scn *ctfscn;
	Elf_Data *ctfdata = NULL;
	symit_data_t *si = NULL;
	int ctfscnidx;
	tdata_t *td;

	if ((ctfscnidx = findelfsecidx(elf, file, ".SUNW_ctf")) < 0) {
		if (require_ctf &&
		    (built_source_types(elf, file) & SOURCE_C)) {
			terminate("Input file %s was partially built from "
			    "C sources, but no CTF data was present\n", file);
		}
		return (0);
	}

	if ((ctfscn = elf_getscn(elf, ctfscnidx)) == NULL ||
	    (ctfdata = elf_getdata(ctfscn, NULL)) == NULL)
		elfterminate(file, "Cannot read CTF section");

	/* Reconstruction of type tree */
	if ((si = symit_new(elf, file)) == NULL) {
		warning("%s has no symbol table - skipping", file);
		return (0);
	}

	td = ctf_load(file, ctfdata->d_buf, ctfdata->d_size, si, label);
	tdata_build_hashes(td);

	symit_free(si);

	if (td != NULL) {
		if (func(td, file, arg) < 0)
			return (-1);
		else
			return (1);
	}
	return (0);
}
Beispiel #4
0
static int
read_ctf_common(char *file, char *label, read_cb_f *func, void *arg,
    int require_ctf)
{
	Elf *elf;
	int found = 0;
	int fd;

	debug(3, "Reading %s (label %s)\n", file, (label ? label : "NONE"));

	(void) elf_version(EV_CURRENT);

	if ((fd = open(file, O_RDONLY)) < 0)
		terminate("%s: Cannot open for reading", file);
	if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL)
		elfterminate(file, "Cannot read");

	switch (elf_kind(elf)) {
	case ELF_K_AR:
		found = read_archive(fd, elf, file, label,
		    func, arg, require_ctf);
		break;

	case ELF_K_ELF:
		found = read_file(elf, file, label,
		    func, arg, require_ctf);
		break;

	default:
		terminate("%s: Unknown elf kind %d\n", file, elf_kind(elf));
	}

	(void) elf_end(elf);
	(void) close(fd);

	return (found);
}