e714d2eaa1
Signed-off-by: Domenico Andreoli <domenico.andreoli@linux.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
126 lines
2.7 KiB
C
126 lines
2.7 KiB
C
/*
|
|
* SPDX-License-Identifier: GPL-2.0-only
|
|
*
|
|
* Copyright 2009 Red Hat, Inc.
|
|
*
|
|
* Author: Peter Jones <pjones@redhat.com>
|
|
*/
|
|
#include <gelf.h>
|
|
#include <stdio.h>
|
|
#include <strings.h>
|
|
#include <string.h>
|
|
#include <fcntl.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
#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, elf, scn);
|
|
}
|
|
elfcreator_end(ctor);
|
|
return 0;
|
|
}
|