proc.c revision ea8eb9a606096fd072abe104b4239f67883ad39a
1750ca8c13f402a40b01802dcb5c88e092ff68125Petr Machata#define _GNU_SOURCE /* For getline.  */
2d44c6b8b090b8b7aa9d971d9e0bfd848732a3071Juan Cespedes#include "config.h"
3d44c6b8b090b8b7aa9d971d9e0bfd848732a3071Juan Cespedes
41fe93d5b55ad2b8d4009a63e343db19cc1f21bb0Juan Cespedes#include <sys/types.h>
59a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata#include <sys/stat.h>
69a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata#include <fcntl.h>
7bfb26c745705a839f1ef5fc45e1b32135b9bc3e7Zachary T Welch#include <inttypes.h>
847cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato#include <link.h>
91fe93d5b55ad2b8d4009a63e343db19cc1f21bb0Juan Cespedes#include <stdio.h>
101fe93d5b55ad2b8d4009a63e343db19cc1f21bb0Juan Cespedes#include <string.h>
111fe93d5b55ad2b8d4009a63e343db19cc1f21bb0Juan Cespedes#include <signal.h>
12273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes#include <unistd.h>
139a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata#include <dirent.h>
149a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata#include <ctype.h>
159a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata#include <errno.h>
169a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata#include <sys/syscall.h>
17750ca8c13f402a40b01802dcb5c88e092ff68125Petr Machata#include <error.h>
189a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
19a611fc8f887c099b04cb764f477b9289a4c21d6ePetr Machata#include "common.h"
209294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machata#include "breakpoint.h"
21366c2f46d844f040458df9b7e35fc3b8527ed2d3Petr Machata#include "proc.h"
222b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata#include "library.h"
23273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes
24273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes/* /proc/pid doesn't exist just after the fork, and sometimes `ltrace'
25273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes * couldn't open it to find the executable.  So it may be necessary to
26273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes * have a bit delay
27273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes */
28273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes
292d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand#define	MAX_DELAY	100000	/* 100000 microseconds = 0.1 seconds */
301fe93d5b55ad2b8d4009a63e343db19cc1f21bb0Juan Cespedes
319a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata#define PROC_PID_FILE(VAR, FORMAT, PID)		\
329a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	char VAR[strlen(FORMAT) + 6];		\
339a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	sprintf(VAR, FORMAT, PID)
349a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
351fe93d5b55ad2b8d4009a63e343db19cc1f21bb0Juan Cespedes/*
36e0660df7f943cc832694db3b8b6778c0ff65860dJuan Cespedes * Returns a (malloc'd) file name corresponding to a running pid
371fe93d5b55ad2b8d4009a63e343db19cc1f21bb0Juan Cespedes */
38f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedeschar *
39f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedespid2name(pid_t pid) {
401fe93d5b55ad2b8d4009a63e343db19cc1f21bb0Juan Cespedes	if (!kill(pid, 0)) {
412d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand		int delay = 0;
42273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes
439a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		PROC_PID_FILE(proc_exe, "/proc/%d/exe", pid);
44273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes
452d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand		while (delay < MAX_DELAY) {
46273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes			if (!access(proc_exe, F_OK)) {
47273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes				return strdup(proc_exe);
48273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes			}
49273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes			delay += 1000;	/* 1 milisecond */
50273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes		}
511fe93d5b55ad2b8d4009a63e343db19cc1f21bb0Juan Cespedes	}
52273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes	return NULL;
531fe93d5b55ad2b8d4009a63e343db19cc1f21bb0Juan Cespedes}
5447cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato
559a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machatastatic FILE *
569a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataopen_status_file(pid_t pid)
579a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
589a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	PROC_PID_FILE(fn, "/proc/%d/status", pid);
599a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	/* Don't complain if we fail.  This would typically happen
609a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	   when the process is about to terminate, and these files are
619a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	   not available anymore.  This function is called from the
629a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	   event loop, and we don't want to clutter the output just
639a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	   because the process terminates.  */
649a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	return fopen(fn, "r");
659a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
669a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
679a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machatastatic char *
689a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machatafind_line_starting(FILE * file, const char * prefix, size_t len)
699a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
709a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	char * line = NULL;
719a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	size_t line_len = 0;
729a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	while (!feof(file)) {
739a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		if (getline(&line, &line_len, file) < 0)
749a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			return NULL;
759a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		if (strncmp(line, prefix, len) == 0)
769a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			return line;
779a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	}
789a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	return NULL;
799a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
809a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
819a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machatastatic void
822b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machataeach_line_starting(FILE *file, const char *prefix,
832b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		   enum callback_status (*cb)(const char *line,
842b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata					      const char *prefix,
852b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata					      void *data),
862b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		   void *data)
879a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
889a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	size_t len = strlen(prefix);
899a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	char * line;
909a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	while ((line = find_line_starting(file, prefix, len)) != NULL) {
912b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		enum callback_status st = (*cb)(line, prefix, data);
929a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		free (line);
932b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		if (st == CBS_STOP)
949a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			return;
959a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	}
969a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
979a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
982b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machatastatic enum callback_status
992b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machataprocess_leader_cb(const char *line, const char *prefix, void *data)
1009a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
1019a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	pid_t * pidp = data;
1029a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	*pidp = atoi(line + strlen(prefix));
1032b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	return CBS_STOP;
1049a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
1059a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
1069a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machatapid_t
1079a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataprocess_leader(pid_t pid)
1089a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
1091974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata	pid_t tgid = 0;
1109a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	FILE * file = open_status_file(pid);
1119a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	if (file != NULL) {
1129a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		each_line_starting(file, "Tgid:\t", &process_leader_cb, &tgid);
1139a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		fclose(file);
1149a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	}
1159a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
1169a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	return tgid;
1179a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
1189a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
1192b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machatastatic enum callback_status
1202b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machataprocess_stopped_cb(const char *line, const char *prefix, void *data)
1219a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
1229a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	char c = line[strlen(prefix)];
1239a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	// t:tracing stop, T:job control stop
1249a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	*(int *)data = (c == 't' || c == 'T');
1252b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	return CBS_STOP;
1269a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
1279a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
1289a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataint
1299a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataprocess_stopped(pid_t pid)
1309a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
1319a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	int is_stopped = -1;
1329a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	FILE * file = open_status_file(pid);
1339a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	if (file != NULL) {
1349a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		each_line_starting(file, "State:\t", &process_stopped_cb,
1359a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata				   &is_stopped);
1369a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		fclose(file);
1379a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	}
1389a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	return is_stopped;
1399a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
1409a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
1412b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machatastatic enum callback_status
1422b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machataprocess_status_cb(const char *line, const char *prefix, void *data)
1439a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
144617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata	const char * status = line + strlen(prefix);
145617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata	const char c = *status;
146617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata
147617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata#define RETURN(C) do {					\
148617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata		*(enum process_status *)data = C;	\
1492b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		return CBS_STOP;			\
150617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata	} while (0)
151617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata
152617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata	switch (c) {
153617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata	case 'Z': RETURN(ps_zombie);
154617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata	case 't': RETURN(ps_tracing_stop);
155cbe29c6c0ad01839a81272c4715ea73d17e89611Petr Machata	case 'T':
156617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata		/* This can be either "T (stopped)" or, for older
157617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata		 * kernels, "T (tracing stop)".  */
158617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata		if (!strcmp(status, "T (stopped)\n"))
159617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata			RETURN(ps_stop);
160617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata		else if (!strcmp(status, "T (tracing stop)\n"))
161617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata			RETURN(ps_tracing_stop);
162617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata		else {
163617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata			fprintf(stderr, "Unknown process status: %s",
164617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata				status);
165617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata			RETURN(ps_stop); /* Some sort of stop
166617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata					  * anyway.  */
167617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata		}
168cbe29c6c0ad01839a81272c4715ea73d17e89611Petr Machata	case 'D':
169cbe29c6c0ad01839a81272c4715ea73d17e89611Petr Machata	case 'S': RETURN(ps_sleeping);
170617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata	}
171617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata
172617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata	RETURN(ps_other);
173617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata#undef RETURN
1749a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
1759a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
176617ff0bb228c64df4bb6682321338aecfec2d170Petr Machataenum process_status
1779a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataprocess_status(pid_t pid)
1789a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
179617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata	enum process_status ret = ps_invalid;
1809a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	FILE * file = open_status_file(pid);
1819a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	if (file != NULL) {
1829a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		each_line_starting(file, "State:\t", &process_status_cb, &ret);
1839a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		fclose(file);
184750ca8c13f402a40b01802dcb5c88e092ff68125Petr Machata		if (ret == ps_invalid)
185750ca8c13f402a40b01802dcb5c88e092ff68125Petr Machata			error(0, errno, "process_status %d", pid);
186750ca8c13f402a40b01802dcb5c88e092ff68125Petr Machata	} else
187750ca8c13f402a40b01802dcb5c88e092ff68125Petr Machata		/* If the file is not present, the process presumably
188750ca8c13f402a40b01802dcb5c88e092ff68125Petr Machata		 * exited already.  */
189750ca8c13f402a40b01802dcb5c88e092ff68125Petr Machata		ret = ps_zombie;
190750ca8c13f402a40b01802dcb5c88e092ff68125Petr Machata
1919a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	return ret;
1929a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
1939a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
1949a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machatastatic int
1959a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataall_digits(const char *str)
1969a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
1979a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	while (isdigit(*str))
1989a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		str++;
1999a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	return !*str;
2009a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
2019a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
2029a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataint
2039a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataprocess_tasks(pid_t pid, pid_t **ret_tasks, size_t *ret_n)
2049a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
2059a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	PROC_PID_FILE(fn, "/proc/%d/task", pid);
2069a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	DIR * d = opendir(fn);
2079a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	if (d == NULL)
2089a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		return -1;
2099a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
2109a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	pid_t *tasks = NULL;
2119a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	size_t n = 0;
2129a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	size_t alloc = 0;
2139a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
2149a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	while (1) {
2159a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		struct dirent entry;
2169a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		struct dirent *result;
2179a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		if (readdir_r(d, &entry, &result) != 0) {
2189a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			free(tasks);
2199a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			return -1;
2209a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		}
2219a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		if (result == NULL)
2229a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			break;
2239a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		if (result->d_type == DT_DIR && all_digits(result->d_name)) {
2249a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			pid_t npid = atoi(result->d_name);
2259a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			if (n >= alloc) {
2269a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata				alloc = alloc > 0 ? (2 * alloc) : 8;
2279a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata				pid_t *ntasks = realloc(tasks,
2289a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata							sizeof(*tasks) * alloc);
2299a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata				if (ntasks == NULL) {
2309a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata					free(tasks);
2319a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata					return -1;
2329a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata				}
2339a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata				tasks = ntasks;
2349a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			}
2359a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			if (n >= alloc)
2369a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata				abort();
2379a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			tasks[n++] = npid;
2389a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		}
2399a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	}
2409a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
2419a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	closedir(d);
2429a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
2439a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	*ret_tasks = tasks;
2449a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	*ret_n = n;
2459a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	return 0;
2469a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
2479a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
2486a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata/* On native 64-bit system, we need to be careful when handling cross
2496a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * tracing.  This select appropriate pointer depending on host and
2506a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * target architectures.  XXX Really we should abstract this into the
2516a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * ABI object, as theorized about somewhere on pmachata/revamp
2526a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * branch.  */
2536a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic void *
2546a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machataselect_32_64(struct Process *proc, void *p32, void *p64)
2556a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
2566a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (sizeof(long) == 4 || proc->mask_32bit)
2576a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return p32;
2586a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	else
2596a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return p64;
2606a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
2616a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
2626a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
2636a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatafetch_dyn64(struct Process *proc, target_address_t *addr, Elf64_Dyn *ret)
2646a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
2656a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (umovebytes(proc, *addr, ret, sizeof(*ret)) != sizeof(*ret))
2666a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
2676a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	*addr += sizeof(*ret);
2686a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
2696a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
2706a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
2716a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
2726a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatafetch_dyn32(struct Process *proc, target_address_t *addr, Elf64_Dyn *ret)
2736a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
2746a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	Elf32_Dyn dyn;
2756a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (umovebytes(proc, *addr, &dyn, sizeof(dyn)) != sizeof(dyn))
2766a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
2776a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
2786a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	*addr += sizeof(dyn);
2796a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->d_tag = dyn.d_tag;
2806a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->d_un.d_val = dyn.d_un.d_val;
2816a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
2826a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
2836a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
2846a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
2856a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int (*
2866a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatadyn_fetcher(struct Process *proc))(struct Process *,
2876a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata				   target_address_t *, Elf64_Dyn *)
2886a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
2896a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return select_32_64(proc, fetch_dyn32, fetch_dyn64);
2906a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
2916a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
29247cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damatostatic int
2936a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatafind_dynamic_entry_addr(struct Process *proc, target_address_t src_addr,
2946a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata			int d_tag, target_address_t *ret)
2956a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
29647cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato	debug(DEBUG_FUNCTION, "find_dynamic_entry()");
29747cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato
2986a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (ret == NULL || src_addr == 0 || d_tag < 0 || d_tag > DT_NUM)
29947cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato		return -1;
30047cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato
3016a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	int i = 0;
3026a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	while (1) {
3036a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf64_Dyn entry;
3046a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		if (dyn_fetcher(proc)(proc, &src_addr, &entry) < 0
3056a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		    || entry.d_tag == DT_NULL
3066a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		    || i++ > 100) { /* Arbitrary cut-off so that we
3076a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata				     * don't loop forever if the
3086a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata				     * binary is corrupted.  */
3096a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata			debug(2, "Couldn't find address for dtag!");
3106a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata			return -1;
3116a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		}
3126a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
31347cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato		if (entry.d_tag == d_tag) {
314ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata			/* XXX The double cast should be removed when
315ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata			 * target_address_t becomes integral type.  */
316ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata			*ret = (target_address_t)(uintptr_t)entry.d_un.d_val;
3176a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata			debug(2, "found address: %p in dtag %d\n", *ret, d_tag);
31817476b7bfac0e1cb68f9a1dbdb65dab2ac2160c6Petr Machata			return 0;
31947cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato		}
32047cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato	}
3216a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
3226a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3236a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata/* Our own type for representing 32-bit linkmap.  We can't rely on the
3246a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * definition in link.h, because that's only accurate for our host
3256a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * architecture, not for target architecture (where the traced process
3266a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * runs). */
3276a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata#define LT_LINK_MAP(BITS)			\
3286a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	{					\
3296a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr l_addr;	\
3306a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr l_name;	\
3316a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr l_ld;		\
3326a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr l_next;	\
3336a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr l_prev;	\
3346a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	}
3356a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastruct lt_link_map_32 LT_LINK_MAP(32);
3366a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastruct lt_link_map_64 LT_LINK_MAP(64);
33747cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato
3386a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
3396a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatafetch_lm64(struct Process *proc, target_address_t addr,
3406a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	   struct lt_link_map_64 *ret)
3416a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
3426a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (umovebytes(proc, addr, ret, sizeof(*ret)) != sizeof(*ret))
3436a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
3446a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
3456a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
3466a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3476a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
3486a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatafetch_lm32(struct Process *proc, target_address_t addr,
3496a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	   struct lt_link_map_64 *ret)
3506a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
3516a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	struct lt_link_map_32 lm;
3526a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (umovebytes(proc, addr, &lm, sizeof(lm)) != sizeof(lm))
3536a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
3546a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3556a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->l_addr = lm.l_addr;
3566a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->l_name = lm.l_name;
3576a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->l_ld = lm.l_ld;
3586a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->l_next = lm.l_next;
3596a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->l_prev = lm.l_prev;
3606a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3616a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
3626a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
3636a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3646a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int (*
3656a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatalm_fetcher(struct Process *proc))(struct Process *,
3666a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata				  target_address_t, struct lt_link_map_64 *)
3676a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
3686a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return select_32_64(proc, fetch_lm32, fetch_lm64);
3696a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
3706a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3716a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata/* The same as above holds for struct r_debug.  */
3726a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata#define LT_R_DEBUG(BITS)			\
3736a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	{					\
3746a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		int r_version;			\
3756a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr r_map;		\
3766a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr r_brk;		\
3776a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		int r_state;			\
3786a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr r_ldbase;	\
3796a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	}
3806a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3816a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastruct lt_r_debug_32 LT_R_DEBUG(32);
3826a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastruct lt_r_debug_64 LT_R_DEBUG(64);
3836a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3846a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
3856a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatafetch_rd64(struct Process *proc, target_address_t addr,
3866a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	   struct lt_r_debug_64 *ret)
3876a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
3886a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (umovebytes(proc, addr, ret, sizeof(*ret)) != sizeof(*ret))
3896a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
3906a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
3916a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
3926a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3936a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
3946a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatafetch_rd32(struct Process *proc, target_address_t addr,
3956a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	   struct lt_r_debug_64 *ret)
3966a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
3976a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	struct lt_r_debug_32 rd;
3986a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (umovebytes(proc, addr, &rd, sizeof(rd)) != sizeof(rd))
3996a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
4006a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
4016a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->r_version = rd.r_version;
4026a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->r_map = rd.r_map;
4036a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->r_brk = rd.r_brk;
4046a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->r_state = rd.r_state;
4056a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->r_ldbase = rd.r_ldbase;
4066a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
4076a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
4086a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
4096a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
4106a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int (*
4116a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatardebug_fetcher(struct Process *proc))(struct Process *,
4126a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata				      target_address_t, struct lt_r_debug_64 *)
4136a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
4146a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return select_32_64(proc, fetch_rd32, fetch_rd64);
41547cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato}
416f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
417f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damatostatic void
4186a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatacrawl_linkmap(struct Process *proc, struct lt_r_debug_64 *dbg)
4192b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata{
420f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	debug (DEBUG_FUNCTION, "crawl_linkmap()");
421f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
422f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	if (!dbg || !dbg->r_map) {
423f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		debug(2, "Debug structure or it's linkmap are NULL!");
424f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		return;
425f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
426f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
427ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata	/* XXX The double cast should be removed when
428ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata	 * target_address_t becomes integral type.  */
429ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata	target_address_t addr = (target_address_t)(uintptr_t)dbg->r_map;
430f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
4316a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	while (addr != 0) {
4326a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		struct lt_link_map_64 rlm;
4336a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		if (lm_fetcher(proc)(proc, addr, &rlm) < 0) {
43474d80544c9ad0b1c5ff94dda639e12ddf1d2ca1cPetr Machata			debug(2, "Unable to read link map");
435f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			return;
436f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		}
437f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
43889ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata		target_address_t key = addr;
439ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata		/* XXX The double cast should be removed when
440ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata		 * target_address_t becomes integral type.  */
441ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata		addr = (target_address_t)(uintptr_t)rlm.l_next;
4426a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		if (rlm.l_name == 0) {
44374d80544c9ad0b1c5ff94dda639e12ddf1d2ca1cPetr Machata			debug(2, "Name of mapped library is NULL");
444f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			return;
445f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		}
446f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
4476a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		char lib_name[BUFSIZ];
448ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata		/* XXX The double cast should be removed when
449ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata		 * target_address_t becomes integral type.  */
450ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata		umovebytes(proc, (target_address_t)(uintptr_t)rlm.l_name,
4516a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata			   lib_name, sizeof(lib_name));
452f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
4532b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		if (*lib_name == '\0') {
4542b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			/* VDSO.  No associated file, XXX but we might
4552b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			 * load it from the address space of the
4562b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			 * process.  */
457f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			continue;
458f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		}
459f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
46089ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata		/* Do we have that library already?  */
46189ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata		if (proc_each_library(proc, NULL, library_with_key_cb, &key))
46289ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata			continue;
46389ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata
464b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata		struct library *lib = malloc(sizeof(*lib));
4652b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		if (lib == NULL) {
466b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata		fail:
467b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata			if (lib != NULL)
468b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata				library_destroy(lib);
4692b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			error(0, errno, "Couldn't load ELF object %s\n",
4702b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			      lib_name);
4712b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			continue;
472f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		}
473b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata		library_init(lib, LT_LIBTYPE_DSO);
474b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata
475b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata		if (ltelf_read_library(lib, proc, lib_name, rlm.l_addr) < 0)
476b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata			goto fail;
477b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata
47889ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata		lib->key = key;
4792b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		proc_add_library(proc, lib);
480f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
481f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	return;
482f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato}
483f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
484029171fffcf6328768866cf510763b2eb927f1bdPetr Machata/* A struct stored at proc->debug.  */
485029171fffcf6328768866cf510763b2eb927f1bdPetr Machatastruct debug_struct
486029171fffcf6328768866cf510763b2eb927f1bdPetr Machata{
487029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	target_address_t debug_addr;
488029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	int state;
489029171fffcf6328768866cf510763b2eb927f1bdPetr Machata};
490029171fffcf6328768866cf510763b2eb927f1bdPetr Machata
4916a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
4926a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machataload_debug_struct(struct Process *proc, struct lt_r_debug_64 *ret)
4936a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
494f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	debug(DEBUG_FUNCTION, "load_debug_struct");
495f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
496029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	struct debug_struct *debug = proc->debug;
497029171fffcf6328768866cf510763b2eb927f1bdPetr Machata
498029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	if (rdebug_fetcher(proc)(proc, debug->debug_addr, ret) < 0) {
499f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		debug(2, "This process does not have a debug structure!\n");
5006a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
501f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
502f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
5036a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
504f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato}
505f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
506f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damatostatic void
50712affff3c88731a0880690442485494e540f7a58Petr Machatardebug_bp_on_hit(struct breakpoint *bp, struct Process *proc)
5082b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata{
509f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	debug(DEBUG_FUNCTION, "arch_check_dbg");
510f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
5116a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	struct lt_r_debug_64 rdbg;
5126a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (load_debug_struct(proc, &rdbg) < 0) {
513f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		debug(2, "Unable to load debug structure!");
514f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		return;
515f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
516f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
517029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	struct debug_struct *debug = proc->debug;
5186a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (rdbg.r_state == RT_CONSISTENT) {
519f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		debug(2, "Linkmap is now consistent");
520029171fffcf6328768866cf510763b2eb927f1bdPetr Machata		if (debug->state == RT_ADD) {
521f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			debug(2, "Adding DSO to linkmap");
5222b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			//data.proc = proc;
5236a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata			crawl_linkmap(proc, &rdbg);
5242b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			//&data);
525029171fffcf6328768866cf510763b2eb927f1bdPetr Machata		} else if (debug->state == RT_DELETE) {
526f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			debug(2, "Removing DSO from linkmap");
527f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		} else {
528f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			debug(2, "Unexpected debug state!");
529f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		}
530f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
531f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
532029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	debug->state = rdbg.r_state;
533f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato}
534f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
535f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damatoint
53652dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machatalinkmap_init(struct Process *proc, target_address_t dyn_addr)
5372b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata{
538f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	debug(DEBUG_FUNCTION, "linkmap_init()");
539f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
540029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	struct debug_struct *debug = malloc(sizeof(*debug));
541029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	if (debug == NULL) {
542029171fffcf6328768866cf510763b2eb927f1bdPetr Machata		error(0, errno, "couldn't allocate debug struct");
54389ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata	fail:
544029171fffcf6328768866cf510763b2eb927f1bdPetr Machata		proc->debug = NULL;
545029171fffcf6328768866cf510763b2eb927f1bdPetr Machata		free(debug);
546f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		return -1;
547f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
548029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	proc->debug = debug;
549f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
550029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	if (find_dynamic_entry_addr(proc, dyn_addr, DT_DEBUG,
551029171fffcf6328768866cf510763b2eb927f1bdPetr Machata				    &debug->debug_addr) == -1) {
552029171fffcf6328768866cf510763b2eb927f1bdPetr Machata		debug(2, "Couldn't find debug structure!");
553029171fffcf6328768866cf510763b2eb927f1bdPetr Machata		goto fail;
554029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	}
555f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
5566a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	int status;
5576a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	struct lt_r_debug_64 rdbg;
5586a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if ((status = load_debug_struct(proc, &rdbg)) < 0) {
559f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		debug(2, "No debug structure or no memory to allocate one!");
5606a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return status;
561f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
562f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
563ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata	/* XXX The double cast should be removed when
564ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata	 * target_address_t becomes integral type.  */
565ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata	target_address_t addr = (target_address_t)(uintptr_t)rdbg.r_brk;
56689ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata	if (arch_translate_address(proc, addr, &addr) < 0)
56789ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata		goto fail;
56889ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata
5699df15016447915a61526af8cb81c588913bcf44cPetr Machata	struct breakpoint *rdebug_bp = insert_breakpoint(proc, addr, NULL);
5702b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	static struct bp_callbacks rdebug_callbacks = {
57112affff3c88731a0880690442485494e540f7a58Petr Machata		.on_hit = rdebug_bp_on_hit,
5722b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	};
5732b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	rdebug_bp->cbs = &rdebug_callbacks;
574f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
5756a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	crawl_linkmap(proc, &rdbg);
576f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
577f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	return 0;
578f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato}
5799a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
58018bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machatastatic int
58118bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machatafetch_auxv64_entry(int fd, Elf64_auxv_t *ret)
58218bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata{
58318bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata	/* Reaching EOF is as much problem as not reading whole
58418bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata	 * entry.  */
58518bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata	return read(fd, ret, sizeof(*ret)) == sizeof(*ret) ? 0 : -1;
58618bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata}
58718bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata
58818bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machatastatic int
58918bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machatafetch_auxv32_entry(int fd, Elf64_auxv_t *ret)
59018bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata{
59118bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata	Elf32_auxv_t auxv;
59218bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata	if (read(fd, &auxv, sizeof(auxv)) != sizeof(auxv))
59318bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata		return -1;
59418bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata
59518bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata	ret->a_type = auxv.a_type;
59618bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata	ret->a_un.a_val = auxv.a_un.a_val;
59718bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata	return 0;
59818bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata}
59918bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata
60018bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machatastatic int (*
60118bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machataauxv_fetcher(struct Process *proc))(int, Elf64_auxv_t *)
60218bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata{
60318bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata	return select_32_64(proc, fetch_auxv32_entry, fetch_auxv64_entry);
60418bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata}
60518bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata
60618bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machataint
60718bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machataprocess_get_entry(struct Process *proc,
60818bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata		  target_address_t *entryp,
60918bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata		  target_address_t *interp_biasp)
61018bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata{
61118bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata	PROC_PID_FILE(fn, "/proc/%d/auxv", proc->pid);
61218bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata	int fd = open(fn, O_RDONLY);
61318bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata	if (fd == -1) {
61418bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata	fail:
61518bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata		error(0, errno, "couldn't read %s", fn);
61618bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata	done:
61718bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata		if (fd != -1)
61818bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata			close(fd);
61918bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata		return fd == -1 ? -1 : 0;
62018bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata	}
62118bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata
62218bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata	target_address_t at_entry = 0;
62318bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata	target_address_t at_bias = 0;
62418bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata	while (1) {
62518bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata		Elf64_auxv_t entry;
62618bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata		if (auxv_fetcher(proc)(fd, &entry) < 0)
62718bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata			goto fail;
62818bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata
62918bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata		switch (entry.a_type) {
63018bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata		case AT_BASE:
631ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata			/* XXX The double cast should be removed when
632ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata			 * target_address_t becomes integral type.  */
633ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata			at_bias = (target_address_t)
634ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata				(uintptr_t)entry.a_un.a_val;
63518bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata			continue;
63618bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata
63718bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata		case AT_ENTRY:
638ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata			/* XXX The double cast should be removed when
639ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata			 * target_address_t becomes integral type.  */
640ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata			at_entry = (target_address_t)
641ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata				(uintptr_t)entry.a_un.a_val;
64218bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata		default:
64318bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata			continue;
64418bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata
64518bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata		case AT_NULL:
64618bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata			break;
64718bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata		}
64818bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata		break;
64918bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata	}
65018bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata
65118bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata	*entryp = at_entry;
65218bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata	*interp_biasp = at_bias;
65318bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata	goto done;
65418bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata}
65518bd8ffa003c680e3d44d1b05fc3a7b43e6a25cePetr Machata
6569a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataint
6579a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machatatask_kill (pid_t pid, int sig)
6589a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
6599a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	// Taken from GDB
6609a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata        int ret;
6619a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
6629a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata        errno = 0;
6639a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata        ret = syscall (__NR_tkill, pid, sig);
6649a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	return ret;
6659a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
666