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