proc.c revision 6a7997de9eabf9b0c6e32309ca08870198eb864b
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	fprintf(stderr, "find_dynamic_entry_addr %d %p %d\n",
297		proc->pid, src_addr, d_tag);
298
299	debug(DEBUG_FUNCTION, "find_dynamic_entry()");
300
301	if (ret == NULL || src_addr == 0 || d_tag < 0 || d_tag > DT_NUM)
302		return -1;
303
304	int i = 0;
305	while (1) {
306		Elf64_Dyn entry;
307		if (dyn_fetcher(proc)(proc, &src_addr, &entry) < 0
308		    || entry.d_tag == DT_NULL
309		    || i++ > 100) { /* Arbitrary cut-off so that we
310				     * don't loop forever if the
311				     * binary is corrupted.  */
312			debug(2, "Couldn't find address for dtag!");
313			return -1;
314		}
315
316		if (entry.d_tag == d_tag) {
317			fprintf(stderr, "   hit\n");
318			*ret = (target_address_t)entry.d_un.d_val;
319			debug(2, "found address: %p in dtag %d\n", *ret, d_tag);
320			return 0;
321		}
322	}
323}
324
325/* Our own type for representing 32-bit linkmap.  We can't rely on the
326 * definition in link.h, because that's only accurate for our host
327 * architecture, not for target architecture (where the traced process
328 * runs). */
329#define LT_LINK_MAP(BITS)			\
330	{					\
331		Elf##BITS##_Addr l_addr;	\
332		Elf##BITS##_Addr l_name;	\
333		Elf##BITS##_Addr l_ld;		\
334		Elf##BITS##_Addr l_next;	\
335		Elf##BITS##_Addr l_prev;	\
336	}
337struct lt_link_map_32 LT_LINK_MAP(32);
338struct lt_link_map_64 LT_LINK_MAP(64);
339
340static int
341fetch_lm64(struct Process *proc, target_address_t addr,
342	   struct lt_link_map_64 *ret)
343{
344	if (umovebytes(proc, addr, ret, sizeof(*ret)) != sizeof(*ret))
345		return -1;
346	return 0;
347}
348
349static int
350fetch_lm32(struct Process *proc, target_address_t addr,
351	   struct lt_link_map_64 *ret)
352{
353	struct lt_link_map_32 lm;
354	if (umovebytes(proc, addr, &lm, sizeof(lm)) != sizeof(lm))
355		return -1;
356
357	ret->l_addr = lm.l_addr;
358	ret->l_name = lm.l_name;
359	ret->l_ld = lm.l_ld;
360	ret->l_next = lm.l_next;
361	ret->l_prev = lm.l_prev;
362
363	return 0;
364}
365
366static int (*
367lm_fetcher(struct Process *proc))(struct Process *,
368				  target_address_t, struct lt_link_map_64 *)
369{
370	return select_32_64(proc, fetch_lm32, fetch_lm64);
371}
372
373/* The same as above holds for struct r_debug.  */
374#define LT_R_DEBUG(BITS)			\
375	{					\
376		int r_version;			\
377		Elf##BITS##_Addr r_map;		\
378		Elf##BITS##_Addr r_brk;		\
379		int r_state;			\
380		Elf##BITS##_Addr r_ldbase;	\
381	}
382
383struct lt_r_debug_32 LT_R_DEBUG(32);
384struct lt_r_debug_64 LT_R_DEBUG(64);
385
386static int
387fetch_rd64(struct Process *proc, target_address_t addr,
388	   struct lt_r_debug_64 *ret)
389{
390	if (umovebytes(proc, addr, ret, sizeof(*ret)) != sizeof(*ret))
391		return -1;
392	return 0;
393}
394
395static int
396fetch_rd32(struct Process *proc, target_address_t addr,
397	   struct lt_r_debug_64 *ret)
398{
399	struct lt_r_debug_32 rd;
400	if (umovebytes(proc, addr, &rd, sizeof(rd)) != sizeof(rd))
401		return -1;
402
403	ret->r_version = rd.r_version;
404	ret->r_map = rd.r_map;
405	ret->r_brk = rd.r_brk;
406	ret->r_state = rd.r_state;
407	ret->r_ldbase = rd.r_ldbase;
408
409	return 0;
410}
411
412static int (*
413rdebug_fetcher(struct Process *proc))(struct Process *,
414				      target_address_t, struct lt_r_debug_64 *)
415{
416	return select_32_64(proc, fetch_rd32, fetch_rd64);
417}
418
419enum callback_status
420find_library_addr(struct Process *proc, struct library *lib, void *data)
421{
422	target_address_t addr = (target_address_t)*(GElf_Addr *)data;
423	return lib->base == addr ? CBS_STOP : CBS_CONT;
424}
425
426static void
427crawl_linkmap(struct Process *proc, struct lt_r_debug_64 *dbg)
428{
429	debug (DEBUG_FUNCTION, "crawl_linkmap()");
430
431	if (!dbg || !dbg->r_map) {
432		debug(2, "Debug structure or it's linkmap are NULL!");
433		return;
434	}
435
436	target_address_t addr = (target_address_t)dbg->r_map;
437
438	while (addr != 0) {
439		struct lt_link_map_64 rlm;
440		if (lm_fetcher(proc)(proc, addr, &rlm) < 0) {
441			debug(2, "Unable to read link map\n");
442			return;
443		}
444
445		addr = (target_address_t)rlm.l_next;
446		if (rlm.l_name == 0) {
447			debug(2, "Invalid library name referenced in dynamic linker map\n");
448			return;
449		}
450
451		char lib_name[BUFSIZ];
452		umovebytes(proc, (target_address_t)rlm.l_name,
453			   lib_name, sizeof(lib_name));
454
455		debug(2, "Dispatching callback for: %s, "
456		      "Loaded at 0x%" PRI_ELF_ADDR "\n",
457		      lib_name, rlm.l_addr);
458		fprintf(stderr, "DSO addr=%#lx, name='%s'\n", rlm.l_addr, lib_name);
459
460		/* Do we have that library already?  */
461		struct library *lib
462			= proc_each_library(proc, NULL, find_library_addr,
463					    &rlm.l_addr);
464		if (lib != NULL)
465			continue;
466
467		if (*lib_name == '\0') {
468			/* VDSO.  No associated file, XXX but we might
469			 * load it from the address space of the
470			 * process.  */
471			continue;
472		}
473
474		lib = ltelf_read_library(proc, lib_name, rlm.l_addr);
475		if (lib == NULL) {
476			error(0, errno, "Couldn't load ELF object %s\n",
477			      lib_name);
478			continue;
479		}
480
481		proc_add_library(proc, lib);
482	}
483	return;
484}
485
486static int
487load_debug_struct(struct Process *proc, struct lt_r_debug_64 *ret)
488{
489	debug(DEBUG_FUNCTION, "load_debug_struct");
490
491	if (rdebug_fetcher(proc)(proc, proc->debug, ret) < 0) {
492		debug(2, "This process does not have a debug structure!\n");
493		return -1;
494	}
495
496	return 0;
497}
498
499static void
500rdebug_bp_on_hit(struct breakpoint *bp, struct Process *proc)
501{
502	fprintf(stderr, "======= HIT\n");
503
504	debug(DEBUG_FUNCTION, "arch_check_dbg");
505
506	struct lt_r_debug_64 rdbg;
507	if (load_debug_struct(proc, &rdbg) < 0) {
508		debug(2, "Unable to load debug structure!");
509		return;
510	}
511
512	if (rdbg.r_state == RT_CONSISTENT) {
513		debug(2, "Linkmap is now consistent");
514		if (proc->debug_state == RT_ADD) {
515			debug(2, "Adding DSO to linkmap");
516			//data.proc = proc;
517			crawl_linkmap(proc, &rdbg);
518			//&data);
519		} else if (proc->debug_state == RT_DELETE) {
520			debug(2, "Removing DSO from linkmap");
521		} else {
522			debug(2, "Unexpected debug state!");
523		}
524	}
525
526	proc->debug_state = rdbg.r_state;
527}
528
529int
530linkmap_init(struct Process *proc, target_address_t dyn_addr)
531{
532	target_address_t dbg_addr = NULL;
533	//struct cb_data data;
534
535	debug(DEBUG_FUNCTION, "linkmap_init()");
536	fprintf(stderr, "linkmap_init dyn_addr=%p\n", dyn_addr);
537
538	if (find_dynamic_entry_addr(proc, dyn_addr, DT_DEBUG, &dbg_addr) == -1) {
539		debug(2, "Couldn't find debug structure!");
540		return -1;
541	}
542
543	proc->debug = dbg_addr;
544
545	int status;
546	struct lt_r_debug_64 rdbg;
547	if ((status = load_debug_struct(proc, &rdbg)) < 0) {
548		debug(2, "No debug structure or no memory to allocate one!");
549		return status;
550	}
551
552	//data.lte = lte;
553
554	void *addr;
555	{
556		struct library_symbol libsym;
557		library_symbol_init(&libsym, (target_address_t)rdbg.r_brk,
558				    NULL, 0, LS_TOPLT_NONE);
559		addr = sym2addr(proc, &libsym);
560		library_symbol_destroy(&libsym);
561	}
562	struct breakpoint *rdebug_bp = insert_breakpoint(proc, addr, NULL);
563	static struct bp_callbacks rdebug_callbacks = {
564		.on_hit = rdebug_bp_on_hit,
565	};
566	rdebug_bp->cbs = &rdebug_callbacks;
567
568	crawl_linkmap(proc, &rdbg);
569
570	return 0;
571}
572
573int
574task_kill (pid_t pid, int sig)
575{
576	// Taken from GDB
577        int ret;
578
579        errno = 0;
580        ret = syscall (__NR_tkill, pid, sig);
581	return ret;
582}
583