Пример #1
0
void list_link_after(int* first, int* next,
    int head, int node, int prev)
{
  if (prev == NULL_IDX) {
    list_link(first, next, head, node);
  } else {
    next[node] = next[prev];
    next[prev] = node;
  }
}
Пример #2
0
inline void list_insert_back(struct list_link* sent, struct list_link* n_node) {
	list_link(n_node, sent->prev, sent);
}
Пример #3
0
inline void list_insert_front(struct list_link* sent, struct list_link* n_node) {
	list_link(n_node, sent, sent->next);
}
Пример #4
0
void list_insert_after(list_t* list_pos, list_t* list_val)
{
    list_t* list_temp_after = list_pos->next;
    list_link(list_pos, list_val);
    list_link(list_val, list_temp_after);
}
Пример #5
0
struct ps_prochandle *
Pgrab_file(const char *fname, int *perr)
{
	struct ps_prochandle *P = NULL;
	char buf[PATH_MAX];
	GElf_Ehdr ehdr;
	Elf *elf = NULL;
	size_t phnum;
	file_info_t *fp = NULL;
	int fd;
	int i;

	if ((fd = open64(fname, O_RDONLY)) < 0) {
		dprintf("couldn't open file");
		*perr = (errno == ENOENT) ? G_NOEXEC : G_STRANGE;
		return (NULL);
	}

	if (elf_version(EV_CURRENT) == EV_NONE) {
		dprintf("libproc ELF version is more recent than libelf");
		*perr = G_ELF;
		goto err;
	}

	if ((P = calloc(1, sizeof (struct ps_prochandle))) == NULL) {
		*perr = G_STRANGE;
		goto err;
	}

	(void) mutex_init(&P->proc_lock, USYNC_THREAD, NULL);
	P->state = PS_IDLE;
	P->pid = (pid_t)-1;
	P->asfd = fd;
	P->ctlfd = -1;
	P->statfd = -1;
	P->agentctlfd = -1;
	P->agentstatfd = -1;
	P->info_valid = -1;
	P->ops = &P_idle_ops;
	Pinitsym(P);

	if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {
		*perr = G_ELF;
		return (NULL);
	}

	/*
	 * Construct a file_info_t that corresponds to this file.
	 */
	if ((fp = calloc(1, sizeof (file_info_t))) == NULL) {
		*perr = G_STRANGE;
		goto err;
	}

	if ((fp->file_lo = calloc(1, sizeof (rd_loadobj_t))) == NULL) {
		*perr = G_STRANGE;
		goto err;
	}

	if (*fname == '/') {
		(void) strncpy(fp->file_pname, fname, sizeof (fp->file_pname));
	} else {
		size_t sz;

		if (getcwd(fp->file_pname, sizeof (fp->file_pname) - 1) ==
		    NULL) {
			*perr = G_STRANGE;
			goto err;
		}

		sz = strlen(fp->file_pname);
		(void) snprintf(&fp->file_pname[sz],
		    sizeof (fp->file_pname) - sz, "/%s", fname);
	}

	fp->file_fd = fd;
	fp->file_lo->rl_lmident = LM_ID_BASE;
	if ((fp->file_lname = strdup(fp->file_pname)) == NULL) {
		*perr = G_STRANGE;
		goto err;
	}
	fp->file_lbase = basename(fp->file_lname);

	if ((P->execname = strdup(fp->file_pname)) == NULL) {
		*perr = G_STRANGE;
		goto err;
	}

	P->num_files++;
	list_link(fp, &P->file_head);

	if (gelf_getehdr(elf, &ehdr) == NULL) {
		*perr = G_STRANGE;
		goto err;
	}

	if (elf_getphdrnum(elf, &phnum) == -1) {
		*perr = G_STRANGE;
		goto err;
	}

	dprintf("Pgrab_file: program header count = %lu\n", (ulong_t)phnum);

	/*
	 * Sift through the program headers making the relevant maps.
	 */
	for (i = 0; i < phnum; i++) {
		GElf_Phdr phdr, *php;

		if ((php = gelf_getphdr(elf, i, &phdr)) == NULL) {
			*perr = G_STRANGE;
			goto err;
		}

		if (php->p_type != PT_LOAD)
			continue;

		if (idle_add_mapping(P, php, fp) != 0) {
			*perr = G_STRANGE;
			goto err;
		}
	}
	Psort_mappings(P);

	(void) elf_end(elf);

	P->map_exec = fp->file_map;

	P->status.pr_flags = PR_STOPPED;
	P->status.pr_nlwp = 0;
	P->status.pr_pid = (pid_t)-1;
	P->status.pr_ppid = (pid_t)-1;
	P->status.pr_pgid = (pid_t)-1;
	P->status.pr_sid = (pid_t)-1;
	P->status.pr_taskid = (taskid_t)-1;
	P->status.pr_projid = (projid_t)-1;
	P->status.pr_zoneid = (zoneid_t)-1;
	switch (ehdr.e_ident[EI_CLASS]) {
	case ELFCLASS32:
		P->status.pr_dmodel = PR_MODEL_ILP32;
		break;
	case ELFCLASS64:
		P->status.pr_dmodel = PR_MODEL_LP64;
		break;
	default:
		*perr = G_FORMAT;
		goto err;
	}

	/*
	 * Pfindobj() checks what zone a process is associated with, so
	 * we call it after initializing pr_zoneid to -1.  This ensures
	 * we don't get associated with any zone on the system.
	 */
	if (Pfindobj(P, fp->file_lname, buf, sizeof (buf)) != NULL) {
		free(P->execname);
		P->execname = strdup(buf);
		if ((fp->file_rname = strdup(buf)) != NULL)
			fp->file_rbase = basename(fp->file_rname);
	}

	/*
	 * The file and map lists are complete, and will never need to be
	 * adjusted.
	 */
	P->info_valid = 1;

	return (P);
err:
	(void) close(fd);
	if (P != NULL)
		Pfree(P);
	if (elf != NULL)
		(void) elf_end(elf);
	return (NULL);
}