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_name2map(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_BODY(map_prefix_name2map, tc) { struct proc_handle *phdl; prmap_t *map1, *map2; phdl = start_prog(tc, false); /* Initialize the rtld_db handle. */ (void)proc_rdagent(phdl); /* Make sure that "ld-elf" and "ld-elf.so" return the same map. */ map1 = proc_name2map(phdl, "ld-elf"); ATF_REQUIRE_MSG(map1 != NULL, "failed to look up map for 'ld-elf'"); map2 = proc_name2map(phdl, "ld-elf.so"); ATF_REQUIRE_MSG(map2 != NULL, "failed to look up map for 'ld-elf.so'"); ATF_CHECK_EQ(strcmp(map1->pr_mapname, map2->pr_mapname), 0); ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution"); proc_free(phdl); }
ATF_TC_BODY(map_alias_name2map, tc) { struct proc_handle *phdl; prmap_t *map1, *map2; phdl = start_prog(tc, false); /* Initialize the rtld_db handle. */ (void)proc_rdagent(phdl); /* Ensure that "target_prog" and "a.out" return the same map. */ map1 = proc_name2map(phdl, target_prog_file); ATF_REQUIRE_MSG(map1 != NULL, "failed to look up map for '%s'", target_prog_file); map2 = proc_name2map(phdl, aout_object); ATF_REQUIRE_MSG(map2 != NULL, "failed to look up map for '%s'", aout_object); ATF_CHECK_EQ(strcmp(map1->pr_mapname, map2->pr_mapname), 0); ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution"); proc_free(phdl); }
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); ctf = ctf_open(map->pr_mapname, &error); free(map); return (ctf); #else (void)p; (void)name; return (NULL); #endif }
int proc_iter_symbyaddr(struct proc_handle *p, const char *object, int which, int mask, proc_sym_f *func, void *cd) { Elf *e; int i, fd; prmap_t *map; Elf_Scn *scn, *foundscn = NULL; Elf_Data *data; GElf_Shdr shdr; GElf_Sym sym; unsigned long stridx = -1; char *s; int error = -1; if ((map = proc_name2map(p, object)) == NULL) return (-1); if ((fd = open(map->pr_mapname, O_RDONLY)) < 0) { warn("ERROR: open %s failed", map->pr_mapname); goto err0; } if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { warn("ERROR: elf_begin() failed"); goto err1; } /* * Find the section we are looking for. */ scn = NULL; while ((scn = elf_nextscn(e, scn)) != NULL) { gelf_getshdr(scn, &shdr); if (which == PR_SYMTAB && shdr.sh_type == SHT_SYMTAB) { foundscn = scn; break; } else if (which == PR_DYNSYM && shdr.sh_type == SHT_DYNSYM) { foundscn = scn; break; } } if (!foundscn) return (-1); stridx = shdr.sh_link; if ((data = elf_getdata(foundscn, NULL)) == NULL) { DPRINTF("ERROR: elf_getdata() failed"); goto err2; } i = 0; while (gelf_getsym(data, i++, &sym) != NULL) { if (GELF_ST_BIND(sym.st_info) == STB_LOCAL && (mask & BIND_LOCAL) == 0) continue; if (GELF_ST_BIND(sym.st_info) == STB_GLOBAL && (mask & BIND_GLOBAL) == 0) continue; if (GELF_ST_BIND(sym.st_info) == STB_WEAK && (mask & BIND_WEAK) == 0) continue; if (GELF_ST_TYPE(sym.st_info) == STT_NOTYPE && (mask & TYPE_NOTYPE) == 0) continue; if (GELF_ST_TYPE(sym.st_info) == STT_OBJECT && (mask & TYPE_OBJECT) == 0) continue; if (GELF_ST_TYPE(sym.st_info) == STT_FUNC && (mask & TYPE_FUNC) == 0) continue; if (GELF_ST_TYPE(sym.st_info) == STT_SECTION && (mask & TYPE_SECTION) == 0) continue; if (GELF_ST_TYPE(sym.st_info) == STT_FILE && (mask & TYPE_FILE) == 0) continue; s = elf_strptr(e, stridx, sym.st_name); sym.st_value += map->pr_vaddr; (*func)(cd, &sym, s); } error = 0; err2: elf_end(e); err1: close(fd); err0: free(map); return (error); }
int proc_name2sym(struct proc_handle *p, const char *object, const char *symbol, GElf_Sym *symcopy) { Elf *e; Elf_Scn *scn, *dynsymscn = NULL, *symtabscn = NULL; Elf_Data *data; GElf_Shdr shdr; GElf_Sym sym; GElf_Ehdr ehdr; int fd, error = -1; size_t i; prmap_t *map; char *s; unsigned long symtabstridx = 0, dynsymstridx = 0; if ((map = proc_name2map(p, object)) == NULL) { DPRINTF("ERROR: couldn't find object %s", object); goto err0; } if ((fd = open(map->pr_mapname, O_RDONLY, 0)) < 0) { DPRINTF("ERROR: open %s failed", map->pr_mapname); goto err0; } if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { warn("ERROR: elf_begin() failed"); goto err1; } if (gelf_getehdr(e, &ehdr) == NULL) { warn("ERROR: gelf_getehdr() failed"); goto err2; } /* * Find the index of the STRTAB and SYMTAB sections to locate * symbol names. */ scn = NULL; while ((scn = elf_nextscn(e, scn)) != NULL) { gelf_getshdr(scn, &shdr); switch (shdr.sh_type) { case SHT_SYMTAB: symtabscn = scn; symtabstridx = shdr.sh_link; break; case SHT_DYNSYM: dynsymscn = scn; dynsymstridx = shdr.sh_link; break; default: break; } } /* * Iterate over the Dynamic Symbols table to find the symbol. * Then look up the string name in STRTAB (.dynstr) */ if ((data = elf_getdata(dynsymscn, NULL))) { DPRINTF("ERROR: elf_getdata() failed"); i = 0; while (gelf_getsym(data, i++, &sym) != NULL) { s = elf_strptr(e, dynsymstridx, sym.st_name); if (s && strcmp(s, symbol) == 0) { memcpy(symcopy, &sym, sizeof(sym)); symcopy->st_value = map->pr_vaddr + sym.st_value; error = 0; goto out; } } } /* * Iterate over the Symbols Table to find the symbol. * Then look up the string name in STRTAB (.dynstr) */ if (symtabscn == NULL) goto err2; if ((data = elf_getdata(symtabscn, NULL))) { i = 0; while (gelf_getsym(data, i++, &sym) != NULL) { s = elf_strptr(e, symtabstridx, sym.st_name); if (s && strcmp(s, symbol) == 0) { memcpy(symcopy, &sym, sizeof(sym)); error = 0; goto out; } } } out: err2: elf_end(e); err1: close(fd); err0: free(map); return (error); }
int proc_name2sym(struct proc_handle *p, const char *object, const char *symbol, GElf_Sym *symcopy, prsyminfo_t *si) { Elf *e; Elf_Scn *scn, *dynsymscn = NULL, *symtabscn = NULL; GElf_Shdr shdr; GElf_Ehdr ehdr; prmap_t *map; uintptr_t off; u_long symtabstridx = 0, dynsymstridx = 0; int fd, error = -1; if ((map = proc_name2map(p, object)) == NULL) { DPRINTFX("ERROR: couldn't find object %s", object); goto err0; } if ((fd = find_dbg_obj(map->pr_mapname)) < 0) { DPRINTF("ERROR: open %s failed", map->pr_mapname); goto err0; } if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { DPRINTFX("ERROR: elf_begin() failed: %s", elf_errmsg(-1)); goto err1; } if (gelf_getehdr(e, &ehdr) == NULL) { DPRINTFX("ERROR: gelf_getehdr() failed: %s", elf_errmsg(-1)); goto err2; } /* * Find the index of the STRTAB and SYMTAB sections to locate * symbol names. */ scn = NULL; while ((scn = elf_nextscn(e, scn)) != NULL) { gelf_getshdr(scn, &shdr); switch (shdr.sh_type) { case SHT_SYMTAB: symtabscn = scn; symtabstridx = shdr.sh_link; break; case SHT_DYNSYM: dynsymscn = scn; dynsymstridx = shdr.sh_link; break; } } /* * First look up the symbol in the dynsymtab, and fall back to the * symtab if the lookup fails. */ error = lookup_name(e, dynsymscn, dynsymstridx, symbol, symcopy, si); if (error == 0) goto out; error = lookup_name(e, symtabscn, symtabstridx, symbol, symcopy, si); if (error == 0) goto out; out: off = ehdr.e_type == ET_EXEC ? 0 : map->pr_vaddr; symcopy->st_value += off; err2: elf_end(e); err1: close(fd); err0: free(map); return (error); }