ltrace-elf.c revision 40cc53b8a944aabfd42e64bf71815252652d7f77
1#include "config.h" 2 3#include <assert.h> 4#include <endian.h> 5#include <errno.h> 6#include <error.h> 7#include <fcntl.h> 8#include <gelf.h> 9#include <inttypes.h> 10#include <search.h> 11#include <stdint.h> 12#include <stdlib.h> 13#include <string.h> 14#include <unistd.h> 15 16#include "common.h" 17#include "proc.h" 18#include "library.h" 19#include "filter.h" 20 21#ifdef PLT_REINITALISATION_BP 22extern char *PLTs_initialized_by_here; 23#endif 24 25#ifndef DT_PPC_GOT 26# define DT_PPC_GOT (DT_LOPROC + 0) 27#endif 28 29 30#ifndef ARCH_HAVE_LTELF_DATA 31int 32arch_elf_init(struct ltelf *lte) 33{ 34 return 0; 35} 36 37void 38arch_elf_destroy(struct ltelf *lte) 39{ 40} 41#endif 42 43int 44default_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, 45 const char *a_name, GElf_Rela *rela, size_t ndx, 46 struct library_symbol **ret) 47{ 48 char *name = strdup(a_name); 49 if (name == NULL) { 50 fail: 51 free(name); 52 return -1; 53 } 54 55 GElf_Addr addr = arch_plt_sym_val(lte, ndx, rela); 56 57 struct library_symbol *libsym = malloc(sizeof(*libsym)); 58 if (libsym == NULL) 59 goto fail; 60 61 target_address_t taddr = (target_address_t)(addr + lte->bias); 62 63 library_symbol_init(libsym, taddr, name, 1, LS_TOPLT_EXEC); 64 *ret = libsym; 65 return 0; 66} 67 68#ifndef ARCH_HAVE_ADD_PLT_ENTRY 69enum plt_status 70arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, 71 const char *a_name, GElf_Rela *rela, size_t ndx, 72 struct library_symbol **ret) 73{ 74 return plt_default; 75} 76#endif 77 78Elf_Data * 79elf_loaddata(Elf_Scn *scn, GElf_Shdr *shdr) 80{ 81 Elf_Data *data = elf_getdata(scn, NULL); 82 if (data == NULL || elf_getdata(scn, data) != NULL 83 || data->d_off || data->d_size != shdr->sh_size) 84 return NULL; 85 return data; 86} 87 88static int 89elf_get_section_if(struct ltelf *lte, Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr, 90 int (*predicate)(Elf_Scn *, GElf_Shdr *, void *data), 91 void *data) 92{ 93 int i; 94 for (i = 1; i < lte->ehdr.e_shnum; ++i) { 95 Elf_Scn *scn; 96 GElf_Shdr shdr; 97 98 scn = elf_getscn(lte->elf, i); 99 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) { 100 debug(1, "Couldn't read section or header."); 101 return -1; 102 } 103 if (predicate(scn, &shdr, data)) { 104 *tgt_sec = scn; 105 *tgt_shdr = shdr; 106 return 0; 107 } 108 } 109 return -1; 110 111} 112 113static int 114inside_p(Elf_Scn *scn, GElf_Shdr *shdr, void *data) 115{ 116 GElf_Addr addr = *(GElf_Addr *)data; 117 return addr >= shdr->sh_addr 118 && addr < shdr->sh_addr + shdr->sh_size; 119} 120 121int 122elf_get_section_covering(struct ltelf *lte, GElf_Addr addr, 123 Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr) 124{ 125 return elf_get_section_if(lte, tgt_sec, tgt_shdr, 126 &inside_p, &addr); 127} 128 129static int 130type_p(Elf_Scn *scn, GElf_Shdr *shdr, void *data) 131{ 132 GElf_Word type = *(GElf_Word *)data; 133 return shdr->sh_type == type; 134} 135 136int 137elf_get_section_type(struct ltelf *lte, GElf_Word type, 138 Elf_Scn **tgt_sec, GElf_Shdr *tgt_shdr) 139{ 140 return elf_get_section_if(lte, tgt_sec, tgt_shdr, 141 &type_p, &type); 142} 143 144static int 145need_data(Elf_Data *data, size_t offset, size_t size) 146{ 147 assert(data != NULL); 148 if (data->d_size < size || offset > data->d_size - size) { 149 debug(1, "Not enough data to read %zd-byte value" 150 " at offset %zd.", size, offset); 151 return -1; 152 } 153 return 0; 154} 155 156#define DEF_READER(NAME, SIZE) \ 157 int \ 158 NAME(Elf_Data *data, size_t offset, uint##SIZE##_t *retp) \ 159 { \ 160 if (!need_data(data, offset, SIZE / 8) < 0) \ 161 return -1; \ 162 \ 163 if (data->d_buf == NULL) /* NODATA section */ { \ 164 *retp = 0; \ 165 return 0; \ 166 } \ 167 \ 168 union { \ 169 uint##SIZE##_t dst; \ 170 char buf[0]; \ 171 } u; \ 172 memcpy(u.buf, data->d_buf + offset, sizeof(u.dst)); \ 173 *retp = u.dst; \ 174 return 0; \ 175 } 176 177DEF_READER(elf_read_u16, 16) 178DEF_READER(elf_read_u32, 32) 179DEF_READER(elf_read_u64, 64) 180 181#undef DEF_READER 182 183int 184open_elf(struct ltelf *lte, const char *filename) 185{ 186 lte->fd = open(filename, O_RDONLY); 187 if (lte->fd == -1) 188 return 1; 189 190 elf_version(EV_CURRENT); 191 192#ifdef HAVE_ELF_C_READ_MMAP 193 lte->elf = elf_begin(lte->fd, ELF_C_READ_MMAP, NULL); 194#else 195 lte->elf = elf_begin(lte->fd, ELF_C_READ, NULL); 196#endif 197 198 if (lte->elf == NULL || elf_kind(lte->elf) != ELF_K_ELF) 199 error(EXIT_FAILURE, 0, "Can't open ELF file \"%s\"", filename); 200 201 if (gelf_getehdr(lte->elf, <e->ehdr) == NULL) 202 error(EXIT_FAILURE, 0, "Can't read ELF header of \"%s\"", 203 filename); 204 205 if (lte->ehdr.e_type != ET_EXEC && lte->ehdr.e_type != ET_DYN) 206 error(EXIT_FAILURE, 0, 207 "\"%s\" is not an ELF executable nor shared library", 208 filename); 209 210 if ((lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS 211 || lte->ehdr.e_machine != LT_ELF_MACHINE) 212#ifdef LT_ELF_MACHINE2 213 && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS2 214 || lte->ehdr.e_machine != LT_ELF_MACHINE2) 215#endif 216#ifdef LT_ELF_MACHINE3 217 && (lte->ehdr.e_ident[EI_CLASS] != LT_ELFCLASS3 218 || lte->ehdr.e_machine != LT_ELF_MACHINE3) 219#endif 220 ) 221 error(EXIT_FAILURE, 0, 222 "\"%s\" is ELF from incompatible architecture", filename); 223 224 return 0; 225} 226 227static int 228do_init_elf(struct ltelf *lte, const char *filename, GElf_Addr bias) 229{ 230 int i; 231 GElf_Addr relplt_addr = 0; 232 GElf_Addr soname_offset = 0; 233 234 debug(DEBUG_FUNCTION, "do_init_elf(filename=%s)", filename); 235 debug(1, "Reading ELF from %s...", filename); 236 237 if (open_elf(lte, filename) < 0) 238 return -1; 239 240 /* Find out the base address. */ 241 { 242 GElf_Phdr phdr; 243 for (i = 0; gelf_getphdr (lte->elf, i, &phdr) != NULL; ++i) { 244 if (phdr.p_type == PT_LOAD) { 245 lte->base_addr = phdr.p_vaddr + bias; 246 break; 247 } 248 } 249 } 250 251 if (lte->base_addr == 0) { 252 fprintf(stderr, "Couldn't determine base address of %s\n", 253 filename); 254 return -1; 255 } 256 257 lte->bias = bias; 258 lte->entry_addr = lte->ehdr.e_entry + lte->bias; 259 260 for (i = 1; i < lte->ehdr.e_shnum; ++i) { 261 Elf_Scn *scn; 262 GElf_Shdr shdr; 263 const char *name; 264 265 scn = elf_getscn(lte->elf, i); 266 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) 267 error(EXIT_FAILURE, 0, 268 "Couldn't get section header from \"%s\"", 269 filename); 270 271 name = elf_strptr(lte->elf, lte->ehdr.e_shstrndx, shdr.sh_name); 272 if (name == NULL) 273 error(EXIT_FAILURE, 0, 274 "Couldn't get section header from \"%s\"", 275 filename); 276 277 if (shdr.sh_type == SHT_SYMTAB) { 278 Elf_Data *data; 279 280 lte->symtab = elf_getdata(scn, NULL); 281 lte->symtab_count = shdr.sh_size / shdr.sh_entsize; 282 if ((lte->symtab == NULL 283 || elf_getdata(scn, lte->symtab) != NULL) 284 && options.static_filter != NULL) 285 error(EXIT_FAILURE, 0, 286 "Couldn't get .symtab data from \"%s\"", 287 filename); 288 289 scn = elf_getscn(lte->elf, shdr.sh_link); 290 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) 291 error(EXIT_FAILURE, 0, 292 "Couldn't get section header from \"%s\"", 293 filename); 294 295 data = elf_getdata(scn, NULL); 296 if (data == NULL || elf_getdata(scn, data) != NULL 297 || shdr.sh_size != data->d_size || data->d_off) 298 error(EXIT_FAILURE, 0, 299 "Couldn't get .strtab data from \"%s\"", 300 filename); 301 302 lte->strtab = data->d_buf; 303 } else if (shdr.sh_type == SHT_DYNSYM) { 304 Elf_Data *data; 305 306 lte->dynsym = elf_getdata(scn, NULL); 307 lte->dynsym_count = shdr.sh_size / shdr.sh_entsize; 308 if (lte->dynsym == NULL 309 || elf_getdata(scn, lte->dynsym) != NULL) 310 error(EXIT_FAILURE, 0, 311 "Couldn't get .dynsym data from \"%s\"", 312 filename); 313 314 scn = elf_getscn(lte->elf, shdr.sh_link); 315 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) 316 error(EXIT_FAILURE, 0, 317 "Couldn't get section header from \"%s\"", 318 filename); 319 320 data = elf_getdata(scn, NULL); 321 if (data == NULL || elf_getdata(scn, data) != NULL 322 || shdr.sh_size != data->d_size || data->d_off) 323 error(EXIT_FAILURE, 0, 324 "Couldn't get .dynstr data from \"%s\"", 325 filename); 326 327 lte->dynstr = data->d_buf; 328 } else if (shdr.sh_type == SHT_DYNAMIC) { 329 Elf_Data *data; 330 size_t j; 331 332 lte->dyn_addr = shdr.sh_addr; 333 lte->dyn_sz = shdr.sh_size; 334 335 data = elf_getdata(scn, NULL); 336 if (data == NULL || elf_getdata(scn, data) != NULL) 337 error(EXIT_FAILURE, 0, 338 "Couldn't get .dynamic data from \"%s\"", 339 filename); 340 341 for (j = 0; j < shdr.sh_size / shdr.sh_entsize; ++j) { 342 GElf_Dyn dyn; 343 344 if (gelf_getdyn(data, j, &dyn) == NULL) 345 error(EXIT_FAILURE, 0, 346 "Couldn't get .dynamic data from \"%s\"", 347 filename); 348 if (dyn.d_tag == DT_JMPREL) 349 relplt_addr = dyn.d_un.d_ptr; 350 else if (dyn.d_tag == DT_PLTRELSZ) 351 lte->relplt_size = dyn.d_un.d_val; 352 else if (dyn.d_tag == DT_SONAME) 353 soname_offset = dyn.d_un.d_val; 354 } 355 } else if (shdr.sh_type == SHT_PROGBITS 356 || shdr.sh_type == SHT_NOBITS) { 357 if (strcmp(name, ".plt") == 0) { 358 lte->plt_addr = shdr.sh_addr; 359 lte->plt_size = shdr.sh_size; 360 lte->plt_data = elf_loaddata(scn, &shdr); 361 if (lte->plt_data == NULL) 362 fprintf(stderr, 363 "Can't load .plt data\n"); 364 lte->plt_flags = shdr.sh_flags; 365 } 366#ifdef ARCH_SUPPORTS_OPD 367 else if (strcmp(name, ".opd") == 0) { 368 lte->opd_addr = (GElf_Addr *) (long) shdr.sh_addr; 369 lte->opd_size = shdr.sh_size; 370 lte->opd = elf_rawdata(scn, NULL); 371 } 372#endif 373 } 374 } 375 376 if (lte->dynsym == NULL || lte->dynstr == NULL) 377 error(EXIT_FAILURE, 0, 378 "Couldn't find .dynsym or .dynstr in \"%s\"", filename); 379 380 if (!relplt_addr || !lte->plt_addr) { 381 debug(1, "%s has no PLT relocations", filename); 382 lte->relplt = NULL; 383 lte->relplt_count = 0; 384 } else if (lte->relplt_size == 0) { 385 debug(1, "%s has unknown PLT size", filename); 386 lte->relplt = NULL; 387 lte->relplt_count = 0; 388 } else { 389 390 for (i = 1; i < lte->ehdr.e_shnum; ++i) { 391 Elf_Scn *scn; 392 GElf_Shdr shdr; 393 394 scn = elf_getscn(lte->elf, i); 395 if (scn == NULL || gelf_getshdr(scn, &shdr) == NULL) 396 error(EXIT_FAILURE, 0, 397 "Couldn't get section header from \"%s\"", 398 filename); 399 if (shdr.sh_addr == relplt_addr 400 && shdr.sh_size == lte->relplt_size) { 401 lte->relplt = elf_getdata(scn, NULL); 402 lte->relplt_count = 403 shdr.sh_size / shdr.sh_entsize; 404 if (lte->relplt == NULL 405 || elf_getdata(scn, lte->relplt) != NULL) 406 error(EXIT_FAILURE, 0, 407 "Couldn't get .rel*.plt data from \"%s\"", 408 filename); 409 break; 410 } 411 } 412 413 if (i == lte->ehdr.e_shnum) 414 error(EXIT_FAILURE, 0, 415 "Couldn't find .rel*.plt section in \"%s\"", 416 filename); 417 418 debug(1, "%s %zd PLT relocations", filename, lte->relplt_count); 419 } 420 421 if (soname_offset != 0) 422 lte->soname = lte->dynstr + soname_offset; 423 424 if (arch_elf_init(lte) < 0) { 425 fprintf(stderr, "Backend initialization failed.\n"); 426 return -1; 427 } 428 429 return 0; 430} 431 432/* XXX temporarily non-static */ 433void 434do_close_elf(struct ltelf *lte) { 435 debug(DEBUG_FUNCTION, "do_close_elf()"); 436 arch_elf_destroy(lte); 437 elf_end(lte->elf); 438 close(lte->fd); 439} 440 441static int 442populate_plt(struct Process *proc, const char *filename, 443 struct ltelf *lte, struct library *lib) 444{ 445 size_t i; 446 for (i = 0; i < lte->relplt_count; ++i) { 447 GElf_Rel rel; 448 GElf_Rela rela; 449 GElf_Sym sym; 450 void *ret; 451 452 if (lte->relplt->d_type == ELF_T_REL) { 453 ret = gelf_getrel(lte->relplt, i, &rel); 454 rela.r_offset = rel.r_offset; 455 rela.r_info = rel.r_info; 456 rela.r_addend = 0; 457 } else { 458 ret = gelf_getrela(lte->relplt, i, &rela); 459 } 460 461 if (ret == NULL 462 || ELF64_R_SYM(rela.r_info) >= lte->dynsym_count 463 || gelf_getsym(lte->dynsym, ELF64_R_SYM(rela.r_info), 464 &sym) == NULL) 465 error(EXIT_FAILURE, 0, 466 "Couldn't get relocation from \"%s\"", 467 filename); 468 469 char const *name = lte->dynstr + sym.st_name; 470 471 if (!filter_matches_symbol(options.plt_filter, name, lib)) 472 continue; 473 474 struct library_symbol *libsym; 475 switch (arch_elf_add_plt_entry(proc, lte, name, 476 &rela, i, &libsym)) { 477 case plt_default: 478 if (default_elf_add_plt_entry(proc, lte, name, 479 &rela, i, &libsym) < 0) 480 case plt_fail: 481 return -1; 482 case plt_ok: 483 if (libsym != NULL) 484 library_add_symbol(lib, libsym); 485 } 486 } 487 return 0; 488} 489 490/* When -x rules result in request to trace several aliases, we only 491 * want to add such symbol once. The only way that those symbols 492 * differ in is their name, e.g. in glibc you have __GI___libc_free, 493 * __cfree, __free, __libc_free, cfree and free all defined on the 494 * same address. So instead we keep this unique symbol struct for 495 * each address, and replace name in libsym with a shorter variant if 496 * we find it. */ 497struct unique_symbol { 498 target_address_t addr; 499 struct library_symbol *libsym; 500}; 501 502static int 503unique_symbol_cmp(const void *key, const void *val) 504{ 505 const struct unique_symbol *sym_key = key; 506 const struct unique_symbol *sym_val = val; 507 return sym_key->addr != sym_val->addr; 508} 509 510static int 511populate_this_symtab(struct Process *proc, const char *filename, 512 struct ltelf *lte, struct library *lib, 513 Elf_Data *symtab, const char *strtab, size_t size) 514{ 515 /* Using sorted array would be arguably better, but this 516 * should be well enough for the number of symbols that we 517 * typically deal with. */ 518 size_t num_symbols = 0; 519 struct unique_symbol *symbols = malloc(sizeof(*symbols) * size); 520 if (symbols == NULL) { 521 error(0, errno, "couldn't insert symbols for -x"); 522 return -1; 523 } 524 525 GElf_Word secflags[lte->ehdr.e_shnum]; 526 size_t i; 527 for (i = 1; i < lte->ehdr.e_shnum; ++i) { 528 Elf_Scn *scn = elf_getscn(lte->elf, i); 529 if (scn == NULL) 530 continue; 531 GElf_Shdr shdr; 532 if (gelf_getshdr(scn, &shdr) == NULL) 533 continue; 534 secflags[i] = shdr.sh_flags; 535 } 536 537 size_t lib_len = strlen(lib->soname); 538 for (i = 0; i < size; ++i) { 539 GElf_Sym sym; 540 if (gelf_getsym(symtab, i, &sym) == NULL) { 541 fail: 542 error(0, errno, "couldn't get symbol #%zd from %s: %s", 543 i, filename, elf_errmsg(-1)); 544 continue; 545 } 546 547 /* XXX support IFUNC as well. */ 548 if (GELF_ST_TYPE(sym.st_info) != STT_FUNC 549 || sym.st_value == 0) 550 continue; 551 552 const char *name = strtab + sym.st_name; 553 if (!filter_matches_symbol(options.static_filter, name, lib)) 554 continue; 555 556 target_address_t addr 557 = (target_address_t)(sym.st_value + lte->bias); 558 target_address_t naddr; 559 560 /* On arches that support OPD, the value of typical 561 * function symbol will be a pointer to .opd, but some 562 * will point directly to .text. We don't want to 563 * translate those. */ 564 if (secflags[sym.st_shndx] & SHF_EXECINSTR) { 565 naddr = addr; 566 } else if (arch_translate_address(proc, addr, &naddr) < 0) { 567 error(0, errno, "couldn't translate address of %s@%s", 568 name, lib->soname); 569 continue; 570 } 571 572 /* If the translation actually took place, and wasn't 573 * a no-op, then bias again. XXX We shouldn't apply 574 * second bias for libraries that were open at the 575 * time that we attached. In fact what we should do 576 * is look at each translated address, whether it 577 * falls into a SHF_EXECINSTR section. If it does, 578 * it's most likely already translated. */ 579 if (addr != naddr) 580 naddr += lte->bias; 581 582 char *full_name; 583 if (lib->type != LT_LIBTYPE_MAIN) { 584 full_name = malloc(strlen(name) + 1 + lib_len + 1); 585 if (full_name == NULL) 586 goto fail; 587 sprintf(full_name, "%s@%s", name, lib->soname); 588 } else { 589 full_name = strdup(name); 590 if (full_name == NULL) 591 goto fail; 592 } 593 594 /* Look whether we already have a symbol for this 595 * address. If not, add this one. */ 596 struct unique_symbol key = { naddr, NULL }; 597 struct unique_symbol *unique 598 = lsearch(&key, symbols, &num_symbols, 599 sizeof(*symbols), &unique_symbol_cmp); 600 601 if (unique->libsym == NULL) { 602 struct library_symbol *libsym = malloc(sizeof(*libsym)); 603 if (libsym == NULL) { 604 --num_symbols; 605 goto fail; 606 } 607 library_symbol_init(libsym, naddr, full_name, 608 1, LS_TOPLT_NONE); 609 unique->libsym = libsym; 610 unique->addr = naddr; 611 612 } else if (strlen(full_name) < strlen(unique->libsym->name)) { 613 library_symbol_set_name(unique->libsym, full_name, 1); 614 615 } else { 616 free(full_name); 617 } 618 } 619 620 for (i = 0; i < num_symbols; ++i) { 621 assert(symbols[i].libsym != NULL); 622 library_add_symbol(lib, symbols[i].libsym); 623 } 624 625 free(symbols); 626 627 return 0; 628} 629 630static int 631populate_symtab(struct Process *proc, const char *filename, 632 struct ltelf *lte, struct library *lib) 633{ 634 if (lte->symtab != NULL && lte->strtab != NULL) 635 return populate_this_symtab(proc, filename, lte, lib, 636 lte->symtab, lte->strtab, 637 lte->symtab_count); 638 else 639 return populate_this_symtab(proc, filename, lte, lib, 640 lte->dynsym, lte->dynstr, 641 lte->dynsym_count); 642} 643 644int 645ltelf_read_library(struct library *lib, struct Process *proc, 646 const char *filename, GElf_Addr bias) 647{ 648 struct ltelf lte = {}; 649 if (do_init_elf(<e, filename, bias) < 0) 650 return -1; 651 proc->e_machine = lte.ehdr.e_machine; 652 653 int status = 0; 654 if (lib == NULL) 655 goto fail; 656 657 /* Note that we set soname and pathname as soon as they are 658 * allocated, so in case of further errors, this get released 659 * when LIB is release, which should happen in the caller when 660 * we return error. */ 661 662 if (lib->pathname == NULL) { 663 char *pathname = strdup(filename); 664 if (pathname == NULL) 665 goto fail; 666 library_set_pathname(lib, filename, 1); 667 } 668 669 if (lte.soname != NULL) { 670 char *soname = strdup(lte.soname); 671 if (soname == NULL) 672 goto fail; 673 library_set_soname(lib, soname, 1); 674 } else { 675 const char *soname = rindex(lib->pathname, '/') + 1; 676 if (soname == NULL) 677 soname = lib->pathname; 678 library_set_soname(lib, soname, 0); 679 } 680 681 target_address_t entry = (target_address_t)lte.entry_addr; 682 if (arch_translate_address(proc, entry, &entry) < 0) 683 goto fail; 684 685 lib->base = (target_address_t)lte.base_addr; 686 lib->entry = entry; 687 lib->dyn_addr = (target_address_t)lte.dyn_addr; 688 689 if (filter_matches_library(options.plt_filter, lib) 690 && populate_plt(proc, filename, <e, lib) < 0) 691 goto fail; 692 693 if (filter_matches_library(options.static_filter, lib) 694 && populate_symtab(proc, filename, <e, lib) < 0) 695 goto fail; 696 697done: 698 do_close_elf(<e); 699 return status; 700 701fail: 702 status = -1; 703 goto done; 704} 705 706struct library * 707ltelf_read_main_binary(struct Process *proc, const char *path) 708{ 709 struct library *lib = malloc(sizeof(*lib)); 710 if (lib == NULL) 711 return NULL; 712 library_init(lib, LT_LIBTYPE_MAIN); 713 library_set_pathname(lib, path, 0); 714 715 /* There is a race between running the process and reading its 716 * binary for internal consumption. So open the binary from 717 * the /proc filesystem. XXX Note that there is similar race 718 * for libraries, but there we don't have a nice answer like 719 * that. Presumably we could read the DSOs from the process 720 * memory image, but that's not currently done. */ 721 char *fname = pid2name(proc->pid); 722 if (ltelf_read_library(lib, proc, fname, 0) < 0) { 723 library_destroy(lib); 724 free(lib); 725 return NULL; 726 } 727 728 return lib; 729} 730