Changeset View
Changeset View
Standalone View
Standalone View
head/contrib/elftoolchain/elfcopy/sections.c
Show All 22 Lines | |||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
*/ | */ | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <err.h> | #include <err.h> | ||||
#include <libgen.h> | #include <libgen.h> | ||||
#include <stdbool.h> | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include "elfcopy.h" | #include "elfcopy.h" | ||||
ELFTC_VCSID("$Id: sections.c 3758 2019-06-28 01:16:50Z emaste $"); | ELFTC_VCSID("$Id: sections.c 3758 2019-06-28 01:16:50Z emaste $"); | ||||
▲ Show 20 Lines • Show All 297 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct section *s; | struct section *s; | ||||
const char *name; | const char *name; | ||||
Elf_Scn *is; | Elf_Scn *is; | ||||
GElf_Shdr ish; | GElf_Shdr ish; | ||||
size_t indx; | size_t indx; | ||||
uint64_t oldndx, newndx; | uint64_t oldndx, newndx; | ||||
int elferr, sec_flags, reorder; | int elferr, sec_flags, reorder; | ||||
bool sections_added; | |||||
/* | /* | ||||
* Insert a pseudo section that contains the ELF header | * Insert a pseudo section that contains the ELF header | ||||
* and program header. Used as reference for section offset | * and program header. Used as reference for section offset | ||||
* or load address adjustment. | * or load address adjustment. | ||||
*/ | */ | ||||
if ((s = calloc(1, sizeof(*s))) == NULL) | if ((s = calloc(1, sizeof(*s))) == NULL) | ||||
err(EXIT_FAILURE, "calloc failed"); | err(EXIT_FAILURE, "calloc failed"); | ||||
s->off = 0; | s->off = 0; | ||||
s->sz = gelf_fsize(ecp->eout, ELF_T_EHDR, 1, EV_CURRENT) + | s->sz = gelf_fsize(ecp->eout, ELF_T_EHDR, 1, EV_CURRENT) + | ||||
gelf_fsize(ecp->eout, ELF_T_PHDR, ecp->ophnum, EV_CURRENT); | gelf_fsize(ecp->eout, ELF_T_PHDR, ecp->ophnum, EV_CURRENT); | ||||
s->align = 1; | s->align = 1; | ||||
s->pseudo = 1; | s->pseudo = 1; | ||||
s->loadable = add_to_inseg_list(ecp, s); | s->loadable = add_to_inseg_list(ecp, s); | ||||
insert_to_sec_list(ecp, s, 0); | insert_to_sec_list(ecp, s, 0); | ||||
/* Create internal .shstrtab section. */ | /* Create internal .shstrtab section. */ | ||||
init_shstrtab(ecp); | init_shstrtab(ecp); | ||||
if (elf_getshstrndx(ecp->ein, &indx) == 0) | if (elf_getshstrndx(ecp->ein, &indx) == 0) | ||||
errx(EXIT_FAILURE, "elf_getshstrndx failed: %s", | errx(EXIT_FAILURE, "elf_getshstrndx failed: %s", | ||||
elf_errmsg(-1)); | elf_errmsg(-1)); | ||||
sections_added = false; | |||||
reorder = 0; | reorder = 0; | ||||
is = NULL; | is = NULL; | ||||
while ((is = elf_nextscn(ecp->ein, is)) != NULL) { | while ((is = elf_nextscn(ecp->ein, is)) != NULL) { | ||||
if (gelf_getshdr(is, &ish) == NULL) | if (gelf_getshdr(is, &ish) == NULL) | ||||
errx(EXIT_FAILURE, "gelf_getshdr failed: %s", | errx(EXIT_FAILURE, "gelf_getshdr failed: %s", | ||||
elf_errmsg(-1)); | elf_errmsg(-1)); | ||||
if ((name = elf_strptr(ecp->ein, indx, ish.sh_name)) == NULL) | if ((name = elf_strptr(ecp->ein, indx, ish.sh_name)) == NULL) | ||||
errx(EXIT_FAILURE, "elf_strptr failed: %s", | errx(EXIT_FAILURE, "elf_strptr failed: %s", | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | if (strcmp(name, ".shstrtab") != 0) { | ||||
/* Assuming .shstrtab is "unloadable". */ | /* Assuming .shstrtab is "unloadable". */ | ||||
s = ecp->shstrtab; | s = ecp->shstrtab; | ||||
s->off = ish.sh_offset; | s->off = ish.sh_offset; | ||||
} | } | ||||
oldndx = newndx = SHN_UNDEF; | oldndx = newndx = SHN_UNDEF; | ||||
if (strcmp(name, ".symtab") != 0 && | if (strcmp(name, ".symtab") != 0 && | ||||
strcmp(name, ".strtab") != 0) { | strcmp(name, ".strtab") != 0) { | ||||
/* Add new sections before .shstrtab if we have one. */ | |||||
if (!strcmp(name, ".shstrtab")) { | if (!strcmp(name, ".shstrtab")) { | ||||
/* | /* | ||||
* Add sections specified by --add-section and | * Add sections specified by --add-section and | ||||
* gnu debuglink. we want these sections have | * gnu debuglink. we want these sections have | ||||
* smaller index than .shstrtab section. | * smaller index than .shstrtab section. | ||||
*/ | */ | ||||
sections_added = true; | |||||
if (ecp->debuglink != NULL) | if (ecp->debuglink != NULL) | ||||
add_gnu_debuglink(ecp); | add_gnu_debuglink(ecp); | ||||
if (ecp->flags & SEC_ADD) | if (ecp->flags & SEC_ADD) | ||||
insert_sections(ecp); | insert_sections(ecp); | ||||
} | } | ||||
if ((s->os = elf_newscn(ecp->eout)) == NULL) | if ((s->os = elf_newscn(ecp->eout)) == NULL) | ||||
errx(EXIT_FAILURE, "elf_newscn failed: %s", | errx(EXIT_FAILURE, "elf_newscn failed: %s", | ||||
elf_errmsg(-1)); | elf_errmsg(-1)); | ||||
▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | while ((is = elf_nextscn(ecp->ein, is)) != NULL) { | ||||
if (strcmp(name, ".symtab") == 0) { | if (strcmp(name, ".symtab") == 0) { | ||||
ecp->flags |= SYMTAB_EXIST; | ecp->flags |= SYMTAB_EXIST; | ||||
ecp->symtab = s; | ecp->symtab = s; | ||||
} | } | ||||
if (strcmp(name, ".strtab") == 0) | if (strcmp(name, ".strtab") == 0) | ||||
ecp->strtab = s; | ecp->strtab = s; | ||||
insert_to_sec_list(ecp, s, 0); | insert_to_sec_list(ecp, s, 0); | ||||
} | |||||
if (!sections_added) { | |||||
if (ecp->debuglink != NULL) | |||||
add_gnu_debuglink(ecp); | |||||
if (ecp->flags & SEC_ADD) | |||||
insert_sections(ecp); | |||||
} | } | ||||
elferr = elf_errno(); | elferr = elf_errno(); | ||||
if (elferr != 0) | if (elferr != 0) | ||||
errx(EXIT_FAILURE, "elf_nextscn failed: %s", | errx(EXIT_FAILURE, "elf_nextscn failed: %s", | ||||
elf_errmsg(elferr)); | elf_errmsg(elferr)); | ||||
} | } | ||||
struct section * | struct section * | ||||
▲ Show 20 Lines • Show All 1,228 Lines • Show Last 20 Lines |