diff options
Diffstat (limited to 'src/copy/section.c')
-rw-r--r-- | src/copy/section.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/copy/section.c b/src/copy/section.c new file mode 100644 index 0000000..5a62593 --- /dev/null +++ b/src/copy/section.c @@ -0,0 +1,75 @@ +#include <stdio.h> + +#include <libelf.h> +#include <gelf.h> + +#include <libelfu/libelfu.h> + + +void elfu_copySection(Elf *eo, Elf_Scn *scn) +{ + Elf_Scn *scnOut; + Elf_Data *data; + GElf_Shdr shdr, shdrOut; + + scnOut = elf_newscn(eo); + if (!scnOut) { + fprintf(stderr, "elf_newscn() failed: %s\n", elf_errmsg(-1)); + return; + } + + if (gelf_getshdr(scn, &shdr) != &shdr) { + fprintf(stderr, "gelf_getshdr() failed: %s\n", elf_errmsg(-1)); + } + + + /* Copy section header */ + if (gelf_getshdr(scnOut, &shdrOut) != &shdrOut) { + fprintf(stderr, "gelf_getshdr() failed: %s\n", elf_errmsg(-1)); + } + + shdrOut.sh_name = shdr.sh_name; + shdrOut.sh_type = shdr.sh_type; + shdrOut.sh_flags = shdr.sh_flags; + /* sh_addr */ + shdrOut.sh_addr = shdr.sh_addr; + /* sh_offset */ + /* sh_size */ + shdrOut.sh_link = shdr.sh_link; + shdrOut.sh_info = shdr.sh_info; + shdrOut.sh_addralign = shdr.sh_addralign; + //shdrOut.sh_entsize = shdr.sh_entsize; + + if (!gelf_update_shdr(scnOut, &shdrOut)) { + fprintf(stderr, "gelf_update_shdr() failed: %s\n", elf_errmsg(-1)); + } + + + //elf_flagshdr(scnOut, ELF_C_SET, ELF_F_DIRTY); + //elf_flagscn(scnOut, ELF_C_SET, ELF_F_DIRTY); + + + /* Copy each data part in source segment */ + data = elf_rawdata(scn, NULL); + while (data) { + Elf_Data *dataOut = elf_newdata(scnOut); + if (!dataOut) { + fprintf(stderr, "elf_newdata() failed: %s\n", elf_errmsg(-1)); + } + + dataOut->d_align = data->d_align; + dataOut->d_buf = data->d_buf; + /* dataOut->d_off = data->d_off; */ + dataOut->d_type = data->d_type; + dataOut->d_size = data->d_size; + dataOut->d_version = data->d_version; + + //elf_flagdata(dataOut, ELF_C_SET, ELF_F_DIRTY); + + data = elf_rawdata(scn, data); + } + + // ehf_newdata() should flag the entire section dirty + //elf_flagshdr(scnOut, ELF_C_SET, ELF_F_DIRTY); + //elf_flagscn(scnOut, ELF_C_SET, ELF_F_DIRTY); +} |