proc.c revision 8b00d5bb6a0925ece06aad0d9df0a85e8dbd7b57
1#define _GNU_SOURCE /* For getline.  */
2#include "config.h"
3
4#include <sys/types.h>
5#include <sys/stat.h>
6#include <fcntl.h>
7#include <inttypes.h>
8#include <link.h>
9#include <stdio.h>
10#include <string.h>
11#include <signal.h>
12#include <unistd.h>
13#include <dirent.h>
14#include <ctype.h>
15#include <errno.h>
16#include <sys/syscall.h>
17#include <error.h>
18
19#include "common.h"
20#include "breakpoint.h"
21#include "proc.h"
22#include "library.h"
23
24/* /proc/pid doesn't exist just after the fork, and sometimes `ltrace'
25 * couldn't open it to find the executable.  So it may be necessary to
26 * have a bit delay
27 */
28
29#define	MAX_DELAY	100000	/* 100000 microseconds = 0.1 seconds */
30
31#define PROC_PID_FILE(VAR, FORMAT, PID)		\
32	char VAR[strlen(FORMAT) + 6];		\
33	sprintf(VAR, FORMAT, PID)
34
35/*
36 * Returns a (malloc'd) file name corresponding to a running pid
37 */
38char *
39pid2name(pid_t pid) {
40	if (!kill(pid, 0)) {
41		int delay = 0;
42
43		PROC_PID_FILE(proc_exe, "/proc/%d/exe", pid);
44
45		while (delay < MAX_DELAY) {
46			if (!access(proc_exe, F_OK)) {
47				return strdup(proc_exe);
48			}
49			delay += 1000;	/* 1 milisecond */
50		}
51	}
52	return NULL;
53}
54
55static FILE *
56open_status_file(pid_t pid)
57{
58	PROC_PID_FILE(fn, "/proc/%d/status", pid);
59	/* Don't complain if we fail.  This would typically happen
60	   when the process is about to terminate, and these files are
61	   not available anymore.  This function is called from the
62	   event loop, and we don't want to clutter the output just
63	   because the process terminates.  */
64	return fopen(fn, "r");
65}
66
67static char *
68find_line_starting(FILE * file, const char * prefix, size_t len)
69{
70	char * line = NULL;
71	size_t line_len = 0;
72	while (!feof(file)) {
73		if (getline(&line, &line_len, file) < 0)
74			return NULL;
75		if (strncmp(line, prefix, len) == 0)
76			return line;
77	}
78	return NULL;
79}
80
81static void
82each_line_starting(FILE *file, const char *prefix,
83		   enum callback_status (*cb)(const char *line,
84					      const char *prefix,
85					      void *data),
86		   void *data)
87{
88	size_t len = strlen(prefix);
89	char * line;
90	while ((line = find_line_starting(file, prefix, len)) != NULL) {
91		enum callback_status st = (*cb)(line, prefix, data);
92		free (line);
93		if (st == CBS_STOP)
94			return;
95	}
96}
97
98static enum callback_status
99process_leader_cb(const char *line, const char *prefix, void *data)
100{
101	pid_t * pidp = data;
102	*pidp = atoi(line + strlen(prefix));
103	return CBS_STOP;
104}
105
106pid_t
107process_leader(pid_t pid)
108{
109	pid_t tgid = 0;
110	FILE * file = open_status_file(pid);
111	if (file != NULL) {
112		each_line_starting(file, "Tgid:\t", &process_leader_cb, &tgid);
113		fclose(file);
114	}
115
116	return tgid;
117}
118
119static enum callback_status
120process_stopped_cb(const char *line, const char *prefix, void *data)
121{
122	char c = line[strlen(prefix)];
123	// t:tracing stop, T:job control stop
124	*(int *)data = (c == 't' || c == 'T');
125	return CBS_STOP;
126}
127
128int
129process_stopped(pid_t pid)
130{
131	int is_stopped = -1;
132	FILE * file = open_status_file(pid);
133	if (file != NULL) {
134		each_line_starting(file, "State:\t", &process_stopped_cb,
135				   &is_stopped);
136		fclose(file);
137	}
138	return is_stopped;
139}
140
141static enum callback_status
142process_status_cb(const char *line, const char *prefix, void *data)
143{
144	const char * status = line + strlen(prefix);
145	const char c = *status;
146
147#define RETURN(C) do {					\
148		*(enum process_status *)data = C;	\
149		return CBS_STOP;			\
150	} while (0)
151
152	switch (c) {
153	case 'Z': RETURN(ps_zombie);
154	case 't': RETURN(ps_tracing_stop);
155	case 'T':
156		/* This can be either "T (stopped)" or, for older
157		 * kernels, "T (tracing stop)".  */
158		if (!strcmp(status, "T (stopped)\n"))
159			RETURN(ps_stop);
160		else if (!strcmp(status, "T (tracing stop)\n"))
161			RETURN(ps_tracing_stop);
162		else {
163			fprintf(stderr, "Unknown process status: %s",
164				status);
165			RETURN(ps_stop); /* Some sort of stop
166					  * anyway.  */
167		}
168	case 'D':
169	case 'S': RETURN(ps_sleeping);
170	}
171
172	RETURN(ps_other);
173#undef RETURN
174}
175
176enum process_status
177process_status(pid_t pid)
178{
179	enum process_status ret = ps_invalid;
180	FILE * file = open_status_file(pid);
181	if (file != NULL) {
182		each_line_starting(file, "State:\t", &process_status_cb, &ret);
183		fclose(file);
184		if (ret == ps_invalid)
185			error(0, errno, "process_status %d", pid);
186	} else
187		/* If the file is not present, the process presumably
188		 * exited already.  */
189		ret = ps_zombie;
190
191	return ret;
192}
193
194static int
195all_digits(const char *str)
196{
197	while (isdigit(*str))
198		str++;
199	return !*str;
200}
201
202int
203process_tasks(pid_t pid, pid_t **ret_tasks, size_t *ret_n)
204{
205	PROC_PID_FILE(fn, "/proc/%d/task", pid);
206	DIR * d = opendir(fn);
207	if (d == NULL)
208		return -1;
209
210	pid_t *tasks = NULL;
211	size_t n = 0;
212	size_t alloc = 0;
213
214	while (1) {
215		struct dirent entry;
216		struct dirent *result;
217		if (readdir_r(d, &entry, &result) != 0) {
218			free(tasks);
219			return -1;
220		}
221		if (result == NULL)
222			break;
223		if (result->d_type == DT_DIR && all_digits(result->d_name)) {
224			pid_t npid = atoi(result->d_name);
225			if (n >= alloc) {
226				alloc = alloc > 0 ? (2 * alloc) : 8;
227				pid_t *ntasks = realloc(tasks,
228							sizeof(*tasks) * alloc);
229				if (ntasks == NULL) {
230					free(tasks);
231					return -1;
232				}
233				tasks = ntasks;
234			}
235			if (n >= alloc)
236				abort();
237			tasks[n++] = npid;
238		}
239	}
240
241	closedir(d);
242
243	*ret_tasks = tasks;
244	*ret_n = n;
245	return 0;
246}
247
248/* On native 64-bit system, we need to be careful when handling cross
249 * tracing.  This select appropriate pointer depending on host and
250 * target architectures.  XXX Really we should abstract this into the
251 * ABI object, as theorized about somewhere on pmachata/revamp
252 * branch.  */
253static void *
254select_32_64(struct Process *proc, void *p32, void *p64)
255{
256	if (sizeof(long) == 4 || proc->mask_32bit)
257		return p32;
258	else
259		return p64;
260}
261
262static int
263fetch_dyn64(struct Process *proc, target_address_t *addr, Elf64_Dyn *ret)
264{
265	if (umovebytes(proc, *addr, ret, sizeof(*ret)) != sizeof(*ret))
266		return -1;
267	*addr += sizeof(*ret);
268	return 0;
269}
270
271static int
272fetch_dyn32(struct Process *proc, target_address_t *addr, Elf64_Dyn *ret)
273{
274	Elf32_Dyn dyn;
275	if (umovebytes(proc, *addr, &dyn, sizeof(dyn)) != sizeof(dyn))
276		return -1;
277
278	*addr += sizeof(dyn);
279	ret->d_tag = dyn.d_tag;
280	ret->d_un.d_val = dyn.d_un.d_val;
281
282	return 0;
283}
284
285static int (*
286dyn_fetcher(struct Process *proc))(struct Process *,
287				   target_address_t *, Elf64_Dyn *)
288{
289	return select_32_64(proc, fetch_dyn32, fetch_dyn64);
290}
291
292static int
293find_dynamic_entry_addr(struct Process *proc, target_address_t src_addr,
294			int d_tag, target_address_t *ret)
295{
296	debug(DEBUG_FUNCTION, "find_dynamic_entry()");
297
298	if (ret == NULL || src_addr == 0 || d_tag < 0 || d_tag > DT_NUM)
299		return -1;
300
301	int i = 0;
302	while (1) {
303		Elf64_Dyn entry;
304		if (dyn_fetcher(proc)(proc, &src_addr, &entry) < 0
305		    || entry.d_tag == DT_NULL
306		    || i++ > 100) { /* Arbitrary cut-off so that we
307				     * don't loop forever if the
308				     * binary is corrupted.  */
309			debug(2, "Couldn't find address for dtag!");
310			return -1;
311		}
312
313		if (entry.d_tag == d_tag) {
314			*ret = (target_address_t)entry.d_un.d_val;
315			debug(2, "found address: %p in dtag %d\n", *ret, d_tag);
316			return 0;
317		}
318	}
319}
320
321/* Our own type for representing 32-bit linkmap.  We can't rely on the
322 * definition in link.h, because that's only accurate for our host
323 * architecture, not for target architecture (where the traced process
324 * runs). */
325#define LT_LINK_MAP(BITS)			\
326	{					\
327		Elf##BITS##_Addr l_addr;	\
328		Elf##BITS##_Addr l_name;	\
329		Elf##BITS##_Addr l_ld;		\
330		Elf##BITS##_Addr l_next;	\
331		Elf##BITS##_Addr l_prev;	\
332	}
333struct lt_link_map_32 LT_LINK_MAP(32);
334struct lt_link_map_64 LT_LINK_MAP(64);
335
336static int
337fetch_lm64(struct Process *proc, target_address_t addr,
338	   struct lt_link_map_64 *ret)
339{
340	if (umovebytes(proc, addr, ret, sizeof(*ret)) != sizeof(*ret))
341		return -1;
342	return 0;
343}
344
345static int
346fetch_lm32(struct Process *proc, target_address_t addr,
347	   struct lt_link_map_64 *ret)
348{
349	struct lt_link_map_32 lm;
350	if (umovebytes(proc, addr, &lm, sizeof(lm)) != sizeof(lm))
351		return -1;
352
353	ret->l_addr = lm.l_addr;
354	ret->l_name = lm.l_name;
355	ret->l_ld = lm.l_ld;
356	ret->l_next = lm.l_next;
357	ret->l_prev = lm.l_prev;
358
359	return 0;
360}
361
362static int (*
363lm_fetcher(struct Process *proc))(struct Process *,
364				  target_address_t, struct lt_link_map_64 *)
365{
366	return select_32_64(proc, fetch_lm32, fetch_lm64);
367}
368
369/* The same as above holds for struct r_debug.  */
370#define LT_R_DEBUG(BITS)			\
371	{					\
372		int r_version;			\
373		Elf##BITS##_Addr r_map;		\
374		Elf##BITS##_Addr r_brk;		\
375		int r_state;			\
376		Elf##BITS##_Addr r_ldbase;	\
377	}
378
379struct lt_r_debug_32 LT_R_DEBUG(32);
380struct lt_r_debug_64 LT_R_DEBUG(64);
381
382static int
383fetch_rd64(struct Process *proc, target_address_t addr,
384	   struct lt_r_debug_64 *ret)
385{
386	if (umovebytes(proc, addr, ret, sizeof(*ret)) != sizeof(*ret))
387		return -1;
388	return 0;
389}
390
391static int
392fetch_rd32(struct Process *proc, target_address_t addr,
393	   struct lt_r_debug_64 *ret)
394{
395	struct lt_r_debug_32 rd;
396	if (umovebytes(proc, addr, &rd, sizeof(rd)) != sizeof(rd))
397		return -1;
398
399	ret->r_version = rd.r_version;
400	ret->r_map = rd.r_map;
401	ret->r_brk = rd.r_brk;
402	ret->r_state = rd.r_state;
403	ret->r_ldbase = rd.r_ldbase;
404
405	return 0;
406}
407
408static int (*
409rdebug_fetcher(struct Process *proc))(struct Process *,
410				      target_address_t, struct lt_r_debug_64 *)
411{
412	return select_32_64(proc, fetch_rd32, fetch_rd64);
413}
414
415static void
416crawl_linkmap(struct Process *proc, struct lt_r_debug_64 *dbg)
417{
418	debug (DEBUG_FUNCTION, "crawl_linkmap()");
419
420	if (!dbg || !dbg->r_map) {
421		debug(2, "Debug structure or it's linkmap are NULL!");
422		return;
423	}
424
425	target_address_t addr = (target_address_t)dbg->r_map;
426
427	while (addr != 0) {
428		struct lt_link_map_64 rlm;
429		if (lm_fetcher(proc)(proc, addr, &rlm) < 0) {
430			debug(2, "Unable to read link map");
431			return;
432		}
433
434		target_address_t key = addr;
435		addr = (target_address_t)rlm.l_next;
436		if (rlm.l_name == 0) {
437			debug(2, "Name of mapped library is NULL");
438			return;
439		}
440
441		char lib_name[BUFSIZ];
442		umovebytes(proc, (target_address_t)rlm.l_name,
443			   lib_name, sizeof(lib_name));
444
445		if (*lib_name == '\0') {
446			/* VDSO.  No associated file, XXX but we might
447			 * load it from the address space of the
448			 * process.  */
449			continue;
450		}
451
452		/* Do we have that library already?  */
453		if (proc_each_library(proc, NULL, library_with_key_cb, &key))
454			continue;
455
456		struct library *lib = malloc(sizeof(*lib));
457		if (lib == NULL) {
458		fail:
459			if (lib != NULL)
460				library_destroy(lib);
461			error(0, errno, "Couldn't load ELF object %s\n",
462			      lib_name);
463			continue;
464		}
465		library_init(lib, LT_LIBTYPE_DSO);
466
467		if (ltelf_read_library(lib, proc, lib_name, rlm.l_addr) < 0)
468			goto fail;
469
470		lib->key = key;
471		proc_add_library(proc, lib);
472	}
473	return;
474}
475
476/* A struct stored at proc->debug.  */
477struct debug_struct
478{
479	target_address_t debug_addr;
480	int state;
481};
482
483static int
484load_debug_struct(struct Process *proc, struct lt_r_debug_64 *ret)
485{
486	debug(DEBUG_FUNCTION, "load_debug_struct");
487
488	struct debug_struct *debug = proc->debug;
489
490	if (rdebug_fetcher(proc)(proc, debug->debug_addr, ret) < 0) {
491		debug(2, "This process does not have a debug structure!\n");
492		return -1;
493	}
494
495	return 0;
496}
497
498static void
499rdebug_bp_on_hit(struct breakpoint *bp, struct Process *proc)
500{
501	debug(DEBUG_FUNCTION, "arch_check_dbg");
502
503	struct lt_r_debug_64 rdbg;
504	if (load_debug_struct(proc, &rdbg) < 0) {
505		debug(2, "Unable to load debug structure!");
506		return;
507	}
508
509	struct debug_struct *debug = proc->debug;
510	if (rdbg.r_state == RT_CONSISTENT) {
511		debug(2, "Linkmap is now consistent");
512		if (debug->state == RT_ADD) {
513			debug(2, "Adding DSO to linkmap");
514			//data.proc = proc;
515			crawl_linkmap(proc, &rdbg);
516			//&data);
517		} else if (debug->state == RT_DELETE) {
518			debug(2, "Removing DSO from linkmap");
519		} else {
520			debug(2, "Unexpected debug state!");
521		}
522	}
523
524	debug->state = rdbg.r_state;
525}
526
527int
528linkmap_init(struct Process *proc, target_address_t dyn_addr)
529{
530	debug(DEBUG_FUNCTION, "linkmap_init()");
531
532	struct debug_struct *debug = malloc(sizeof(*debug));
533	if (debug == NULL) {
534		error(0, errno, "couldn't allocate debug struct");
535	fail:
536		proc->debug = NULL;
537		free(debug);
538		return -1;
539	}
540	proc->debug = debug;
541
542	if (find_dynamic_entry_addr(proc, dyn_addr, DT_DEBUG,
543				    &debug->debug_addr) == -1) {
544		debug(2, "Couldn't find debug structure!");
545		goto fail;
546	}
547
548	int status;
549	struct lt_r_debug_64 rdbg;
550	if ((status = load_debug_struct(proc, &rdbg)) < 0) {
551		debug(2, "No debug structure or no memory to allocate one!");
552		return status;
553	}
554
555	target_address_t addr = (target_address_t)rdbg.r_brk;
556	if (arch_translate_address(proc, addr, &addr) < 0)
557		goto fail;
558
559	struct breakpoint *rdebug_bp = insert_breakpoint(proc, addr, NULL);
560	static struct bp_callbacks rdebug_callbacks = {
561		.on_hit = rdebug_bp_on_hit,
562	};
563	rdebug_bp->cbs = &rdebug_callbacks;
564
565	crawl_linkmap(proc, &rdbg);
566
567	return 0;
568}
569
570int
571task_kill (pid_t pid, int sig)
572{
573	// Taken from GDB
574        int ret;
575
576        errno = 0;
577        ret = syscall (__NR_tkill, pid, sig);
578	return ret;
579}
580