static void set_flag(char *ifile, ulong_t flval) { Elf *elf; Elf_Scn *scn; Elf_Data *data; GElf_Shdr shdr; GElf_Dyn dyn; int fd, secidx, nent, i; (void) elf_version(EV_CURRENT); if ((fd = open(ifile, O_RDWR)) < 0) die("Can't open %s", ifile); if ((elf = elf_begin(fd, ELF_C_RDWR, NULL)) == NULL) elfdie("Can't start ELF for %s", ifile); if ((secidx = findelfsecidx(elf, ".dynamic")) == -1) die("Can't find .dynamic section in %s\n", ifile); if ((scn = elf_getscn(elf, secidx)) == NULL) elfdie("elf_getscn (%d)", secidx); if (gelf_getshdr(scn, &shdr) == NULL) elfdie("gelf_shdr"); if ((data = elf_getdata(scn, NULL)) == NULL) elfdie("elf_getdata"); nent = shdr.sh_size / shdr.sh_entsize; for (i = 0; i < nent; i++) { if (gelf_getdyn(data, i, &dyn) == NULL) elfdie("gelf_getdyn"); if (dyn.d_tag == DT_FLAGS_1) { dyn.d_un.d_val |= (Elf64_Xword)flval; if (gelf_update_dyn(data, i, &dyn) == 0) elfdie("gelf_update_dyn"); break; } } if (i == nent) { die("%s's .dynamic section doesn't have a DT_FLAGS_1 " "field\n", ifile); } if (elf_update(elf, ELF_C_WRITE) == -1) elfdie("Couldn't update %s with changes", ifile); (void) elf_end(elf); (void) close(fd); }
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); }