proc.c revision 029171fffcf6328768866cf510763b2eb927f1bd
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{
2962b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	fprintf(stderr, "find_dynamic_entry_addr %d %p %d\n",
2976a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		proc->pid, src_addr, d_tag);
29847cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato
29947cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato	debug(DEBUG_FUNCTION, "find_dynamic_entry()");
30047cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato
3016a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (ret == NULL || src_addr == 0 || d_tag < 0 || d_tag > DT_NUM)
30247cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato		return -1;
30347cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato
3046a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	int i = 0;
3056a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	while (1) {
3066a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf64_Dyn entry;
3076a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		if (dyn_fetcher(proc)(proc, &src_addr, &entry) < 0
3086a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		    || entry.d_tag == DT_NULL
3096a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		    || i++ > 100) { /* Arbitrary cut-off so that we
3106a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata				     * don't loop forever if the
3116a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata				     * binary is corrupted.  */
3126a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata			debug(2, "Couldn't find address for dtag!");
3136a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata			return -1;
3146a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		}
3156a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
31647cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato		if (entry.d_tag == d_tag) {
3172b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			fprintf(stderr, "   hit\n");
3186a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata			*ret = (target_address_t)entry.d_un.d_val;
3196a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata			debug(2, "found address: %p in dtag %d\n", *ret, d_tag);
32017476b7bfac0e1cb68f9a1dbdb65dab2ac2160c6Petr Machata			return 0;
32147cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato		}
32247cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato	}
3236a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
3246a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3256a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata/* Our own type for representing 32-bit linkmap.  We can't rely on the
3266a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * definition in link.h, because that's only accurate for our host
3276a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * architecture, not for target architecture (where the traced process
3286a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * runs). */
3296a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata#define LT_LINK_MAP(BITS)			\
3306a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	{					\
3316a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr l_addr;	\
3326a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr l_name;	\
3336a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr l_ld;		\
3346a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr l_next;	\
3356a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr l_prev;	\
3366a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	}
3376a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastruct lt_link_map_32 LT_LINK_MAP(32);
3386a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastruct lt_link_map_64 LT_LINK_MAP(64);
33947cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato
3406a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
3416a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatafetch_lm64(struct Process *proc, target_address_t addr,
3426a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	   struct lt_link_map_64 *ret)
3436a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
3446a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (umovebytes(proc, addr, ret, sizeof(*ret)) != sizeof(*ret))
3456a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
3466a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
3476a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
3486a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3496a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
3506a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatafetch_lm32(struct Process *proc, target_address_t addr,
3516a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	   struct lt_link_map_64 *ret)
3526a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
3536a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	struct lt_link_map_32 lm;
3546a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (umovebytes(proc, addr, &lm, sizeof(lm)) != sizeof(lm))
3556a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
3566a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3576a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->l_addr = lm.l_addr;
3586a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->l_name = lm.l_name;
3596a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->l_ld = lm.l_ld;
3606a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->l_next = lm.l_next;
3616a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->l_prev = lm.l_prev;
3626a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3636a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
3646a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
3656a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3666a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int (*
3676a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatalm_fetcher(struct Process *proc))(struct Process *,
3686a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata				  target_address_t, struct lt_link_map_64 *)
3696a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
3706a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return select_32_64(proc, fetch_lm32, fetch_lm64);
3716a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
3726a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3736a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata/* The same as above holds for struct r_debug.  */
3746a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata#define LT_R_DEBUG(BITS)			\
3756a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	{					\
3766a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		int r_version;			\
3776a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr r_map;		\
3786a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr r_brk;		\
3796a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		int r_state;			\
3806a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr r_ldbase;	\
3816a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	}
3826a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3836a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastruct lt_r_debug_32 LT_R_DEBUG(32);
3846a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastruct lt_r_debug_64 LT_R_DEBUG(64);
3856a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3866a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
3876a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatafetch_rd64(struct Process *proc, target_address_t addr,
3886a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	   struct lt_r_debug_64 *ret)
3896a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
3906a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (umovebytes(proc, addr, ret, sizeof(*ret)) != sizeof(*ret))
3916a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
3926a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
3936a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
3946a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3956a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
3966a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatafetch_rd32(struct Process *proc, target_address_t addr,
3976a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	   struct lt_r_debug_64 *ret)
3986a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
3996a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	struct lt_r_debug_32 rd;
4006a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (umovebytes(proc, addr, &rd, sizeof(rd)) != sizeof(rd))
4016a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
4026a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
4036a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->r_version = rd.r_version;
4046a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->r_map = rd.r_map;
4056a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->r_brk = rd.r_brk;
4066a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->r_state = rd.r_state;
4076a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->r_ldbase = rd.r_ldbase;
4086a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
4096a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
4106a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
4116a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
4126a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int (*
4136a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatardebug_fetcher(struct Process *proc))(struct Process *,
4146a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata				      target_address_t, struct lt_r_debug_64 *)
4156a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
4166a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return select_32_64(proc, fetch_rd32, fetch_rd64);
41747cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato}
418f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
419f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damatostatic void
4206a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatacrawl_linkmap(struct Process *proc, struct lt_r_debug_64 *dbg)
4212b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata{
422f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	debug (DEBUG_FUNCTION, "crawl_linkmap()");
423f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
424f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	if (!dbg || !dbg->r_map) {
425f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		debug(2, "Debug structure or it's linkmap are NULL!");
426f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		return;
427f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
428f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
4296a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	target_address_t addr = (target_address_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;
4396a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		addr = (target_address_t)rlm.l_next;
4406a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		if (rlm.l_name == 0) {
44174d80544c9ad0b1c5ff94dda639e12ddf1d2ca1cPetr Machata			debug(2, "Name of mapped library is NULL");
442f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			return;
443f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		}
444f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
4456a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		char lib_name[BUFSIZ];
4466a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		umovebytes(proc, (target_address_t)rlm.l_name,
4476a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata			   lib_name, sizeof(lib_name));
448f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
4492b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		if (*lib_name == '\0') {
4502b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			/* VDSO.  No associated file, XXX but we might
4512b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			 * load it from the address space of the
4522b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			 * process.  */
453f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			continue;
454f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		}
455f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
45689ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata		/* Do we have that library already?  */
45789ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata		if (proc_each_library(proc, NULL, library_with_key_cb, &key))
45889ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata			continue;
45989ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata
46089ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata		fprintf(stderr, "DSO addr=%#lx, name='%s'\n",
46189ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata			rlm.l_addr, lib_name);
462b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata
463b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata		struct library *lib = malloc(sizeof(*lib));
4642b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		if (lib == NULL) {
465b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata		fail:
466b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata			if (lib != NULL)
467b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata				library_destroy(lib);
4682b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			error(0, errno, "Couldn't load ELF object %s\n",
4692b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			      lib_name);
4702b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			continue;
471f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		}
472b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata		library_init(lib, LT_LIBTYPE_DSO);
473b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata
474b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata		if (ltelf_read_library(lib, proc, lib_name, rlm.l_addr) < 0)
475b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata			goto fail;
476b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata
47789ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata		lib->key = key;
4782b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		proc_add_library(proc, lib);
479f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
480f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	return;
481f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato}
482f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
483029171fffcf6328768866cf510763b2eb927f1bdPetr Machata/* A struct stored at proc->debug.  */
484029171fffcf6328768866cf510763b2eb927f1bdPetr Machatastruct debug_struct
485029171fffcf6328768866cf510763b2eb927f1bdPetr Machata{
486029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	target_address_t debug_addr;
487029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	int state;
488029171fffcf6328768866cf510763b2eb927f1bdPetr Machata};
489029171fffcf6328768866cf510763b2eb927f1bdPetr Machata
4906a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
4916a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machataload_debug_struct(struct Process *proc, struct lt_r_debug_64 *ret)
4926a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
493f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	debug(DEBUG_FUNCTION, "load_debug_struct");
494f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
495029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	struct debug_struct *debug = proc->debug;
496029171fffcf6328768866cf510763b2eb927f1bdPetr Machata
497029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	if (rdebug_fetcher(proc)(proc, debug->debug_addr, ret) < 0) {
498f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		debug(2, "This process does not have a debug structure!\n");
4996a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
500f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
501f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
5026a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
503f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato}
504f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
505f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damatostatic void
50612affff3c88731a0880690442485494e540f7a58Petr Machatardebug_bp_on_hit(struct breakpoint *bp, struct Process *proc)
5072b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata{
5082b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	fprintf(stderr, "======= HIT\n");
509f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
510f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	debug(DEBUG_FUNCTION, "arch_check_dbg");
511f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
5126a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	struct lt_r_debug_64 rdbg;
5136a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (load_debug_struct(proc, &rdbg) < 0) {
514f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		debug(2, "Unable to load debug structure!");
515f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		return;
516f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
517f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
518029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	struct debug_struct *debug = proc->debug;
5196a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (rdbg.r_state == RT_CONSISTENT) {
520f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		debug(2, "Linkmap is now consistent");
521029171fffcf6328768866cf510763b2eb927f1bdPetr Machata		if (debug->state == RT_ADD) {
522f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			debug(2, "Adding DSO to linkmap");
5232b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			//data.proc = proc;
5246a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata			crawl_linkmap(proc, &rdbg);
5252b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			//&data);
526029171fffcf6328768866cf510763b2eb927f1bdPetr Machata		} else if (debug->state == RT_DELETE) {
527f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			debug(2, "Removing DSO from linkmap");
528f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		} else {
529f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			debug(2, "Unexpected debug state!");
530f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		}
531f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
532f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
533029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	debug->state = rdbg.r_state;
534f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato}
535f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
536f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damatoint
53752dbfb161efeab85bddc880966db2f7af9b9cf9aPetr Machatalinkmap_init(struct Process *proc, target_address_t dyn_addr)
5382b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata{
5392b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	//struct cb_data data;
540f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
541f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	debug(DEBUG_FUNCTION, "linkmap_init()");
5422b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	fprintf(stderr, "linkmap_init dyn_addr=%p\n", dyn_addr);
543f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
544029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	struct debug_struct *debug = malloc(sizeof(*debug));
545029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	if (debug == NULL) {
546029171fffcf6328768866cf510763b2eb927f1bdPetr Machata		error(0, errno, "couldn't allocate debug struct");
54789ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata	fail:
548029171fffcf6328768866cf510763b2eb927f1bdPetr Machata		proc->debug = NULL;
549029171fffcf6328768866cf510763b2eb927f1bdPetr Machata		free(debug);
550f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		return -1;
551f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
552029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	proc->debug = debug;
553f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
554029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	if (find_dynamic_entry_addr(proc, dyn_addr, DT_DEBUG,
555029171fffcf6328768866cf510763b2eb927f1bdPetr Machata				    &debug->debug_addr) == -1) {
556029171fffcf6328768866cf510763b2eb927f1bdPetr Machata		debug(2, "Couldn't find debug structure!");
557029171fffcf6328768866cf510763b2eb927f1bdPetr Machata		goto fail;
558029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	}
559f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
5606a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	int status;
5616a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	struct lt_r_debug_64 rdbg;
5626a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if ((status = load_debug_struct(proc, &rdbg)) < 0) {
563f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		debug(2, "No debug structure or no memory to allocate one!");
5646a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return status;
565f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
566f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
5672b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	//data.lte = lte;
568f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
56989ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata	target_address_t addr = (target_address_t)rdbg.r_brk;
57089ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata	if (arch_translate_address(proc, addr, &addr) < 0)
57189ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata		goto fail;
57289ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata	fprintf(stderr, "  r_brk=%p\n", addr);
57389ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata
5749df15016447915a61526af8cb81c588913bcf44cPetr Machata	struct breakpoint *rdebug_bp = insert_breakpoint(proc, addr, NULL);
5752b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	static struct bp_callbacks rdebug_callbacks = {
57612affff3c88731a0880690442485494e540f7a58Petr Machata		.on_hit = rdebug_bp_on_hit,
5772b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	};
5782b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	rdebug_bp->cbs = &rdebug_callbacks;
579f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
5806a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	crawl_linkmap(proc, &rdbg);
581f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
582f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	return 0;
583f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato}
5849a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
5859a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataint
5869a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machatatask_kill (pid_t pid, int sig)
5879a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
5889a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	// Taken from GDB
5899a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata        int ret;
5909a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
5919a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata        errno = 0;
5929a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata        ret = syscall (__NR_tkill, pid, sig);
5939a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	return ret;
5949a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
595