6 #include <libelf/gelf.h>
7 #include <libelfu/libelfu.h>
10 void elfu_mExpandNobits(ElfuElf *me, GElf_Off off)
14 GElf_Xword expansionSize;
20 /* Find the maximum amount we need to expand by. Check PHDRs first */
21 CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
22 GElf_Off off2 = mp->phdr.p_offset;
23 GElf_Off end2 = mp->phdr.p_offset + mp->phdr.p_filesz;
25 GElf_Xword size2 = mp->phdr.p_memsz - mp->phdr.p_filesz;
26 if (size2 > expansionSize) {
27 expansionSize = size2;
29 } else if (end2 > off) {
32 * Found a PHDR whose file contents overlaps with the section
33 * to be filled. This means that it relies on the NOBITS area
34 * being actually 0 bytes, and the expansion would ruin it.
36 fprintf(stderr, "mExpandNobits: Found PHDR spanning expansion offset. Aborting.\n");
40 // end2 < off, and the PHDR is unaffected.
46 CIRCLEQ_FOREACH(ms, &me->scnList, elem) {
47 if (ms->shdr.sh_offset == off) {
48 if (ms->shdr.sh_type == SHT_NOBITS) {
49 if (ms->shdr.sh_size > expansionSize) {
50 expansionSize = ms->shdr.sh_size;
61 /* Move all following PHDR offsets further down the file. */
62 CIRCLEQ_FOREACH(mp, &me->phdrList, elem) {
63 GElf_Off off2 = mp->phdr.p_offset;
64 GElf_Off end2 = mp->phdr.p_offset + mp->phdr.p_filesz;
67 mp->phdr.p_offset += expansionSize;
70 /* This PHDR now has corresponding bytes in the file for every
72 mp->phdr.p_filesz = mp->phdr.p_memsz;
77 /* Move the following sections */
78 CIRCLEQ_FOREACH(ms, &me->scnList, elem) {
79 if (ms->shdr.sh_offset >= off) {
80 if (ms->shdr.sh_offset > off
81 || ms->shdr.sh_type != SHT_NOBITS) {
82 ms->shdr.sh_offset += expansionSize;
87 /* Move SHDR/PHDR tables */
88 if (me->ehdr.e_shoff >= off) {
89 me->ehdr.e_shoff += expansionSize;
92 if (me->ehdr.e_phoff >= off) {
93 me->ehdr.e_phoff += expansionSize;
97 /* Convert any NOBITS at off to PROGBITS */
98 CIRCLEQ_FOREACH(ms, &me->scnList, elem) {
99 if (ms->shdr.sh_offset == off) {
100 if (ms->shdr.sh_type == SHT_NOBITS) {
101 ms->data.d_buf = malloc(ms->shdr.sh_size);
102 memset(ms->data.d_buf, '\0', ms->shdr.sh_size);
103 if (!ms->data.d_buf) {
104 fprintf(stderr, "mExpandNobits: Could not allocate %jd bytes for NOBITS expansion.\n", ms->shdr.sh_size);
107 ms->data.d_align = 1;
109 ms->data.d_type = ELF_T_BYTE;
110 ms->data.d_size = ms->shdr.sh_size;
111 ms->data.d_version = elf_version(EV_NONE);
113 ms->shdr.sh_type = SHT_PROGBITS;