1 /* 2 * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 #include <stdarg.h> 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include <fcntl.h> 29 #ifdef INCLUDE_SA_ATTACH 30 #include <thread_db.h> 31 #else 32 #include <dirent.h> 33 #endif 34 #include "libproc_impl.h" 35 36 #define SA_ALTROOT "SA_ALTROOT" 37 38 int pathmap_open(const char* name) { 39 static const char *alt_root = NULL; 40 static int alt_root_initialized = 0; 41 42 int fd; 43 char alt_path[PATH_MAX + 1], *alt_path_end; 44 const char *s; 45 int free_space; 46 47 if (!alt_root_initialized) { 48 alt_root_initialized = -1; 49 alt_root = getenv(SA_ALTROOT); 50 } 51 52 if (alt_root == NULL) { 53 return open(name, O_RDONLY); 54 } 55 56 57 if (strlen(alt_root) + strlen(name) > PATH_MAX) { 58 // Buffer too small. 59 return -1; 60 } 61 62 strncpy(alt_path, alt_root, PATH_MAX); 63 alt_path[PATH_MAX] = '\0'; 64 alt_path_end = alt_path + strlen(alt_path); 65 free_space = PATH_MAX + 1 - (alt_path_end-alt_path); 66 67 // Strip path items one by one and try to open file with alt_root prepended. 68 s = name; 69 while (1) { 70 strncat(alt_path, s, free_space); 71 s += 1; // Skip /. 72 73 fd = open(alt_path, O_RDONLY); 74 if (fd >= 0) { 75 print_debug("path %s substituted for %s\n", alt_path, name); 76 return fd; 77 } 78 79 // Linker always put full path to solib to process, so we can rely 80 // on presence of /. If slash is not present, it means, that SOlib doesn't 81 // physically exist (e.g. linux-gate.so) and we fail opening it anyway 82 if ((s = strchr(s, '/')) == NULL) { 83 break; 84 } 85 86 // Cut off what we appended above. 87 *alt_path_end = '\0'; 88 } 89 90 return -1; 91 } 92 93 static bool _libsaproc_debug; 94 95 void print_debug(const char* format,...) { 96 if (_libsaproc_debug) { 97 va_list alist; 98 99 va_start(alist, format); 100 fputs("libsaproc DEBUG: ", stderr); 101 vfprintf(stderr, format, alist); 102 va_end(alist); 103 } 104 } 105 106 void print_error(const char* format,...) { 107 va_list alist; 108 va_start(alist, format); 109 fputs("ERROR: ", stderr); 110 vfprintf(stderr, format, alist); 111 va_end(alist); 112 } 113 114 bool is_debug() { 115 return _libsaproc_debug; 116 } 117 118 // initialize libproc 119 bool init_libproc(bool debug) { 120 // init debug mode 121 _libsaproc_debug = debug; 122 123 #ifdef INCLUDE_SA_ATTACH 124 // initialize the thread_db library 125 if (td_init() != TD_OK) { 126 print_debug("libthread_db's td_init failed\n"); 127 return false; 128 } 129 #endif 130 131 return true; 132 } 133 134 static void destroy_lib_info(struct ps_prochandle* ph) { 135 lib_info* lib = ph->libs; 136 while (lib) { 137 lib_info *next = lib->next; 138 if (lib->symtab) { 139 destroy_symtab(lib->symtab); 140 } 141 free(lib); 142 lib = next; 143 } 144 } 145 146 static void destroy_thread_info(struct ps_prochandle* ph) { 147 thread_info* thr = ph->threads; 148 while (thr) { 149 thread_info *next = thr->next; 150 free(thr); 151 thr = next; 152 } 153 } 154 155 // ps_prochandle cleanup 156 157 // ps_prochandle cleanup 158 void Prelease(struct ps_prochandle* ph) { 159 // do the "derived class" clean-up first 160 ph->ops->release(ph); 161 destroy_lib_info(ph); 162 destroy_thread_info(ph); 163 free(ph); 164 } 165 166 lib_info* add_lib_info(struct ps_prochandle* ph, const char* libname, uintptr_t base) { 167 return add_lib_info_fd(ph, libname, -1, base); 168 } 169 170 lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd, uintptr_t base) { 171 lib_info* newlib; 172 173 if ( (newlib = (lib_info*) calloc(1, sizeof(struct lib_info))) == NULL) { 174 print_debug("can't allocate memory for lib_info\n"); 175 return NULL; 176 } 177 178 if (strlen(libname) >= sizeof(newlib->name)) { 179 print_debug("libname %s too long\n", libname); 180 free(newlib); 181 return NULL; 182 } 183 strcpy(newlib->name, libname); 184 185 newlib->base = base; 186 187 if (fd == -1) { 188 if ( (newlib->fd = pathmap_open(newlib->name)) < 0) { 189 print_debug("can't open shared object %s\n", newlib->name); 190 free(newlib); 191 return NULL; 192 } 193 } else { 194 newlib->fd = fd; 195 } 196 197 // check whether we have got an ELF file. /proc/<pid>/map 198 // gives out all file mappings and not just shared objects 199 if (is_elf_file(newlib->fd) == false) { 200 close(newlib->fd); 201 free(newlib); 202 return NULL; 203 } 204 205 newlib->symtab = build_symtab(newlib->fd, libname); 206 if (newlib->symtab == NULL) { 207 print_debug("symbol table build failed for %s\n", newlib->name); 208 } 209 210 // even if symbol table building fails, we add the lib_info. 211 // This is because we may need to read from the ELF file for core file 212 // address read functionality. lookup_symbol checks for NULL symtab. 213 if (ph->libs) { 214 ph->lib_tail->next = newlib; 215 ph->lib_tail = newlib; 216 } else { 217 ph->libs = ph->lib_tail = newlib; 218 } 219 ph->num_libs++; 220 221 return newlib; 222 } 223 224 // lookup for a specific symbol 225 uintptr_t lookup_symbol(struct ps_prochandle* ph, const char* object_name, 226 const char* sym_name) { 227 // ignore object_name. search in all libraries 228 // FIXME: what should we do with object_name?? The library names are obtained 229 // by parsing /proc/<pid>/maps, which may not be the same as object_name. 230 // What we need is a utility to map object_name to real file name, something 231 // dlopen() does by looking at LD_LIBRARY_PATH and /etc/ld.so.cache. For 232 // now, we just ignore object_name and do a global search for the symbol. 233 234 lib_info* lib = ph->libs; 235 while (lib) { 236 if (lib->symtab) { 237 uintptr_t res = search_symbol(lib->symtab, lib->base, sym_name, NULL); 238 if (res) return res; 239 } 240 lib = lib->next; 241 } 242 243 print_debug("lookup failed for symbol '%s' in obj '%s'\n", 244 sym_name, object_name); 245 return (uintptr_t) NULL; 246 } 247 248 249 const char* symbol_for_pc(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* poffset) { 250 const char* res = NULL; 251 lib_info* lib = ph->libs; 252 while (lib) { 253 if (lib->symtab && addr >= lib->base) { 254 res = nearest_symbol(lib->symtab, addr - lib->base, poffset); 255 if (res) return res; 256 } 257 lib = lib->next; 258 } 259 return NULL; 260 } 261 262 // add a thread to ps_prochandle 263 thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id) { 264 thread_info* newthr; 265 if ( (newthr = (thread_info*) calloc(1, sizeof(thread_info))) == NULL) { 266 print_debug("can't allocate memory for thread_info\n"); 267 return NULL; 268 } 269 270 // initialize thread info 271 newthr->pthread_id = pthread_id; 272 newthr->lwp_id = lwp_id; 273 274 // add new thread to the list 275 newthr->next = ph->threads; 276 ph->threads = newthr; 277 ph->num_threads++; 278 return newthr; 279 } 280 281 282 #ifdef INCLUDE_SA_ATTACH 283 // struct used for client data from thread_db callback 284 struct thread_db_client_data { 285 struct ps_prochandle* ph; 286 thread_info_callback callback; 287 }; 288 289 // callback function for libthread_db 290 static int thread_db_callback(const td_thrhandle_t *th_p, void *data) { 291 struct thread_db_client_data* ptr = (struct thread_db_client_data*) data; 292 td_thrinfo_t ti; 293 td_err_e err; 294 295 memset(&ti, 0, sizeof(ti)); 296 err = td_thr_get_info(th_p, &ti); 297 if (err != TD_OK) { 298 print_debug("libthread_db : td_thr_get_info failed, can't get thread info\n"); 299 return err; 300 } 301 302 print_debug("thread_db : pthread %d (lwp %d)\n", ti.ti_tid, ti.ti_lid); 303 304 if (ptr->callback(ptr->ph, ti.ti_tid, ti.ti_lid) != true) 305 return TD_ERR; 306 307 return TD_OK; 308 } 309 #endif // INCLUDE_SA_ATTACH 310 311 // read thread_info using libthread_db or by iterating through the entries 312 // in /proc/<pid>/task/ 313 bool read_thread_info(struct ps_prochandle* ph, thread_info_callback cb) { 314 #ifdef INCLUDE_SA_ATTACH 315 struct thread_db_client_data mydata; 316 td_thragent_t* thread_agent = NULL; 317 if (td_ta_new(ph, &thread_agent) != TD_OK) { 318 print_debug("can't create libthread_db agent\n"); 319 return false; 320 } 321 322 mydata.ph = ph; 323 mydata.callback = cb; 324 325 // we use libthread_db iterator to iterate thru list of threads. 326 if (td_ta_thr_iter(thread_agent, thread_db_callback, &mydata, 327 TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY, 328 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS) != TD_OK) { 329 td_ta_delete(thread_agent); 330 return false; 331 } 332 333 // delete thread agent 334 td_ta_delete(thread_agent); 335 #else 336 DIR *dir = NULL; 337 struct dirent *ent = NULL; 338 char taskpath[80]; 339 pid_t pid = ph->pid; 340 341 // Find the lwpids to attach to by traversing the /proc/<pid>/task/ directory. 342 snprintf(taskpath, sizeof (taskpath), "/proc/%ld/task", (unsigned long)pid); 343 if ((dir = opendir(taskpath)) != NULL) { 344 while ((ent = readdir(dir)) != NULL) { 345 unsigned long lwp; 346 347 if ((lwp = strtoul(ent->d_name, NULL, 10)) != 0) { 348 // Create and add the thread info. 349 (*cb)(ph, 0, lwp); 350 } 351 } 352 } else { 353 print_debug("Could not open /proc/%ld/task.\n", (unsigned long)pid); 354 return false; 355 } 356 357 closedir(dir); 358 #endif 359 return true; 360 } 361 362 // get number of threads 363 int get_num_threads(struct ps_prochandle* ph) { 364 return ph->num_threads; 365 } 366 367 // get lwp_id of n'th thread 368 lwpid_t get_lwp_id(struct ps_prochandle* ph, int index) { 369 int count = 0; 370 thread_info* thr = ph->threads; 371 while (thr) { 372 if (count == index) { 373 return thr->lwp_id; 374 } 375 count++; 376 thr = thr->next; 377 } 378 return -1; 379 } 380 381 // get regs for a given lwp 382 bool get_lwp_regs(struct ps_prochandle* ph, lwpid_t lwp_id, struct user_regs_struct* regs) { 383 return ph->ops->get_lwp_regs(ph, lwp_id, regs); 384 } 385 386 // get number of shared objects 387 int get_num_libs(struct ps_prochandle* ph) { 388 return ph->num_libs; 389 } 390 391 // get name of n'th solib 392 const char* get_lib_name(struct ps_prochandle* ph, int index) { 393 int count = 0; 394 lib_info* lib = ph->libs; 395 while (lib) { 396 if (count == index) { 397 return lib->name; 398 } 399 count++; 400 lib = lib->next; 401 } 402 return NULL; 403 } 404 405 // get base address of a lib 406 uintptr_t get_lib_base(struct ps_prochandle* ph, int index) { 407 int count = 0; 408 lib_info* lib = ph->libs; 409 while (lib) { 410 if (count == index) { 411 return lib->base; 412 } 413 count++; 414 lib = lib->next; 415 } 416 return (uintptr_t)NULL; 417 } 418 419 bool find_lib(struct ps_prochandle* ph, const char *lib_name) { 420 lib_info *p = ph->libs; 421 while (p) { 422 if (strcmp(p->name, lib_name) == 0) { 423 return true; 424 } 425 p = p->next; 426 } 427 return false; 428 } 429 430 //-------------------------------------------------------------------------- 431 // proc service functions 432 433 // get process id 434 pid_t ps_getpid(struct ps_prochandle *ph) { 435 return ph->pid; 436 } 437 438 // ps_pglobal_lookup() looks up the symbol sym_name in the symbol table 439 // of the load object object_name in the target process identified by ph. 440 // It returns the symbol's value as an address in the target process in 441 // *sym_addr. 442 443 ps_err_e ps_pglobal_lookup(struct ps_prochandle *ph, const char *object_name, 444 const char *sym_name, psaddr_t *sym_addr) { 445 *sym_addr = (psaddr_t) lookup_symbol(ph, object_name, sym_name); 446 return (*sym_addr ? PS_OK : PS_NOSYM); 447 } 448 449 // read "size" bytes info "buf" from address "addr" 450 ps_err_e ps_pdread(struct ps_prochandle *ph, psaddr_t addr, 451 void *buf, size_t size) { 452 return ph->ops->p_pread(ph, (uintptr_t) addr, buf, size)? PS_OK: PS_ERR; 453 } 454 455 // write "size" bytes of data to debuggee at address "addr" 456 ps_err_e ps_pdwrite(struct ps_prochandle *ph, psaddr_t addr, 457 const void *buf, size_t size) { 458 return ph->ops->p_pwrite(ph, (uintptr_t)addr, buf, size)? PS_OK: PS_ERR; 459 } 460 461 // ------------------------------------------------------------------------ 462 // Functions below this point are not yet implemented. They are here only 463 // to make the linker happy. 464 465 ps_err_e ps_lsetfpregs(struct ps_prochandle *ph, lwpid_t lid, const prfpregset_t *fpregs) { 466 print_debug("ps_lsetfpregs not implemented\n"); 467 return PS_OK; 468 } 469 470 ps_err_e ps_lsetregs(struct ps_prochandle *ph, lwpid_t lid, const prgregset_t gregset) { 471 print_debug("ps_lsetregs not implemented\n"); 472 return PS_OK; 473 } 474 475 ps_err_e ps_lgetfpregs(struct ps_prochandle *ph, lwpid_t lid, prfpregset_t *fpregs) { 476 print_debug("ps_lgetfpregs not implemented\n"); 477 return PS_OK; 478 } 479 480 ps_err_e ps_lgetregs(struct ps_prochandle *ph, lwpid_t lid, prgregset_t gregset) { 481 print_debug("ps_lgetfpregs not implemented\n"); 482 return PS_OK; 483 } 484 485 // new libthread_db of NPTL seem to require this symbol 486 ps_err_e ps_get_thread_area() { 487 print_debug("ps_get_thread_area not implemented\n"); 488 return PS_OK; 489 }