summaryrefslogtreecommitdiff
path: root/src/copy/section.c
blob: 6fd08e29ad1f5f654d2e974713f199561eb2857a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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;
  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_align = shdr.sh_addralign;
    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);
}