1642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata/*
2642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata * This file is part of ltrace.
34e553c020b0e621bc15d76296990d06e47cf29f9Petr Machata * Copyright (C) 2011,2012,2013 Petr Machata, Red Hat Inc.
4642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata * Copyright (C) 2010 Zachary T Welch, CodeSourcery
5642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata * Copyright (C) 2010 Joe Damato
6642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata * Copyright (C) 1998,2008,2009 Juan Cespedes
7642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata *
8642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata * This program is free software; you can redistribute it and/or
9642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata * modify it under the terms of the GNU General Public License as
10642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata * published by the Free Software Foundation; either version 2 of the
11642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata * License, or (at your option) any later version.
12642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata *
13642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata * This program is distributed in the hope that it will be useful, but
14642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of
15642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata * General Public License for more details.
17642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata *
18642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata * You should have received a copy of the GNU General Public License
19642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata * along with this program; if not, write to the Free Software
20642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata * 02110-1301 USA
22642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata */
23642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata
24750ca8c13f402a40b01802dcb5c88e092ff68125Petr Machata#define _GNU_SOURCE /* For getline.  */
25d44c6b8b090b8b7aa9d971d9e0bfd848732a3071Juan Cespedes#include "config.h"
26d44c6b8b090b8b7aa9d971d9e0bfd848732a3071Juan Cespedes
279a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata#include <sys/stat.h>
28cc0e1e4b83d69441cc5f61ea87eda5458ee9fae3Petr Machata#include <sys/syscall.h>
29cc0e1e4b83d69441cc5f61ea87eda5458ee9fae3Petr Machata#include <sys/types.h>
30cc0e1e4b83d69441cc5f61ea87eda5458ee9fae3Petr Machata#include <ctype.h>
31cc0e1e4b83d69441cc5f61ea87eda5458ee9fae3Petr Machata#include <dirent.h>
32cc0e1e4b83d69441cc5f61ea87eda5458ee9fae3Petr Machata#include <errno.h>
339a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata#include <fcntl.h>
34bfb26c745705a839f1ef5fc45e1b32135b9bc3e7Zachary T Welch#include <inttypes.h>
3547cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato#include <link.h>
36cc0e1e4b83d69441cc5f61ea87eda5458ee9fae3Petr Machata#include <signal.h>
371fe93d5b55ad2b8d4009a63e343db19cc1f21bb0Juan Cespedes#include <stdio.h>
38ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include <stdlib.h>
391fe93d5b55ad2b8d4009a63e343db19cc1f21bb0Juan Cespedes#include <string.h>
40273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes#include <unistd.h>
419a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
42642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata#include "backend.h"
43ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include "breakpoint.h"
44ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include "config.h"
45ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include "debug.h"
46cd972587a4c0d14d764b3d0a43d75f5941db14ccPetr Machata#include "events.h"
47ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include "library.h"
48ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include "ltrace-elf.h"
49ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata#include "proc.h"
50273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes
51273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes/* /proc/pid doesn't exist just after the fork, and sometimes `ltrace'
52273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes * couldn't open it to find the executable.  So it may be necessary to
53273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes * have a bit delay
54273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes */
55273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes
562d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand#define	MAX_DELAY	100000	/* 100000 microseconds = 0.1 seconds */
571fe93d5b55ad2b8d4009a63e343db19cc1f21bb0Juan Cespedes
589a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata#define PROC_PID_FILE(VAR, FORMAT, PID)		\
599a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	char VAR[strlen(FORMAT) + 6];		\
609a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	sprintf(VAR, FORMAT, PID)
619a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
621fe93d5b55ad2b8d4009a63e343db19cc1f21bb0Juan Cespedes/*
63e0660df7f943cc832694db3b8b6778c0ff65860dJuan Cespedes * Returns a (malloc'd) file name corresponding to a running pid
641fe93d5b55ad2b8d4009a63e343db19cc1f21bb0Juan Cespedes */
65f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedeschar *
66f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedespid2name(pid_t pid) {
671fe93d5b55ad2b8d4009a63e343db19cc1f21bb0Juan Cespedes	if (!kill(pid, 0)) {
682d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand		int delay = 0;
69273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes
709a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		PROC_PID_FILE(proc_exe, "/proc/%d/exe", pid);
71273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes
722d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand		while (delay < MAX_DELAY) {
73273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes			if (!access(proc_exe, F_OK)) {
74273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes				return strdup(proc_exe);
75273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes			}
76273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes			delay += 1000;	/* 1 milisecond */
77273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes		}
781fe93d5b55ad2b8d4009a63e343db19cc1f21bb0Juan Cespedes	}
79273ea6d18164e35ee40524e853a6f04706d3bdffJuan Cespedes	return NULL;
801fe93d5b55ad2b8d4009a63e343db19cc1f21bb0Juan Cespedes}
8147cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato
829a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machatastatic FILE *
839a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataopen_status_file(pid_t pid)
849a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
859a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	PROC_PID_FILE(fn, "/proc/%d/status", pid);
869a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	/* Don't complain if we fail.  This would typically happen
879a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	   when the process is about to terminate, and these files are
889a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	   not available anymore.  This function is called from the
899a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	   event loop, and we don't want to clutter the output just
909a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	   because the process terminates.  */
919a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	return fopen(fn, "r");
929a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
939a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
949a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machatastatic char *
959a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machatafind_line_starting(FILE * file, const char * prefix, size_t len)
969a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
979a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	char * line = NULL;
989a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	size_t line_len = 0;
999a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	while (!feof(file)) {
1009a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		if (getline(&line, &line_len, file) < 0)
1019a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			return NULL;
1029a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		if (strncmp(line, prefix, len) == 0)
1039a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			return line;
1049a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	}
1059a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	return NULL;
1069a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
1079a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
1089a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machatastatic void
1092b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machataeach_line_starting(FILE *file, const char *prefix,
1102b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		   enum callback_status (*cb)(const char *line,
1112b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata					      const char *prefix,
1122b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata					      void *data),
1132b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		   void *data)
1149a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
1159a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	size_t len = strlen(prefix);
1169a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	char * line;
1179a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	while ((line = find_line_starting(file, prefix, len)) != NULL) {
1182b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		enum callback_status st = (*cb)(line, prefix, data);
119ba1664b062414481d0f37d06bb01a19874c8d481Petr Machata		free(line);
1202b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		if (st == CBS_STOP)
1219a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			return;
1229a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	}
1239a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
1249a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
1252b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machatastatic enum callback_status
1262b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machataprocess_leader_cb(const char *line, const char *prefix, void *data)
1279a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
1289a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	pid_t * pidp = data;
1299a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	*pidp = atoi(line + strlen(prefix));
1302b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	return CBS_STOP;
1319a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
1329a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
1339a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machatapid_t
1349a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataprocess_leader(pid_t pid)
1359a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
1361974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata	pid_t tgid = 0;
1379a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	FILE * file = open_status_file(pid);
1389a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	if (file != NULL) {
1399a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		each_line_starting(file, "Tgid:\t", &process_leader_cb, &tgid);
1409a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		fclose(file);
1419a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	}
1429a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
1439a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	return tgid;
1449a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
1459a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
1462b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machatastatic enum callback_status
1472b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machataprocess_stopped_cb(const char *line, const char *prefix, void *data)
1489a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
1499a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	char c = line[strlen(prefix)];
1509a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	// t:tracing stop, T:job control stop
1519a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	*(int *)data = (c == 't' || c == 'T');
1522b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	return CBS_STOP;
1539a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
1549a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
1559a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataint
1569a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataprocess_stopped(pid_t pid)
1579a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
1589a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	int is_stopped = -1;
1599a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	FILE * file = open_status_file(pid);
1609a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	if (file != NULL) {
1619a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		each_line_starting(file, "State:\t", &process_stopped_cb,
1629a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata				   &is_stopped);
1639a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		fclose(file);
1649a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	}
1659a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	return is_stopped;
1669a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
1679a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
1682b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machatastatic enum callback_status
1692b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machataprocess_status_cb(const char *line, const char *prefix, void *data)
1709a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
171617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata	const char * status = line + strlen(prefix);
172617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata	const char c = *status;
173617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata
174617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata#define RETURN(C) do {					\
175617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata		*(enum process_status *)data = C;	\
1762b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		return CBS_STOP;			\
177617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata	} while (0)
178617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata
179617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata	switch (c) {
1806dfc544b6aa6703d2292be34470aebf874d78452Petr Machata	case 'Z': RETURN(PS_ZOMBIE);
1816dfc544b6aa6703d2292be34470aebf874d78452Petr Machata	case 't': RETURN(PS_TRACING_STOP);
182cbe29c6c0ad01839a81272c4715ea73d17e89611Petr Machata	case 'T':
183617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata		/* This can be either "T (stopped)" or, for older
184617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata		 * kernels, "T (tracing stop)".  */
185617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata		if (!strcmp(status, "T (stopped)\n"))
1866dfc544b6aa6703d2292be34470aebf874d78452Petr Machata			RETURN(PS_STOP);
187617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata		else if (!strcmp(status, "T (tracing stop)\n"))
1886dfc544b6aa6703d2292be34470aebf874d78452Petr Machata			RETURN(PS_TRACING_STOP);
189617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata		else {
190617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata			fprintf(stderr, "Unknown process status: %s",
191617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata				status);
1926dfc544b6aa6703d2292be34470aebf874d78452Petr Machata			RETURN(PS_STOP); /* Some sort of stop
193617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata					  * anyway.  */
194617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata		}
195cbe29c6c0ad01839a81272c4715ea73d17e89611Petr Machata	case 'D':
1966dfc544b6aa6703d2292be34470aebf874d78452Petr Machata	case 'S': RETURN(PS_SLEEPING);
197617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata	}
198617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata
1996dfc544b6aa6703d2292be34470aebf874d78452Petr Machata	RETURN(PS_OTHER);
200617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata#undef RETURN
2019a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
2029a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
203617ff0bb228c64df4bb6682321338aecfec2d170Petr Machataenum process_status
2049a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataprocess_status(pid_t pid)
2059a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
2066dfc544b6aa6703d2292be34470aebf874d78452Petr Machata	enum process_status ret = PS_INVALID;
2079a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	FILE * file = open_status_file(pid);
2089a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	if (file != NULL) {
2099a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		each_line_starting(file, "State:\t", &process_status_cb, &ret);
2109a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		fclose(file);
2116dfc544b6aa6703d2292be34470aebf874d78452Petr Machata		if (ret == PS_INVALID)
212aacb95e73bd532bb11fbe4005fe28286ecb2d38dPetr Machata			fprintf(stderr,
213aacb95e73bd532bb11fbe4005fe28286ecb2d38dPetr Machata				"Couldn't determine status of process %d: %s\n",
214aacb95e73bd532bb11fbe4005fe28286ecb2d38dPetr Machata				pid, strerror(errno));
2156dfc544b6aa6703d2292be34470aebf874d78452Petr Machata	} else {
216750ca8c13f402a40b01802dcb5c88e092ff68125Petr Machata		/* If the file is not present, the process presumably
217750ca8c13f402a40b01802dcb5c88e092ff68125Petr Machata		 * exited already.  */
2186dfc544b6aa6703d2292be34470aebf874d78452Petr Machata		ret = PS_ZOMBIE;
2196dfc544b6aa6703d2292be34470aebf874d78452Petr Machata	}
220750ca8c13f402a40b01802dcb5c88e092ff68125Petr Machata
2219a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	return ret;
2229a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
2239a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
2249a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machatastatic int
2259a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataall_digits(const char *str)
2269a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
2279a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	while (isdigit(*str))
2289a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		str++;
2299a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	return !*str;
2309a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
2319a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
2329a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataint
2339a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataprocess_tasks(pid_t pid, pid_t **ret_tasks, size_t *ret_n)
2349a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
2359a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	PROC_PID_FILE(fn, "/proc/%d/task", pid);
2366bf1e6abb46255456d307bb73432d8733978e5fdPetr Machata	DIR *d = opendir(fn);
2379a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	if (d == NULL)
2389a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		return -1;
2399a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
2409a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	pid_t *tasks = NULL;
2419a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	size_t n = 0;
2429a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	size_t alloc = 0;
2439a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
2449a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	while (1) {
2459a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		struct dirent entry;
2469a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		struct dirent *result;
2479a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		if (readdir_r(d, &entry, &result) != 0) {
2486bf1e6abb46255456d307bb73432d8733978e5fdPetr Machata		fail:
2499a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			free(tasks);
2506bf1e6abb46255456d307bb73432d8733978e5fdPetr Machata			closedir(d);
2519a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			return -1;
2529a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		}
2539a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		if (result == NULL)
2549a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			break;
2559a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		if (result->d_type == DT_DIR && all_digits(result->d_name)) {
2569a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			pid_t npid = atoi(result->d_name);
2579a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			if (n >= alloc) {
2589a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata				alloc = alloc > 0 ? (2 * alloc) : 8;
2599a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata				pid_t *ntasks = realloc(tasks,
2609a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata							sizeof(*tasks) * alloc);
2616bf1e6abb46255456d307bb73432d8733978e5fdPetr Machata				if (ntasks == NULL)
2626bf1e6abb46255456d307bb73432d8733978e5fdPetr Machata					goto fail;
2639a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata				tasks = ntasks;
2649a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			}
2656bf1e6abb46255456d307bb73432d8733978e5fdPetr Machata			assert(n < alloc);
2669a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			tasks[n++] = npid;
2679a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		}
2689a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	}
2699a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
2709a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	closedir(d);
2719a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
2729a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	*ret_tasks = tasks;
2739a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	*ret_n = n;
2749a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	return 0;
2759a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
2769a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
2776a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata/* On native 64-bit system, we need to be careful when handling cross
2786a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * tracing.  This select appropriate pointer depending on host and
2796a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * target architectures.  XXX Really we should abstract this into the
2806a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * ABI object, as theorized about somewhere on pmachata/revamp
2816a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * branch.  */
2826a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic void *
283929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataselect_32_64(struct process *proc, void *p32, void *p64)
2846a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
2856a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (sizeof(long) == 4 || proc->mask_32bit)
2866a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return p32;
2876a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	else
2886a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return p64;
2896a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
2906a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
2916a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
292929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatafetch_dyn64(struct process *proc, arch_addr_t *addr, Elf64_Dyn *ret)
2936a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
2946a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (umovebytes(proc, *addr, ret, sizeof(*ret)) != sizeof(*ret))
2956a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
2966a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	*addr += sizeof(*ret);
2976a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
2986a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
2996a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3006a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
301929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatafetch_dyn32(struct process *proc, arch_addr_t *addr, Elf64_Dyn *ret)
3026a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
3036a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	Elf32_Dyn dyn;
3046a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (umovebytes(proc, *addr, &dyn, sizeof(dyn)) != sizeof(dyn))
3056a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
3066a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3076a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	*addr += sizeof(dyn);
3086a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->d_tag = dyn.d_tag;
3096a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->d_un.d_val = dyn.d_un.d_val;
3106a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3116a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
3126a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
3136a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3146a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int (*
315929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatadyn_fetcher(struct process *proc))(struct process *,
316bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata				   arch_addr_t *, Elf64_Dyn *)
3176a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
3186a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return select_32_64(proc, fetch_dyn32, fetch_dyn64);
3196a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
3206a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
321cc77b0e0e735d598f4bc746f8e79b6cd342bd606Edgar E. Iglesiasint
322929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataproc_find_dynamic_entry_addr(struct process *proc, arch_addr_t src_addr,
323cc77b0e0e735d598f4bc746f8e79b6cd342bd606Edgar E. Iglesias			     int d_tag, arch_addr_t *ret)
3246a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
32547cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato	debug(DEBUG_FUNCTION, "find_dynamic_entry()");
32647cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato
327fd4b4ef0d4fbaf2039fac61764421e47cac2ca39Edgar E. Iglesias	if (ret == NULL || src_addr == 0 || d_tag < 0)
32847cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato		return -1;
32947cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato
3306a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	int i = 0;
3316a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	while (1) {
3326a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf64_Dyn entry;
3336a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		if (dyn_fetcher(proc)(proc, &src_addr, &entry) < 0
3346a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		    || entry.d_tag == DT_NULL
3356a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		    || i++ > 100) { /* Arbitrary cut-off so that we
3366a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata				     * don't loop forever if the
3376a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata				     * binary is corrupted.  */
3386a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata			debug(2, "Couldn't find address for dtag!");
3396a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata			return -1;
3406a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		}
3416a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
34247cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato		if (entry.d_tag == d_tag) {
343ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata			/* XXX The double cast should be removed when
344bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata			 * arch_addr_t becomes integral type.  */
345bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata			*ret = (arch_addr_t)(uintptr_t)entry.d_un.d_val;
3468454bd71f00aba4b383d42a8fec44695c9b0f018Petr Machata			debug(2, "found address: %p in dtag %d", *ret, d_tag);
34717476b7bfac0e1cb68f9a1dbdb65dab2ac2160c6Petr Machata			return 0;
34847cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato		}
34947cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato	}
3506a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
3516a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3526a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata/* Our own type for representing 32-bit linkmap.  We can't rely on the
3536a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * definition in link.h, because that's only accurate for our host
3546a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * architecture, not for target architecture (where the traced process
3556a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * runs). */
3566a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata#define LT_LINK_MAP(BITS)			\
3576a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	{					\
3586a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr l_addr;	\
3596a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr l_name;	\
3606a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr l_ld;		\
3616a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr l_next;	\
3626a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr l_prev;	\
3636a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	}
3646a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastruct lt_link_map_32 LT_LINK_MAP(32);
3656a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastruct lt_link_map_64 LT_LINK_MAP(64);
36647cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato
3676a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
368929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatafetch_lm64(struct process *proc, arch_addr_t addr,
3696a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	   struct lt_link_map_64 *ret)
3706a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
3716a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (umovebytes(proc, addr, ret, sizeof(*ret)) != sizeof(*ret))
3726a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
3736a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
3746a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
3756a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3766a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
377929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatafetch_lm32(struct process *proc, arch_addr_t addr,
3786a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	   struct lt_link_map_64 *ret)
3796a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
3806a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	struct lt_link_map_32 lm;
3816a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (umovebytes(proc, addr, &lm, sizeof(lm)) != sizeof(lm))
3826a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
3836a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3846a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->l_addr = lm.l_addr;
3856a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->l_name = lm.l_name;
3866a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->l_ld = lm.l_ld;
3876a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->l_next = lm.l_next;
3886a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->l_prev = lm.l_prev;
3896a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3906a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
3916a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
3926a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3936a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int (*
394929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatalm_fetcher(struct process *proc))(struct process *,
395bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata				  arch_addr_t, struct lt_link_map_64 *)
3966a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
3976a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return select_32_64(proc, fetch_lm32, fetch_lm64);
3986a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
3996a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
4006a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata/* The same as above holds for struct r_debug.  */
4016a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata#define LT_R_DEBUG(BITS)			\
4026a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	{					\
4036a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		int r_version;			\
4046a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr r_map;		\
4056a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr r_brk;		\
4066a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		int r_state;			\
4076a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr r_ldbase;	\
4086a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	}
4096a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
4106a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastruct lt_r_debug_32 LT_R_DEBUG(32);
4116a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastruct lt_r_debug_64 LT_R_DEBUG(64);
4126a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
4136a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
414929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatafetch_rd64(struct process *proc, arch_addr_t addr,
4156a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	   struct lt_r_debug_64 *ret)
4166a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
4176a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (umovebytes(proc, addr, ret, sizeof(*ret)) != sizeof(*ret))
4186a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
4196a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
4206a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
4216a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
4226a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
423929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatafetch_rd32(struct process *proc, arch_addr_t addr,
4246a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	   struct lt_r_debug_64 *ret)
4256a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
4266a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	struct lt_r_debug_32 rd;
4276a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (umovebytes(proc, addr, &rd, sizeof(rd)) != sizeof(rd))
4286a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
4296a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
4306a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->r_version = rd.r_version;
4316a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->r_map = rd.r_map;
4326a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->r_brk = rd.r_brk;
4336a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->r_state = rd.r_state;
4346a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->r_ldbase = rd.r_ldbase;
4356a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
4366a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
4376a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
4386a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
4396a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int (*
440929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatardebug_fetcher(struct process *proc))(struct process *,
441bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata				      arch_addr_t, struct lt_r_debug_64 *)
4426a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
4436a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return select_32_64(proc, fetch_rd32, fetch_rd64);
44447cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato}
445f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
4460475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machatastatic int
4470475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machatafetch_auxv64_entry(int fd, Elf64_auxv_t *ret)
4480475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata{
4490475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	/* Reaching EOF is as much problem as not reading whole
4500475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	 * entry.  */
4510475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	return read(fd, ret, sizeof(*ret)) == sizeof(*ret) ? 0 : -1;
4520475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata}
4530475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata
4540475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machatastatic int
4550475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machatafetch_auxv32_entry(int fd, Elf64_auxv_t *ret)
4560475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata{
4570475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	Elf32_auxv_t auxv;
4580475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	if (read(fd, &auxv, sizeof(auxv)) != sizeof(auxv))
4590475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		return -1;
4600475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata
4610475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	ret->a_type = auxv.a_type;
4620475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	ret->a_un.a_val = auxv.a_un.a_val;
4630475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	return 0;
4640475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata}
4650475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata
4660475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machatastatic int (*
467929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataauxv_fetcher(struct process *proc))(int, Elf64_auxv_t *)
4680475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata{
4690475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	return select_32_64(proc, fetch_auxv32_entry, fetch_auxv64_entry);
4700475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata}
4710475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata
472f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damatostatic void
473929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatacrawl_linkmap(struct process *proc, struct lt_r_debug_64 *dbg)
4742b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata{
475f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	debug (DEBUG_FUNCTION, "crawl_linkmap()");
476f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
477f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	if (!dbg || !dbg->r_map) {
478f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		debug(2, "Debug structure or it's linkmap are NULL!");
479f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		return;
480f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
481f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
482ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata	/* XXX The double cast should be removed when
483bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata	 * arch_addr_t becomes integral type.  */
484bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata	arch_addr_t addr = (arch_addr_t)(uintptr_t)dbg->r_map;
485f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
4866a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	while (addr != 0) {
487efd12cfb10ccd2c612838c0e22069554ce60637cPetr Machata		struct lt_link_map_64 rlm = {};
4886a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		if (lm_fetcher(proc)(proc, addr, &rlm) < 0) {
48974d80544c9ad0b1c5ff94dda639e12ddf1d2ca1cPetr Machata			debug(2, "Unable to read link map");
490f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			return;
491f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		}
492f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
493bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata		arch_addr_t key = addr;
494ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata		/* XXX The double cast should be removed when
495bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata		 * arch_addr_t becomes integral type.  */
496bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata		addr = (arch_addr_t)(uintptr_t)rlm.l_next;
4976a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		if (rlm.l_name == 0) {
49874d80544c9ad0b1c5ff94dda639e12ddf1d2ca1cPetr Machata			debug(2, "Name of mapped library is NULL");
499f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			return;
500f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		}
501f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
5026a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		char lib_name[BUFSIZ];
503ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata		/* XXX The double cast should be removed when
504bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata		 * arch_addr_t becomes integral type.  */
505bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata		umovebytes(proc, (arch_addr_t)(uintptr_t)rlm.l_name,
5066a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata			   lib_name, sizeof(lib_name));
507f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
50815595a3158e0efa20c6f357be526d54aa01393b7Petr Machata		/* Library name can be an empty string, in which case
50915595a3158e0efa20c6f357be526d54aa01393b7Petr Machata		 * the entry represents either the main binary, or a
51015595a3158e0efa20c6f357be526d54aa01393b7Petr Machata		 * VDSO.  Unfortunately we can't rely on that, as in
51115595a3158e0efa20c6f357be526d54aa01393b7Petr Machata		 * recent glibc, that entry is initialized to VDSO
51215595a3158e0efa20c6f357be526d54aa01393b7Petr Machata		 * SONAME.
51315595a3158e0efa20c6f357be526d54aa01393b7Petr Machata		 *
51415595a3158e0efa20c6f357be526d54aa01393b7Petr Machata		 * It's not clear how to detect VDSO in this case.  We
51515595a3158e0efa20c6f357be526d54aa01393b7Petr Machata		 * can't assume that l_name of real DSOs will be
51615595a3158e0efa20c6f357be526d54aa01393b7Petr Machata		 * either absolute or relative (for LD_LIBRARY_PATH=:
51715595a3158e0efa20c6f357be526d54aa01393b7Petr Machata		 * it will be neither).  We can't compare l_addr with
51815595a3158e0efa20c6f357be526d54aa01393b7Petr Machata		 * AT_SYSINFO_EHDR either, as l_addr is bias (which
51915595a3158e0efa20c6f357be526d54aa01393b7Petr Machata		 * also means it's not unique, and therefore useless
52015595a3158e0efa20c6f357be526d54aa01393b7Petr Machata		 * for this).  We could load VDSO from process image
52115595a3158e0efa20c6f357be526d54aa01393b7Petr Machata		 * and at least compare actual SONAMEs.  For now, this
52215595a3158e0efa20c6f357be526d54aa01393b7Petr Machata		 * kludge is about the best that we can do.  */
52315595a3158e0efa20c6f357be526d54aa01393b7Petr Machata		if (*lib_name == 0
52415595a3158e0efa20c6f357be526d54aa01393b7Petr Machata		    || strcmp(lib_name, "linux-vdso.so.1") == 0
525b2cfac8ace230d3cfafd7f3c15d5610bc2e6e044Petr Machata		    || strcmp(lib_name, "linux-gate.so.1") == 0
526b2cfac8ace230d3cfafd7f3c15d5610bc2e6e044Petr Machata		    || strcmp(lib_name, "linux-vdso32.so.1") == 0
527b2cfac8ace230d3cfafd7f3c15d5610bc2e6e044Petr Machata		    || strcmp(lib_name, "linux-vdso64.so.1") == 0)
528f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			continue;
529f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
53089ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata		/* Do we have that library already?  */
53189ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata		if (proc_each_library(proc, NULL, library_with_key_cb, &key))
53289ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata			continue;
53389ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata
534b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata		struct library *lib = malloc(sizeof(*lib));
5352b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		if (lib == NULL) {
536b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata		fail:
5377287166e8fd5949ffcf8eb1f3d378b5ea538915ePetr Machata			free(lib);
538cc0e1e4b83d69441cc5f61ea87eda5458ee9fae3Petr Machata			fprintf(stderr, "Couldn't load ELF object %s: %s\n",
539cc0e1e4b83d69441cc5f61ea87eda5458ee9fae3Petr Machata				lib_name, strerror(errno));
5402b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			continue;
541f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		}
542b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata
5437287166e8fd5949ffcf8eb1f3d378b5ea538915ePetr Machata		if (library_init(lib, LT_LIBTYPE_DSO) < 0)
544b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata			goto fail;
545b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata
5467287166e8fd5949ffcf8eb1f3d378b5ea538915ePetr Machata		if (ltelf_read_library(lib, proc, lib_name, rlm.l_addr) < 0) {
5477287166e8fd5949ffcf8eb1f3d378b5ea538915ePetr Machata			library_destroy(lib);
5487287166e8fd5949ffcf8eb1f3d378b5ea538915ePetr Machata			goto fail;
5497287166e8fd5949ffcf8eb1f3d378b5ea538915ePetr Machata		}
5507287166e8fd5949ffcf8eb1f3d378b5ea538915ePetr Machata
55189ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata		lib->key = key;
5522b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		proc_add_library(proc, lib);
553f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
554f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	return;
555f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato}
556f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
5576a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
558929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataload_debug_struct(struct process *proc, struct lt_r_debug_64 *ret)
5596a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
560f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	debug(DEBUG_FUNCTION, "load_debug_struct");
561f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
56247d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata	if (rdebug_fetcher(proc)(proc, proc->os.debug_addr, ret) < 0) {
563c06f23d2803c7744f3d2cd1fb3e54886d9e41ddfPetr Machata		debug(2, "This process does not have a debug structure!");
5646a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
565f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
566f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
5676a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
568f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato}
569f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
570f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damatostatic void
571929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatardebug_bp_on_hit(struct breakpoint *bp, struct process *proc)
5722b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata{
573f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	debug(DEBUG_FUNCTION, "arch_check_dbg");
574f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
5756a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	struct lt_r_debug_64 rdbg;
5766a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (load_debug_struct(proc, &rdbg) < 0) {
577f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		debug(2, "Unable to load debug structure!");
578f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		return;
579f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
580f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
5816a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (rdbg.r_state == RT_CONSISTENT) {
582f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		debug(2, "Linkmap is now consistent");
58347d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata		switch (proc->os.debug_state) {
58447d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata		case RT_ADD:
585f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			debug(2, "Adding DSO to linkmap");
5866a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata			crawl_linkmap(proc, &rdbg);
58747d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata			break;
58847d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata		case RT_DELETE:
589f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			debug(2, "Removing DSO from linkmap");
59047d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata			// XXX unload that library
59147d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata			break;
59247d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata		default:
593f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			debug(2, "Unexpected debug state!");
594f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		}
595f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
596f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
59747d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata	proc->os.debug_state = rdbg.r_state;
598f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato}
599f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
60011c3c3e28461886bb16c69c745b1fefa946c4d9fEdgar E. Iglesias#ifndef ARCH_HAVE_FIND_DL_DEBUG
60111c3c3e28461886bb16c69c745b1fefa946c4d9fEdgar E. Iglesiasint
602929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataarch_find_dl_debug(struct process *proc, arch_addr_t dyn_addr,
60311c3c3e28461886bb16c69c745b1fefa946c4d9fEdgar E. Iglesias		   arch_addr_t *ret)
60411c3c3e28461886bb16c69c745b1fefa946c4d9fEdgar E. Iglesias{
60511c3c3e28461886bb16c69c745b1fefa946c4d9fEdgar E. Iglesias	return proc_find_dynamic_entry_addr(proc, dyn_addr, DT_DEBUG, ret);
60611c3c3e28461886bb16c69c745b1fefa946c4d9fEdgar E. Iglesias}
60711c3c3e28461886bb16c69c745b1fefa946c4d9fEdgar E. Iglesias#endif
60811c3c3e28461886bb16c69c745b1fefa946c4d9fEdgar E. Iglesias
609f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damatoint
610929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatalinkmap_init(struct process *proc, arch_addr_t dyn_addr)
6112b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata{
612b8fd68d15b1f631e38148ac5dab39d7e857fbc92Petr Machata	debug(DEBUG_FUNCTION, "linkmap_init(%d, dyn_addr=%p)", proc->pid, dyn_addr);
613f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
61447d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata	if (arch_find_dl_debug(proc, dyn_addr, &proc->os.debug_addr) == -1) {
615029171fffcf6328768866cf510763b2eb927f1bdPetr Machata		debug(2, "Couldn't find debug structure!");
61647d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata		return -1;
617029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	}
618f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
6196a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	int status;
6206a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	struct lt_r_debug_64 rdbg;
6216a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if ((status = load_debug_struct(proc, &rdbg)) < 0) {
622f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		debug(2, "No debug structure or no memory to allocate one!");
6236a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return status;
624f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
625f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
6264e553c020b0e621bc15d76296990d06e47cf29f9Petr Machata	crawl_linkmap(proc, &rdbg);
6274e553c020b0e621bc15d76296990d06e47cf29f9Petr Machata
628ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata	/* XXX The double cast should be removed when
629bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata	 * arch_addr_t becomes integral type.  */
630bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata	arch_addr_t addr = (arch_addr_t)(uintptr_t)rdbg.r_brk;
631b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata	if (arch_translate_address_dyn(proc, addr, &addr) < 0)
63247d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata		return -1;
63389ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata
63402a796e5e49c147982020c78b0066930e979f3e4Petr Machata	struct breakpoint *rdebug_bp = insert_breakpoint_at(proc, addr, NULL);
6354e553c020b0e621bc15d76296990d06e47cf29f9Petr Machata	if (rdebug_bp == NULL) {
6364e553c020b0e621bc15d76296990d06e47cf29f9Petr Machata		/* This is not fatal, the tracing can continue with
6374e553c020b0e621bc15d76296990d06e47cf29f9Petr Machata		 * reduced functionality.  */
6384e553c020b0e621bc15d76296990d06e47cf29f9Petr Machata		fprintf(stderr,
6394e553c020b0e621bc15d76296990d06e47cf29f9Petr Machata			"Couldn't insert _r_debug breakpoint to %d: %s.\n"
6404e553c020b0e621bc15d76296990d06e47cf29f9Petr Machata			"As a result of that, ltrace will not be able to "
6414e553c020b0e621bc15d76296990d06e47cf29f9Petr Machata			"detect and trace\nnewly-loaded libraries.\n",
6424e553c020b0e621bc15d76296990d06e47cf29f9Petr Machata			proc->pid, strerror(errno));
6434e553c020b0e621bc15d76296990d06e47cf29f9Petr Machata	} else {
6444e553c020b0e621bc15d76296990d06e47cf29f9Petr Machata		static struct bp_callbacks rdebug_callbacks = {
6454e553c020b0e621bc15d76296990d06e47cf29f9Petr Machata			.on_hit = rdebug_bp_on_hit,
6464e553c020b0e621bc15d76296990d06e47cf29f9Petr Machata		};
6474e553c020b0e621bc15d76296990d06e47cf29f9Petr Machata		rdebug_bp->cbs = &rdebug_callbacks;
6484e553c020b0e621bc15d76296990d06e47cf29f9Petr Machata	}
649f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
650f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	return 0;
651f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato}
6529a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
6539a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataint
6549a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machatatask_kill (pid_t pid, int sig)
6559a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
6569a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	// Taken from GDB
6579a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata        int ret;
6589a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
6599a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata        errno = 0;
6609a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata        ret = syscall (__NR_tkill, pid, sig);
6619a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	return ret;
6629a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
663cd972587a4c0d14d764b3d0a43d75f5941db14ccPetr Machata
664cd972587a4c0d14d764b3d0a43d75f5941db14ccPetr Machatavoid
665929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataprocess_removed(struct process *proc)
666cd972587a4c0d14d764b3d0a43d75f5941db14ccPetr Machata{
667cd972587a4c0d14d764b3d0a43d75f5941db14ccPetr Machata	delete_events_for(proc);
668cd972587a4c0d14d764b3d0a43d75f5941db14ccPetr Machata}
6690475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata
6700475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machataint
671929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataprocess_get_entry(struct process *proc,
6720475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		  arch_addr_t *entryp,
6730475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		  arch_addr_t *interp_biasp)
6740475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata{
6750475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	PROC_PID_FILE(fn, "/proc/%d/auxv", proc->pid);
6760475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	int fd = open(fn, O_RDONLY);
6774754ea02d067a88e87d4cc67500419f20781de39Petr Machata	int ret = 0;
6780475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	if (fd == -1) {
6790475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	fail:
6800475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		fprintf(stderr, "couldn't read %s: %s", fn, strerror(errno));
6814754ea02d067a88e87d4cc67500419f20781de39Petr Machata		ret = -1;
6820475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	done:
6830475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		if (fd != -1)
6840475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata			close(fd);
6854754ea02d067a88e87d4cc67500419f20781de39Petr Machata		return ret;
6860475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	}
6870475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata
6880475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	arch_addr_t at_entry = 0;
6890475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	arch_addr_t at_bias = 0;
6900475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	while (1) {
691eb584971e63ce7a866c376d87ae8cb9088dd69bePetr Machata		Elf64_auxv_t entry = {};
6920475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		if (auxv_fetcher(proc)(fd, &entry) < 0)
6930475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata			goto fail;
6940475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata
6950475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		switch (entry.a_type) {
6960475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		case AT_BASE:
6970475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata			/* XXX The double cast should be removed when
6980475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata			 * arch_addr_t becomes integral type.  */
6990475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata			at_bias = (arch_addr_t)(uintptr_t)entry.a_un.a_val;
7000475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata			continue;
7010475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata
7020475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		case AT_ENTRY:
7030475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata			/* XXX The double cast should be removed when
7040475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata			 * arch_addr_t becomes integral type.  */
7050475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata			at_entry = (arch_addr_t)(uintptr_t)entry.a_un.a_val;
7060475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		default:
7070475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata			continue;
7080475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata
7090475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		case AT_NULL:
7100475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata			break;
7110475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		}
7120475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		break;
7130475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	}
7140475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata
7150475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	if (entryp != NULL)
7160475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		*entryp = at_entry;
7170475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	if (interp_biasp != NULL)
7180475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		*interp_biasp = at_bias;
7190475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	goto done;
7200475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata}
72147d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata
72247d70f6efd145113ad555dd2ba542d1050bbb784Petr Machataint
723929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataos_process_init(struct process *proc)
72447d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata{
72547d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata	proc->os.debug_addr = 0;
72647d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata	proc->os.debug_state = 0;
72747d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata	return 0;
72847d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata}
72947d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata
73047d70f6efd145113ad555dd2ba542d1050bbb784Petr Machatavoid
731929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataos_process_destroy(struct process *proc)
73247d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata{
73347d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata}
73447d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata
73547d70f6efd145113ad555dd2ba542d1050bbb784Petr Machataint
736929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataos_process_clone(struct process *retp, struct process *proc)
73747d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata{
73847d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata	retp->os = proc->os;
73947d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata	return 0;
74047d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata}
74147d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata
74247d70f6efd145113ad555dd2ba542d1050bbb784Petr Machataint
743929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataos_process_exec(struct process *proc)
74447d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata{
74547d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata	return 0;
74647d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata}
747