/* * Will analyse a file to see if it ELF, other files including ar(1), * core dumps are passed off and treated as flat binary files. Unlike * GNU size in FreeBSD this routine will not treat ELF object from * different archs as flat binary files(has to overridden using -a). */ int handle_elf(const char *name, int fd) { GElf_Ehdr elfhdr; GElf_Shdr shdr; Elf *elf; Elf_Scn *scn; int rc; rc = RETURN_OK; /* If entire file is choosen, treat it as a binary file */ if (entire_file) return (handle_binary(name, fd)); (void) lseek(fd, (off_t)0, SEEK_SET); elf = elf_begin(fd, ELF_C_READ, NULL); if (elf_kind(elf) != ELF_K_ELF) { (void) elf_end(elf); return (handle_binary(name, fd)); } if (gelf_getehdr(elf, &elfhdr) == NULL) { (void) elf_end(elf); warnx("%s: ELF file could not be processed", name); return (RETURN_SOFTWARE); } if (elfhdr.e_shnum == 0 && elfhdr.e_type == ET_CORE) { (void) elf_end(elf); return (handle_binary(name, fd)); } else { scn = NULL; while ((scn = elf_nextscn(elf, scn)) != NULL) { if (gelf_getshdr(scn, &shdr) == NULL) continue; if (shdr.sh_type != SHT_NOBITS && (shdr.sh_flags & SHF_ALLOC) != 0) { rc = find_strings(name, shdr.sh_offset, shdr.sh_size); } } } (void) elf_end(elf); return (rc); }
static int piegen(void) { struct stat st; void *mem; int fd, ret = -1; fd = open(opts.input_filename, O_RDONLY); if (fd < 0) { pr_perror("Can't open file %s", opts.input_filename); return -1; } if (fstat(fd, &st)) { pr_perror("Can't stat file %s", opts.input_filename); goto err; } opts.fout = fopen(opts.output_filename, "w"); if (opts.fout == NULL) { pr_perror("Can't open %s", opts.output_filename); goto err; } mem = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FILE, fd, 0); if (mem == MAP_FAILED) { pr_perror("Can't mmap file %s", opts.input_filename); goto err; } if (handle_binary(mem, st.st_size)) { close(fd), fd = -1; unlink(opts.output_filename); goto err; } ret = 0; err: if (fd >= 0) close(fd); if (opts.fout) fclose(opts.fout); if (!ret) printf("%s generated successfully.\n", opts.output_filename); return ret; }