static int read_file(Elf *elf, char *file, char *label, read_cb_f *func, void *arg, int require_ctf) { Elf_Scn *ctfscn; Elf_Data *ctfdata = NULL; symit_data_t *si = NULL; int ctfscnidx; tdata_t *td; if ((ctfscnidx = findelfsecidx(elf, file, ".SUNW_ctf")) < 0) { if (require_ctf && (built_source_types(elf, file) & SOURCE_C)) { terminate("Input file %s was partially built from " "C sources, but no CTF data was present\n", file); } return (0); } if ((ctfscn = elf_getscn(elf, ctfscnidx)) == NULL || (ctfdata = elf_getdata(ctfscn, NULL)) == NULL) elfterminate(file, "Cannot read CTF section"); /* Reconstruction of type tree */ if ((si = symit_new(elf, file)) == NULL) { warning("%s has no symbol table - skipping", file); return (0); } td = ctf_load(file, ctfdata->d_buf, ctfdata->d_size, si, label); tdata_build_hashes(td); symit_free(si); if (td != NULL) { if (func(td, file, arg) < 0) return (-1); else return (1); } return (0); }
static int file_read(tdata_t *td, char *filename, int ignore_non_c) { typedef int (*reader_f)(tdata_t *, Elf *, char *); static reader_f readers[] = { stabs_read, dw_read, NULL }; source_types_t source_types; Elf *elf; int i, rc, fd; if ((fd = open(filename, O_RDONLY)) < 0) terminate("failed to open %s", filename); (void) elf_version(EV_CURRENT); if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { close(fd); terminate("failed to read %s: %s\n", filename, elf_errmsg(-1)); } source_types = built_source_types(elf, filename); if ((source_types == SOURCE_NONE || (source_types & SOURCE_UNKNOWN)) && ignore_non_c) { debug(1, "Ignoring file %s from unknown sources\n", filename); exit(0); } for (i = 0; readers[i] != NULL; i++) { if ((rc = readers[i](td, elf, filename)) == 0) break; assert(rc < 0 && errno == ENOENT); } if (readers[i] == NULL) { /* * None of the readers found compatible type data. */ if (findelfsecidx(elf, filename, ".debug") >= 0) { terminate("%s: DWARF version 1 is not supported\n", filename); } if (!(source_types & SOURCE_C) && ignore_non_c) { debug(1, "Ignoring file %s not built from C sources\n", filename); exit(0); } rc = 0; } else { rc = 1; } (void) elf_end(elf); (void) close(fd); return (rc); }