diff options
Diffstat (limited to 'lib/libproc')
-rw-r--r-- | lib/libproc/Makefile | 12 | ||||
-rw-r--r-- | lib/libproc/Makefile.depend | 1 | ||||
-rw-r--r-- | lib/libproc/proc_bkpt.c | 3 | ||||
-rw-r--r-- | lib/libproc/proc_regs.c | 8 | ||||
-rw-r--r-- | lib/libproc/proc_sym.c | 42 | ||||
-rw-r--r-- | lib/libproc/tests/proc_test.c | 40 |
6 files changed, 89 insertions, 17 deletions
diff --git a/lib/libproc/Makefile b/lib/libproc/Makefile index bfb9492..3feddb5 100644 --- a/lib/libproc/Makefile +++ b/lib/libproc/Makefile @@ -16,20 +16,20 @@ INCS= libproc.h CFLAGS+= -I${.CURDIR} # avoid cyclic dependency CFLAGS+= -I${.CURDIR:H}/librtld_db +GENDIRDEPS_FILTER+= Nlib/librtld_db .if ${MK_CXX} == "no" CFLAGS+= -DNO_CXA_DEMANGLE .elif ${MK_LIBCPLUSPLUS} != "no" -LDADD+= -lcxxrt -DPADD+= ${LIBCXXRT} +LIBADD+= cxxrt .else -LDADD+= -lsupc++ -DPADD+= ${LIBSTDCPLUSPLUS} +LIBADD+= supcplusplus .endif +LIBADD+= elf rtld_db util + .if ${MK_CDDL} != "no" -LDADD+= -lctf -DPADD+= ${LIBCTF} +LIBADD+= ctf IGNORE_PRAGMA= YES CFLAGS+= -I${.CURDIR}/../../cddl/contrib/opensolaris/lib/libctf/common \ -I${.CURDIR}/../../sys/cddl/contrib/opensolaris/uts/common \ diff --git a/lib/libproc/Makefile.depend b/lib/libproc/Makefile.depend index 46c4714..9d42af4 100644 --- a/lib/libproc/Makefile.depend +++ b/lib/libproc/Makefile.depend @@ -3,6 +3,7 @@ DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,} DIRDEPS = \ + cddl/lib/libctf \ gnu/lib/csu \ gnu/lib/libgcc \ include \ diff --git a/lib/libproc/proc_bkpt.c b/lib/libproc/proc_bkpt.c index fe6ed4a..1e4a6cc 100644 --- a/lib/libproc/proc_bkpt.c +++ b/lib/libproc/proc_bkpt.c @@ -51,6 +51,9 @@ __FBSDID("$FreeBSD$"); #elif defined(__powerpc__) #define BREAKPOINT_INSTR 0x7fe00008 /* trap */ #define BREAKPOINT_INSTR_SZ 4 +#elif defined(__arm__) +#define BREAKPOINT_INSTR 0xe7ffffff /* bkpt */ +#define BREAKPOINT_INSTR_SZ 4 #else #error "Add support for your architecture" #endif diff --git a/lib/libproc/proc_regs.c b/lib/libproc/proc_regs.c index 145c8fe..35d8d38 100644 --- a/lib/libproc/proc_regs.c +++ b/lib/libproc/proc_regs.c @@ -56,6 +56,8 @@ proc_regget(struct proc_handle *phdl, proc_reg_t reg, unsigned long *regvalue) case REG_PC: #if defined(__amd64__) *regvalue = regs.r_rip; +#elif defined(__arm__) + *regvalue = regs.r_pc; #elif defined(__i386__) *regvalue = regs.r_eip; #elif defined(__mips__) @@ -67,6 +69,8 @@ proc_regget(struct proc_handle *phdl, proc_reg_t reg, unsigned long *regvalue) case REG_SP: #if defined(__amd64__) *regvalue = regs.r_rsp; +#elif defined(__arm__) + *regvalue = regs.r_sp; #elif defined(__i386__) *regvalue = regs.r_esp; #elif defined(__mips__) @@ -99,6 +103,8 @@ proc_regset(struct proc_handle *phdl, proc_reg_t reg, unsigned long regvalue) case REG_PC: #if defined(__amd64__) regs.r_rip = regvalue; +#elif defined(__arm__) + regs.r_pc = regvalue; #elif defined(__i386__) regs.r_eip = regvalue; #elif defined(__mips__) @@ -110,6 +116,8 @@ proc_regset(struct proc_handle *phdl, proc_reg_t reg, unsigned long regvalue) case REG_SP: #if defined(__amd64__) regs.r_rsp = regvalue; +#elif defined(__arm__) + regs.r_sp = regvalue; #elif defined(__i386__) regs.r_esp = regvalue; #elif defined(__mips__) diff --git a/lib/libproc/proc_sym.c b/lib/libproc/proc_sym.c index 766ff73..dd52638 100644 --- a/lib/libproc/proc_sym.c +++ b/lib/libproc/proc_sym.c @@ -82,6 +82,21 @@ fail: strlcpy(buf, symbol, len); } +static int +find_dbg_obj(const char *path) +{ + int fd; + char dbg_path[PATH_MAX]; + + snprintf(dbg_path, sizeof(dbg_path), + "/usr/lib/debug/%s.debug", path); + fd = open(dbg_path, O_RDONLY); + if (fd >= 0) + return (fd); + else + return (open(path, O_RDONLY)); +} + static void proc_rdl2prmap(rd_loadobj_t *rdl, prmap_t *map) { @@ -153,9 +168,12 @@ proc_iter_objs(struct proc_handle *p, proc_map_f *func, void *cd) prmap_t map; char path[MAXPATHLEN]; char last[MAXPATHLEN]; + int error; if (p->nobjs == 0) return (-1); + + error = 0; memset(last, 0, sizeof(last)); for (i = 0; i < p->nobjs; i++) { rdl = &p->rdobjs[i]; @@ -169,11 +187,11 @@ proc_iter_objs(struct proc_handle *p, proc_map_f *func, void *cd) */ if (strcmp(path, last) == 0) continue; - (*func)(cd, &map, path); + if ((error = (*func)(cd, &map, path)) != 0) + break; strlcpy(last, path, sizeof(last)); } - - return (0); + return (error); } prmap_t * @@ -292,7 +310,7 @@ proc_addr2sym(struct proc_handle *p, uintptr_t addr, char *name, if ((map = proc_addr2map(p, addr)) == NULL) return (-1); - if ((fd = open(map->pr_mapname, O_RDONLY, 0)) < 0) { + if ((fd = find_dbg_obj(map->pr_mapname)) < 0) { DPRINTF("ERROR: open %s failed", map->pr_mapname); goto err0; } @@ -335,8 +353,8 @@ proc_addr2sym(struct proc_handle *p, uintptr_t addr, char *name, goto out; error = lookup_addr(e, symtabscn, symtabstridx, off, addr, &s, symcopy); - if (error == 0) - goto out; + if (error != 0) + goto err2; out: demangle(s, name, namesz); @@ -440,7 +458,7 @@ proc_name2sym(struct proc_handle *p, const char *object, const char *symbol, DPRINTFX("ERROR: couldn't find object %s", object); goto err0; } - if ((fd = open(map->pr_mapname, O_RDONLY, 0)) < 0) { + if ((fd = find_dbg_obj(map->pr_mapname)) < 0) { DPRINTF("ERROR: open %s failed", map->pr_mapname); goto err0; } @@ -501,13 +519,16 @@ ctf_file_t * proc_name2ctf(struct proc_handle *p, const char *name) { #ifndef NO_CTF + ctf_file_t *ctf; prmap_t *map; int error; if ((map = proc_name2map(p, name)) == NULL) return (NULL); - return (ctf_open(map->pr_mapname, &error)); + ctf = ctf_open(map->pr_mapname, &error); + free(map); + return (ctf); #else (void)p; (void)name; @@ -533,7 +554,7 @@ proc_iter_symbyaddr(struct proc_handle *p, const char *object, int which, if ((map = proc_name2map(p, object)) == NULL) return (-1); - if ((fd = open(map->pr_mapname, O_RDONLY)) < 0) { + if ((fd = find_dbg_obj(map->pr_mapname)) < 0) { DPRINTF("ERROR: open %s failed", map->pr_mapname); goto err0; } @@ -596,7 +617,8 @@ proc_iter_symbyaddr(struct proc_handle *p, const char *object, int which, s = elf_strptr(e, stridx, sym.st_name); if (ehdr.e_type != ET_EXEC) sym.st_value += map->pr_vaddr; - (*func)(cd, &sym, s); + if ((error = (*func)(cd, &sym, s)) != 0) + goto err2; } error = 0; err2: diff --git a/lib/libproc/tests/proc_test.c b/lib/libproc/tests/proc_test.c index 0242b5b..dbaace8 100644 --- a/lib/libproc/tests/proc_test.c +++ b/lib/libproc/tests/proc_test.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2014 Mark Johnston <markj@FreeBSD.org> + * Copyright (c) 2014, 2015 Mark Johnston <markj@FreeBSD.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -295,6 +295,43 @@ ATF_TC_BODY(symbol_lookup, tc) proc_free(phdl); } +ATF_TC(symbol_lookup_fail); +ATF_TC_HEAD(symbol_lookup_fail, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Verify that proc_addr2sym() returns an error when given an offset " + "that it cannot resolve."); +} +ATF_TC_BODY(symbol_lookup_fail, tc) +{ + char symname[32]; + GElf_Sym sym; + struct proc_handle *phdl; + prmap_t *map; + int error; + + phdl = start_prog(tc, false); + + /* Initialize the rtld_db handle. */ + (void)proc_rdagent(phdl); + + map = proc_obj2map(phdl, target_prog_file); + ATF_REQUIRE_MSG(map != NULL, "failed to look up map for '%s'", + target_prog_file); + + /* + * We shouldn't be able to find symbols at the beginning of a mapped + * file. + */ + error = proc_addr2sym(phdl, map->pr_vaddr, symname, sizeof(symname), + &sym); + ATF_REQUIRE_MSG(error != 0, "unexpectedly found a symbol"); + + ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution"); + + proc_free(phdl); +} + ATF_TC(signal_forward); ATF_TC_HEAD(signal_forward, tc) { @@ -343,6 +380,7 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, map_alias_name2map); ATF_TP_ADD_TC(tp, map_alias_name2sym); ATF_TP_ADD_TC(tp, symbol_lookup); + ATF_TP_ADD_TC(tp, symbol_lookup_fail); ATF_TP_ADD_TC(tp, signal_forward); return (atf_no_error()); |