proc.c revision eb584971e63ce7a866c376d87ae8cb9088dd69be
1642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata/*
2642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata * This file is part of ltrace.
3642626096a694c6af279d25d2b1b2fba5b10ddfbPetr Machata * Copyright (C) 2011,2012 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) {
180617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata	case 'Z': RETURN(ps_zombie);
181617ff0bb228c64df4bb6682321338aecfec2d170Petr 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"))
186617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata			RETURN(ps_stop);
187617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata		else if (!strcmp(status, "T (tracing stop)\n"))
188617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata			RETURN(ps_tracing_stop);
189617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata		else {
190617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata			fprintf(stderr, "Unknown process status: %s",
191617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata				status);
192617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata			RETURN(ps_stop); /* Some sort of stop
193617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata					  * anyway.  */
194617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata		}
195cbe29c6c0ad01839a81272c4715ea73d17e89611Petr Machata	case 'D':
196cbe29c6c0ad01839a81272c4715ea73d17e89611Petr Machata	case 'S': RETURN(ps_sleeping);
197617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata	}
198617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata
199617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata	RETURN(ps_other);
200617ff0bb228c64df4bb6682321338aecfec2d170Petr Machata#undef RETURN
2019a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
2029a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
203617ff0bb228c64df4bb6682321338aecfec2d170Petr Machataenum process_status
2049a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataprocess_status(pid_t pid)
2059a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
206617ff0bb228c64df4bb6682321338aecfec2d170Petr 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);
211750ca8c13f402a40b01802dcb5c88e092ff68125Petr Machata		if (ret == ps_invalid)
212cc0e1e4b83d69441cc5f61ea87eda5458ee9fae3Petr Machata			fprintf(stderr, "process_status %d: %s", pid,
213cc0e1e4b83d69441cc5f61ea87eda5458ee9fae3Petr Machata				strerror(errno));
214750ca8c13f402a40b01802dcb5c88e092ff68125Petr Machata	} else
215750ca8c13f402a40b01802dcb5c88e092ff68125Petr Machata		/* If the file is not present, the process presumably
216750ca8c13f402a40b01802dcb5c88e092ff68125Petr Machata		 * exited already.  */
217750ca8c13f402a40b01802dcb5c88e092ff68125Petr Machata		ret = ps_zombie;
218750ca8c13f402a40b01802dcb5c88e092ff68125Petr Machata
2199a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	return ret;
2209a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
2219a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
2229a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machatastatic int
2239a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataall_digits(const char *str)
2249a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
2259a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	while (isdigit(*str))
2269a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		str++;
2279a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	return !*str;
2289a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
2299a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
2309a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataint
2319a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataprocess_tasks(pid_t pid, pid_t **ret_tasks, size_t *ret_n)
2329a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
2339a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	PROC_PID_FILE(fn, "/proc/%d/task", pid);
2349a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	DIR * d = opendir(fn);
2359a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	if (d == NULL)
2369a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		return -1;
2379a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
2389a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	pid_t *tasks = NULL;
2399a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	size_t n = 0;
2409a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	size_t alloc = 0;
2419a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
2429a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	while (1) {
2439a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		struct dirent entry;
2449a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		struct dirent *result;
2459a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		if (readdir_r(d, &entry, &result) != 0) {
2469a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			free(tasks);
2479a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			return -1;
2489a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		}
2499a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		if (result == NULL)
2509a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			break;
2519a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		if (result->d_type == DT_DIR && all_digits(result->d_name)) {
2529a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			pid_t npid = atoi(result->d_name);
2539a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			if (n >= alloc) {
2549a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata				alloc = alloc > 0 ? (2 * alloc) : 8;
2559a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata				pid_t *ntasks = realloc(tasks,
2569a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata							sizeof(*tasks) * alloc);
2579a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata				if (ntasks == NULL) {
2589a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata					free(tasks);
2599a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata					return -1;
2609a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata				}
2619a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata				tasks = ntasks;
2629a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			}
2639a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			if (n >= alloc)
2649a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata				abort();
2659a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata			tasks[n++] = npid;
2669a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata		}
2679a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	}
2689a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
2699a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	closedir(d);
2709a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
2719a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	*ret_tasks = tasks;
2729a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	*ret_n = n;
2739a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	return 0;
2749a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
2759a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
2766a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata/* On native 64-bit system, we need to be careful when handling cross
2776a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * tracing.  This select appropriate pointer depending on host and
2786a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * target architectures.  XXX Really we should abstract this into the
2796a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * ABI object, as theorized about somewhere on pmachata/revamp
2806a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * branch.  */
2816a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic void *
2826a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machataselect_32_64(struct Process *proc, void *p32, void *p64)
2836a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
2846a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (sizeof(long) == 4 || proc->mask_32bit)
2856a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return p32;
2866a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	else
2876a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return p64;
2886a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
2896a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
2906a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
291bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machatafetch_dyn64(struct Process *proc, arch_addr_t *addr, Elf64_Dyn *ret)
2926a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
2936a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (umovebytes(proc, *addr, ret, sizeof(*ret)) != sizeof(*ret))
2946a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
2956a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	*addr += sizeof(*ret);
2966a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
2976a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
2986a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
2996a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
300bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machatafetch_dyn32(struct Process *proc, arch_addr_t *addr, Elf64_Dyn *ret)
3016a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
3026a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	Elf32_Dyn dyn;
3036a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (umovebytes(proc, *addr, &dyn, sizeof(dyn)) != sizeof(dyn))
3046a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
3056a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3066a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	*addr += sizeof(dyn);
3076a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->d_tag = dyn.d_tag;
3086a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->d_un.d_val = dyn.d_un.d_val;
3096a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3106a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
3116a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
3126a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3136a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int (*
3146a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatadyn_fetcher(struct Process *proc))(struct Process *,
315bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata				   arch_addr_t *, Elf64_Dyn *)
3166a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
3176a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return select_32_64(proc, fetch_dyn32, fetch_dyn64);
3186a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
3196a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
320cc77b0e0e735d598f4bc746f8e79b6cd342bd606Edgar E. Iglesiasint
321cc77b0e0e735d598f4bc746f8e79b6cd342bd606Edgar E. Iglesiasproc_find_dynamic_entry_addr(struct Process *proc, arch_addr_t src_addr,
322cc77b0e0e735d598f4bc746f8e79b6cd342bd606Edgar E. Iglesias			     int d_tag, arch_addr_t *ret)
3236a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
32447cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato	debug(DEBUG_FUNCTION, "find_dynamic_entry()");
32547cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato
326fd4b4ef0d4fbaf2039fac61764421e47cac2ca39Edgar E. Iglesias	if (ret == NULL || src_addr == 0 || d_tag < 0)
32747cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato		return -1;
32847cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato
3296a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	int i = 0;
3306a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	while (1) {
3316a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf64_Dyn entry;
3326a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		if (dyn_fetcher(proc)(proc, &src_addr, &entry) < 0
3336a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		    || entry.d_tag == DT_NULL
3346a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		    || i++ > 100) { /* Arbitrary cut-off so that we
3356a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata				     * don't loop forever if the
3366a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata				     * binary is corrupted.  */
3376a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata			debug(2, "Couldn't find address for dtag!");
3386a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata			return -1;
3396a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		}
3406a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
34147cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato		if (entry.d_tag == d_tag) {
342ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata			/* XXX The double cast should be removed when
343bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata			 * arch_addr_t becomes integral type.  */
344bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata			*ret = (arch_addr_t)(uintptr_t)entry.d_un.d_val;
3458454bd71f00aba4b383d42a8fec44695c9b0f018Petr Machata			debug(2, "found address: %p in dtag %d", *ret, d_tag);
34617476b7bfac0e1cb68f9a1dbdb65dab2ac2160c6Petr Machata			return 0;
34747cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato		}
34847cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato	}
3496a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
3506a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3516a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata/* Our own type for representing 32-bit linkmap.  We can't rely on the
3526a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * definition in link.h, because that's only accurate for our host
3536a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * architecture, not for target architecture (where the traced process
3546a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata * runs). */
3556a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata#define LT_LINK_MAP(BITS)			\
3566a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	{					\
3576a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr l_addr;	\
3586a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr l_name;	\
3596a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr l_ld;		\
3606a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr l_next;	\
3616a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr l_prev;	\
3626a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	}
3636a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastruct lt_link_map_32 LT_LINK_MAP(32);
3646a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastruct lt_link_map_64 LT_LINK_MAP(64);
36547cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato
3666a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
367bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machatafetch_lm64(struct Process *proc, arch_addr_t addr,
3686a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	   struct lt_link_map_64 *ret)
3696a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
3706a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (umovebytes(proc, addr, ret, sizeof(*ret)) != sizeof(*ret))
3716a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
3726a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
3736a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
3746a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3756a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
376bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machatafetch_lm32(struct Process *proc, arch_addr_t addr,
3776a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	   struct lt_link_map_64 *ret)
3786a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
3796a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	struct lt_link_map_32 lm;
3806a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (umovebytes(proc, addr, &lm, sizeof(lm)) != sizeof(lm))
3816a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
3826a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3836a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->l_addr = lm.l_addr;
3846a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->l_name = lm.l_name;
3856a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->l_ld = lm.l_ld;
3866a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->l_next = lm.l_next;
3876a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->l_prev = lm.l_prev;
3886a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3896a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
3906a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
3916a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3926a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int (*
3936a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatalm_fetcher(struct Process *proc))(struct Process *,
394bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata				  arch_addr_t, struct lt_link_map_64 *)
3956a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
3966a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return select_32_64(proc, fetch_lm32, fetch_lm64);
3976a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
3986a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
3996a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata/* The same as above holds for struct r_debug.  */
4006a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata#define LT_R_DEBUG(BITS)			\
4016a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	{					\
4026a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		int r_version;			\
4036a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr r_map;		\
4046a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr r_brk;		\
4056a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		int r_state;			\
4066a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		Elf##BITS##_Addr r_ldbase;	\
4076a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	}
4086a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
4096a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastruct lt_r_debug_32 LT_R_DEBUG(32);
4106a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastruct lt_r_debug_64 LT_R_DEBUG(64);
4116a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
4126a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
413bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machatafetch_rd64(struct Process *proc, arch_addr_t addr,
4146a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	   struct lt_r_debug_64 *ret)
4156a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
4166a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (umovebytes(proc, addr, ret, sizeof(*ret)) != sizeof(*ret))
4176a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
4186a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
4196a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
4206a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
4216a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
422bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machatafetch_rd32(struct Process *proc, arch_addr_t addr,
4236a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	   struct lt_r_debug_64 *ret)
4246a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
4256a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	struct lt_r_debug_32 rd;
4266a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (umovebytes(proc, addr, &rd, sizeof(rd)) != sizeof(rd))
4276a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
4286a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
4296a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->r_version = rd.r_version;
4306a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->r_map = rd.r_map;
4316a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->r_brk = rd.r_brk;
4326a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->r_state = rd.r_state;
4336a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	ret->r_ldbase = rd.r_ldbase;
4346a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
4356a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
4366a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata}
4376a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata
4386a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int (*
4396a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatardebug_fetcher(struct Process *proc))(struct Process *,
440bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata				      arch_addr_t, struct lt_r_debug_64 *)
4416a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
4426a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return select_32_64(proc, fetch_rd32, fetch_rd64);
44347cae1e251a212425cae5ac6e736de0cb0bbf714Joe Damato}
444f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
4450475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machatastatic int
4460475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machatafetch_auxv64_entry(int fd, Elf64_auxv_t *ret)
4470475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata{
4480475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	/* Reaching EOF is as much problem as not reading whole
4490475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	 * entry.  */
4500475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	return read(fd, ret, sizeof(*ret)) == sizeof(*ret) ? 0 : -1;
4510475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata}
4520475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata
4530475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machatastatic int
4540475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machatafetch_auxv32_entry(int fd, Elf64_auxv_t *ret)
4550475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata{
4560475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	Elf32_auxv_t auxv;
4570475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	if (read(fd, &auxv, sizeof(auxv)) != sizeof(auxv))
4580475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		return -1;
4590475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata
4600475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	ret->a_type = auxv.a_type;
4610475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	ret->a_un.a_val = auxv.a_un.a_val;
4620475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	return 0;
4630475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata}
4640475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata
4650475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machatastatic int (*
4660475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machataauxv_fetcher(struct Process *proc))(int, Elf64_auxv_t *)
4670475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata{
4680475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	return select_32_64(proc, fetch_auxv32_entry, fetch_auxv64_entry);
4690475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata}
4700475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata
471f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damatostatic void
4726a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatacrawl_linkmap(struct Process *proc, struct lt_r_debug_64 *dbg)
4732b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata{
474f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	debug (DEBUG_FUNCTION, "crawl_linkmap()");
475f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
476f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	if (!dbg || !dbg->r_map) {
477f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		debug(2, "Debug structure or it's linkmap are NULL!");
478f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		return;
479f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
480f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
481ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata	/* XXX The double cast should be removed when
482bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata	 * arch_addr_t becomes integral type.  */
483bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata	arch_addr_t addr = (arch_addr_t)(uintptr_t)dbg->r_map;
484f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
4856a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	while (addr != 0) {
4866a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		struct lt_link_map_64 rlm;
4876a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		if (lm_fetcher(proc)(proc, addr, &rlm) < 0) {
48874d80544c9ad0b1c5ff94dda639e12ddf1d2ca1cPetr Machata			debug(2, "Unable to read link map");
489f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			return;
490f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		}
491f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
492bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata		arch_addr_t key = addr;
493ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata		/* XXX The double cast should be removed when
494bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata		 * arch_addr_t becomes integral type.  */
495bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata		addr = (arch_addr_t)(uintptr_t)rlm.l_next;
4966a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		if (rlm.l_name == 0) {
49774d80544c9ad0b1c5ff94dda639e12ddf1d2ca1cPetr Machata			debug(2, "Name of mapped library is NULL");
498f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			return;
499f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		}
500f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
5016a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		char lib_name[BUFSIZ];
502ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata		/* XXX The double cast should be removed when
503bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata		 * arch_addr_t becomes integral type.  */
504bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata		umovebytes(proc, (arch_addr_t)(uintptr_t)rlm.l_name,
5056a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata			   lib_name, sizeof(lib_name));
506f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
5072b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		if (*lib_name == '\0') {
5082b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			/* VDSO.  No associated file, XXX but we might
5092b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			 * load it from the address space of the
5102b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			 * process.  */
511f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			continue;
512f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		}
513f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
51489ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata		/* Do we have that library already?  */
51589ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata		if (proc_each_library(proc, NULL, library_with_key_cb, &key))
51689ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata			continue;
51789ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata
518b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata		struct library *lib = malloc(sizeof(*lib));
5192b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		if (lib == NULL) {
520b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata		fail:
521b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata			if (lib != NULL)
522b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata				library_destroy(lib);
523cc0e1e4b83d69441cc5f61ea87eda5458ee9fae3Petr Machata			fprintf(stderr, "Couldn't load ELF object %s: %s\n",
524cc0e1e4b83d69441cc5f61ea87eda5458ee9fae3Petr Machata				lib_name, strerror(errno));
5252b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata			continue;
526f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		}
527b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata		library_init(lib, LT_LIBTYPE_DSO);
528b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata
529b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata		if (ltelf_read_library(lib, proc, lib_name, rlm.l_addr) < 0)
530b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata			goto fail;
531b5f80ac8982c40f79915ce1e1cb9bf8650ac5fe7Petr Machata
53289ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata		lib->key = key;
5332b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata		proc_add_library(proc, lib);
534f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
535f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	return;
536f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato}
537f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
5386a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machatastatic int
5396a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machataload_debug_struct(struct Process *proc, struct lt_r_debug_64 *ret)
5406a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata{
541f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	debug(DEBUG_FUNCTION, "load_debug_struct");
542f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
54347d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata	if (rdebug_fetcher(proc)(proc, proc->os.debug_addr, ret) < 0) {
544c06f23d2803c7744f3d2cd1fb3e54886d9e41ddfPetr Machata		debug(2, "This process does not have a debug structure!");
5456a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return -1;
546f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
547f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
5486a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	return 0;
549f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato}
550f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
551f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damatostatic void
55212affff3c88731a0880690442485494e540f7a58Petr Machatardebug_bp_on_hit(struct breakpoint *bp, struct Process *proc)
5532b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata{
554f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	debug(DEBUG_FUNCTION, "arch_check_dbg");
555f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
5566a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	struct lt_r_debug_64 rdbg;
5576a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (load_debug_struct(proc, &rdbg) < 0) {
558f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		debug(2, "Unable to load debug structure!");
559f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		return;
560f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
561f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
5626a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if (rdbg.r_state == RT_CONSISTENT) {
563f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		debug(2, "Linkmap is now consistent");
56447d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata		switch (proc->os.debug_state) {
56547d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata		case RT_ADD:
566f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			debug(2, "Adding DSO to linkmap");
5676a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata			crawl_linkmap(proc, &rdbg);
56847d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata			break;
56947d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata		case RT_DELETE:
570f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			debug(2, "Removing DSO from linkmap");
57147d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata			// XXX unload that library
57247d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata			break;
57347d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata		default:
574f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato			debug(2, "Unexpected debug state!");
575f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		}
576f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
577f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
57847d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata	proc->os.debug_state = rdbg.r_state;
579f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato}
580f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
58111c3c3e28461886bb16c69c745b1fefa946c4d9fEdgar E. Iglesias#ifndef ARCH_HAVE_FIND_DL_DEBUG
58211c3c3e28461886bb16c69c745b1fefa946c4d9fEdgar E. Iglesiasint
58311c3c3e28461886bb16c69c745b1fefa946c4d9fEdgar E. Iglesiasarch_find_dl_debug(struct Process *proc, arch_addr_t dyn_addr,
58411c3c3e28461886bb16c69c745b1fefa946c4d9fEdgar E. Iglesias		   arch_addr_t *ret)
58511c3c3e28461886bb16c69c745b1fefa946c4d9fEdgar E. Iglesias{
58611c3c3e28461886bb16c69c745b1fefa946c4d9fEdgar E. Iglesias	return proc_find_dynamic_entry_addr(proc, dyn_addr, DT_DEBUG, ret);
58711c3c3e28461886bb16c69c745b1fefa946c4d9fEdgar E. Iglesias}
58811c3c3e28461886bb16c69c745b1fefa946c4d9fEdgar E. Iglesias#endif
58911c3c3e28461886bb16c69c745b1fefa946c4d9fEdgar E. Iglesias
590f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damatoint
591bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machatalinkmap_init(struct Process *proc, arch_addr_t dyn_addr)
5922b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata{
593b8fd68d15b1f631e38148ac5dab39d7e857fbc92Petr Machata	debug(DEBUG_FUNCTION, "linkmap_init(%d, dyn_addr=%p)", proc->pid, dyn_addr);
594f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
59547d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata	if (arch_find_dl_debug(proc, dyn_addr, &proc->os.debug_addr) == -1) {
596029171fffcf6328768866cf510763b2eb927f1bdPetr Machata		debug(2, "Couldn't find debug structure!");
59747d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata		return -1;
598029171fffcf6328768866cf510763b2eb927f1bdPetr Machata	}
599f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
6006a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	int status;
6016a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	struct lt_r_debug_64 rdbg;
6026a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	if ((status = load_debug_struct(proc, &rdbg)) < 0) {
603f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato		debug(2, "No debug structure or no memory to allocate one!");
6046a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata		return status;
605f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	}
606f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
607ea8eb9a606096fd072abe104b4239f67883ad39aPetr Machata	/* XXX The double cast should be removed when
608bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata	 * arch_addr_t becomes integral type.  */
609bac2da505ee174b7fb984b975c5938f88f0dbab2Petr Machata	arch_addr_t addr = (arch_addr_t)(uintptr_t)rdbg.r_brk;
610b1492dfaca6882fa0798b549e0557c7dec6b7e9cPetr Machata	if (arch_translate_address_dyn(proc, addr, &addr) < 0)
61147d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata		return -1;
61289ac0395a9e018f4d4dbda9d3e27159419a92da2Petr Machata
6139df15016447915a61526af8cb81c588913bcf44cPetr Machata	struct breakpoint *rdebug_bp = insert_breakpoint(proc, addr, NULL);
6142b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	static struct bp_callbacks rdebug_callbacks = {
61512affff3c88731a0880690442485494e540f7a58Petr Machata		.on_hit = rdebug_bp_on_hit,
6162b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	};
6172b46cfc1127d390eddd9593fe5ce5399c1f68130Petr Machata	rdebug_bp->cbs = &rdebug_callbacks;
618f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
6196a7997de9eabf9b0c6e32309ca08870198eb864bPetr Machata	crawl_linkmap(proc, &rdbg);
620f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato
621f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato	return 0;
622f0bd98b3e6753d8609a3054a61f2df6f9cdac10aJoe Damato}
6239a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
6249a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machataint
6259a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machatatask_kill (pid_t pid, int sig)
6269a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata{
6279a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	// Taken from GDB
6289a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata        int ret;
6299a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata
6309a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata        errno = 0;
6319a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata        ret = syscall (__NR_tkill, pid, sig);
6329a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata	return ret;
6339a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata}
634cd972587a4c0d14d764b3d0a43d75f5941db14ccPetr Machata
635cd972587a4c0d14d764b3d0a43d75f5941db14ccPetr Machatavoid
636cd972587a4c0d14d764b3d0a43d75f5941db14ccPetr Machataprocess_removed(struct Process *proc)
637cd972587a4c0d14d764b3d0a43d75f5941db14ccPetr Machata{
638cd972587a4c0d14d764b3d0a43d75f5941db14ccPetr Machata	delete_events_for(proc);
639cd972587a4c0d14d764b3d0a43d75f5941db14ccPetr Machata}
6400475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata
6410475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machataint
6420475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machataprocess_get_entry(struct Process *proc,
6430475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		  arch_addr_t *entryp,
6440475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		  arch_addr_t *interp_biasp)
6450475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata{
6460475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	PROC_PID_FILE(fn, "/proc/%d/auxv", proc->pid);
6470475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	int fd = open(fn, O_RDONLY);
6480475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	if (fd == -1) {
6490475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	fail:
6500475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		fprintf(stderr, "couldn't read %s: %s", fn, strerror(errno));
6510475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	done:
6520475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		if (fd != -1)
6530475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata			close(fd);
6540475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		return fd == -1 ? -1 : 0;
6550475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	}
6560475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata
6570475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	arch_addr_t at_entry = 0;
6580475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	arch_addr_t at_bias = 0;
6590475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	while (1) {
660eb584971e63ce7a866c376d87ae8cb9088dd69bePetr Machata		Elf64_auxv_t entry = {};
6610475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		if (auxv_fetcher(proc)(fd, &entry) < 0)
6620475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata			goto fail;
6630475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata
6640475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		switch (entry.a_type) {
6650475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		case AT_BASE:
6660475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata			/* XXX The double cast should be removed when
6670475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata			 * arch_addr_t becomes integral type.  */
6680475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata			at_bias = (arch_addr_t)(uintptr_t)entry.a_un.a_val;
6690475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata			continue;
6700475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata
6710475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		case AT_ENTRY:
6720475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata			/* XXX The double cast should be removed when
6730475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata			 * arch_addr_t becomes integral type.  */
6740475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata			at_entry = (arch_addr_t)(uintptr_t)entry.a_un.a_val;
6750475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		default:
6760475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata			continue;
6770475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata
6780475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		case AT_NULL:
6790475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata			break;
6800475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		}
6810475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		break;
6820475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	}
6830475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata
6840475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	if (entryp != NULL)
6850475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		*entryp = at_entry;
6860475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	if (interp_biasp != NULL)
6870475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata		*interp_biasp = at_bias;
6880475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata	goto done;
6890475ac36f22c9531cd0e0ba7d02cee5a1c5c67eaPetr Machata}
69047d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata
69147d70f6efd145113ad555dd2ba542d1050bbb784Petr Machataint
69247d70f6efd145113ad555dd2ba542d1050bbb784Petr Machataos_process_init(struct Process *proc)
69347d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata{
69447d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata	proc->os.debug_addr = 0;
69547d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata	proc->os.debug_state = 0;
69647d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata	return 0;
69747d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata}
69847d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata
69947d70f6efd145113ad555dd2ba542d1050bbb784Petr Machatavoid
70047d70f6efd145113ad555dd2ba542d1050bbb784Petr Machataos_process_destroy(struct Process *proc)
70147d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata{
70247d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata}
70347d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata
70447d70f6efd145113ad555dd2ba542d1050bbb784Petr Machataint
70547d70f6efd145113ad555dd2ba542d1050bbb784Petr Machataos_process_clone(struct Process *retp, struct Process *proc)
70647d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata{
70747d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata	retp->os = proc->os;
70847d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata	return 0;
70947d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata}
71047d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata
71147d70f6efd145113ad555dd2ba542d1050bbb784Petr Machataint
71247d70f6efd145113ad555dd2ba542d1050bbb784Petr Machataos_process_exec(struct Process *proc)
71347d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata{
71447d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata	return 0;
71547d70f6efd145113ad555dd2ba542d1050bbb784Petr Machata}
716