6 #include <libelfu/libelfu.h>
10 void elfu_copySegments1(Elf *eo, Elf *ei)
14 if (elf_getphdrnum(ei, &n)) {
15 fprintf(stderr, "elf_getphdrnum() failed: %s\n", elf_errmsg(-1));
18 if (!gelf_newphdr(eo, n)) {
19 fprintf(stderr, "gelf_newphdr() failed: %s\n", elf_errmsg(-1));
22 for (i = 0; i < n; i++) {
23 GElf_Phdr phdr, phdrOut;
25 if (gelf_getphdr(ei, i, &phdr) != &phdr) {
26 fprintf(stderr, "gelf_getphdr() failed for #%d: %s\n", i, elf_errmsg(-1));
30 if (gelf_getphdr(eo, i, &phdrOut) != &phdrOut) {
31 fprintf(stderr, "gelf_getphdr() failed for #%d: %s\n", i, elf_errmsg(-1));
35 phdrOut.p_type = phdr.p_type;
37 phdrOut.p_vaddr = phdr.p_vaddr;
38 phdrOut.p_paddr = phdr.p_paddr;
41 phdrOut.p_flags = phdr.p_flags;
42 phdrOut.p_align = phdr.p_align;
44 if (!gelf_update_phdr (eo, i, &phdrOut)) {
45 fprintf(stderr, "gelf_update_ehdr() failed: %s\n", elf_errmsg(-1));
49 /* Tell libelf that phdrs have changed */
50 elf_flagphdr(eo, ELF_C_SET, ELF_F_DIRTY);
54 void elfu_copySegments2(Elf *eo, Elf *ei)
58 if (elf_getphdrnum(ei, &n)) {
59 fprintf(stderr, "elf_getphdrnum() failed: %s\n", elf_errmsg(-1));
62 for (i = 0; i < n; i++) {
63 GElf_Phdr phdr, phdrOut;
65 if (gelf_getphdr(ei, i, &phdr) != &phdr) {
66 fprintf(stderr, "gelf_getphdr() failed for #%d: %s\n", i, elf_errmsg(-1));
70 if (gelf_getphdr(eo, i, &phdrOut) != &phdrOut) {
71 fprintf(stderr, "gelf_getphdr() failed for #%d: %s\n", i, elf_errmsg(-1));
75 /* Start of segment */
76 if (phdr.p_type == PT_PHDR) {
77 /* Skip PHDR entries and fix them up later */
79 else if (phdr.p_offset == 0) {
80 /* The text segment usually loads the whole ELF header */
83 /* Try to guess the start of the segment */
84 Elf_Scn *scn, *scnOut;
85 GElf_Shdr shdr, shdrOut;
87 scn = elfu_firstSectionInSegment(ei, &phdr);
89 fprintf(stderr, "elfu_firstSectionInSegment() failed for segment #%d\n", i);
93 if (gelf_getshdr(scn, &shdr) != &shdr) {
94 fprintf(stderr, "gelf_getshdr() failed: %s\n", elf_errmsg(-1));
97 if (phdr.p_offset < shdr.sh_offset) {
98 fprintf(stderr, "elfu_copySegments2: Segment #%d starts before first contained section.\n", i);
101 scnOut = elf_getscn(eo, elf_ndxscn(scn));
103 fprintf(stderr, "elf_getscn() failed: %s\n", elf_errmsg(-1));
106 if (gelf_getshdr(scnOut, &shdrOut) != &shdrOut) {
107 fprintf(stderr, "gelf_getshdr() failed: %s\n", elf_errmsg(-1));
110 phdrOut.p_offset = shdrOut.sh_offset;
113 /* File length of segment */
114 if (phdr.p_type == PT_PHDR) {
115 /* Skip PHDR entries and fix them up later */
117 else if (phdr.p_memsz == 0) {
118 phdrOut.p_filesz = 0;
121 /* Try to guess the end of the segment */
122 Elf_Scn *scn, *scnOut;
123 GElf_Shdr shdr, shdrOut;
125 scn = elfu_lastSectionInSegment(ei, &phdr);
127 fprintf(stderr, "elfu_lastSectionInSegment() failed for segment #%d\n", i);
131 if (gelf_getshdr(scn, &shdr) != &shdr) {
132 fprintf(stderr, "gelf_getshdr() failed: %s\n", elf_errmsg(-1));
135 if (phdr.p_offset + phdr.p_filesz > shdr.sh_offset + shdr.sh_size) {
136 fprintf(stderr, "elfu_copySegments2: Segment #%d ends after last contained section.\n", i);
139 scnOut = elf_getscn(eo, elf_ndxscn(scn));
141 fprintf(stderr, "elf_getscn() failed: %s\n", elf_errmsg(-1));
144 if (gelf_getshdr(scnOut, &shdrOut) != &shdrOut) {
145 fprintf(stderr, "gelf_getshdr() failed: %s\n", elf_errmsg(-1));
148 phdrOut.p_filesz = shdrOut.sh_offset - phdrOut.p_offset;
149 if (shdrOut.sh_type != SHT_NOBITS) {
150 phdrOut.p_filesz += shdrOut.sh_size;
153 phdrOut.p_memsz = shdrOut.sh_offset - phdrOut.p_offset + shdrOut.sh_size;
156 if (!gelf_update_phdr (eo, i, &phdrOut)) {
157 fprintf(stderr, "gelf_update_ehdr() failed: %s\n", elf_errmsg(-1));
161 /* Tell libelf that phdrs have changed */
162 elf_flagphdr(eo, ELF_C_SET, ELF_F_DIRTY);