/* * SPDX-License-Identifier: GPL-2.0-only * * Copyright 2009 Red Hat, Inc. * * Author: Peter Jones */ #include #include #include #include #include #include #include #include "elfcreator.h" #include "dutil.h" static int should_copy_scn(Elf *elf, GElf_Shdr *shdr, struct strlist *scns) { char *name; size_t shstrndx; if (elf_getshdrstrndx(elf, &shstrndx) < 0) return 0; name = elf_strptr(elf, shstrndx, shdr->sh_name); if (name == NULL) return 0; if (strlist__has_entry(scns, name)) return 1; return 0; } int main(int argc, char *argv[]) { int n; struct strlist *sections; char *infile = NULL, *outfile = NULL; int fd; Elf *elf; Elf_Scn *scn; int copy_all_sections = 0; ElfCreator *ctor; sections = strlist__new(false); for (n = 1; n < argc; n++) { if (!strcmp(argv[n], "-a")) { copy_all_sections = 1; } else if (!strcmp(argv[n], "-s")) { if (n == argc-1) { fprintf(stderr, "Missing argument to -s\n"); return -1; } n++; strlist__add(sections, argv[n]); continue; } else if (!strcmp(argv[n], "-o")) { if (n == argc-1) { fprintf(stderr, "Missing argument to -o\n"); return -1; } n++; outfile = argv[n]; continue; } else if (!strcmp(argv[n], "-?") || !strcmp(argv[n], "--help") || !strcmp(argv[n], "--usage")) { printf("usage: scncopy [-s section0 [[-s section1] ... -s sectionN] | -a ] -o outfile infile\n"); return 0; } else if (n == argc-1) { infile = argv[n]; } else { fprintf(stderr, "usage: pjoc -s section 0 [[-s section1] ... -s sectionN] -o outfile infile\n"); return 1; } } if (!infile || !outfile) { fprintf(stderr, "usage: pjoc -s section 0 [[-s section1] ... -s sectionN] -o outfile infile\n"); return 1; } if (!(fd = open(infile, O_RDONLY))) { fprintf(stderr, "Could not open \"%s\" for reading: %m\n", infile); return 1; } elf_version(EV_CURRENT); if ((elf = elf_begin(fd, ELF_C_READ_MMAP_PRIVATE, NULL)) == NULL) { fprintf(stderr, "cannot get elf descriptor for \"%s\": %s\n", infile, elf_errmsg(-1)); close(fd); return 1; } if (elf_kind(elf) != ELF_K_ELF) { fprintf(stderr, "\"%s\" is not an ELF file\n", infile); err: elf_end(elf); close(fd); return 1; } if ((ctor = elfcreator_begin(outfile, elf)) == NULL) { fprintf(stderr, "could not initialize ELF creator\n"); goto err; } scn = NULL; while ((scn = elf_nextscn(elf, scn)) != NULL) { GElf_Shdr shdr_mem, *shdr; shdr = gelf_getshdr(scn, &shdr_mem); if (shdr == NULL) continue; if (!should_copy_scn(elf, shdr, sections) && !copy_all_sections) continue; elfcreator_copy_scn(ctor, scn); } elfcreator_end(ctor); return 0; }