Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/lib/libsa Make the ELF loadfile routines byte-order inde...



details:   https://anonhg.NetBSD.org/src/rev/eac1d59decb5
branches:  trunk
changeset: 516865:eac1d59decb5
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Wed Oct 31 21:24:09 2001 +0000

description:
Make the ELF loadfile routines byte-order independent when used in
a non-_STANDALONE environment (e.g. installboot(8)): internalize and
externalize the exec, program, and section headers as necessary.

Reviewed and OK'd by Christos.

diffstat:

 sys/lib/libsa/loadfile_elf32.c |  216 ++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 215 insertions(+), 1 deletions(-)

diffs (266 lines):

diff -r 6d2d7dacdefd -r eac1d59decb5 sys/lib/libsa/loadfile_elf32.c
--- a/sys/lib/libsa/loadfile_elf32.c    Wed Oct 31 21:15:43 2001 +0000
+++ b/sys/lib/libsa/loadfile_elf32.c    Wed Oct 31 21:24:09 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: loadfile_elf32.c,v 1.3 2001/10/31 17:20:50 thorpej Exp $ */
+/* $NetBSD: loadfile_elf32.c,v 1.4 2001/10/31 21:24:09 thorpej Exp $ */
 
 /*-
  * Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -103,6 +103,203 @@
 
 #define        ELFROUND        (ELFSIZE / 8)
 
+#ifndef _STANDALONE
+#include "byteorder.h"
+
+/*
+ * Byte swapping may be necessary in the non-_STANDLONE case because
+ * we may be built with a host compiler.
+ */
+#define        E16(f)                                                          \
+       f = (bo == ELFDATA2LSB) ? sa_htole16(f) : sa_htobe16(f)
+#define        E32(f)                                                          \
+       f = (bo == ELFDATA2LSB) ? sa_htole32(f) : sa_htobe32(f)
+#define        E64(f)                                                          \
+       f = (bo == ELFDATA2LSB) ? sa_htole64(f) : sa_htobe64(f)
+
+#define        I16(f)                                                          \
+       f = (bo == ELFDATA2LSB) ? sa_le16toh(f) : sa_be16toh(f)
+#define        I32(f)                                                          \
+       f = (bo == ELFDATA2LSB) ? sa_le32toh(f) : sa_be32toh(f)
+#define        I64(f)                                                          \
+       f = (bo == ELFDATA2LSB) ? sa_le64toh(f) : sa_be64toh(f)
+
+static void
+internalize_ehdr(Elf_Byte bo, Elf_Ehdr *ehdr)
+{
+
+#if ELFSIZE == 32
+       I16(ehdr->e_type);
+       I16(ehdr->e_machine);
+       I32(ehdr->e_version);
+       I32(ehdr->e_entry);
+       I32(ehdr->e_phoff);
+       I32(ehdr->e_shoff);
+       I32(ehdr->e_flags);
+       I16(ehdr->e_ehsize);
+       I16(ehdr->e_phentsize);
+       I16(ehdr->e_phnum);
+       I16(ehdr->e_shentsize);
+       I16(ehdr->e_shnum);
+       I16(ehdr->e_shstrndx);
+#elif ELFSIZE == 64
+       I16(ehdr->e_type);
+       I16(ehdr->e_machine);
+       I32(ehdr->e_version);
+       I64(ehdr->e_entry);
+       I64(ehdr->e_phoff);
+       I64(ehdr->e_shoff);
+       I32(ehdr->e_flags);
+       I16(ehdr->e_ehsize);
+       I16(ehdr->e_phentsize);
+       I16(ehdr->e_phnum);
+       I16(ehdr->e_shentsize);
+       I16(ehdr->e_shnum);
+       I16(ehdr->e_shstrndx);
+#else
+#error ELFSIZE is not 32 or 64
+#endif
+}
+
+static void
+externalize_ehdr(Elf_Byte bo, Elf_Ehdr *ehdr)
+{
+
+#if ELFSIZE == 32
+       E16(ehdr->e_type);
+       E16(ehdr->e_machine);
+       E32(ehdr->e_version);
+       E32(ehdr->e_entry);
+       E32(ehdr->e_phoff);
+       E32(ehdr->e_shoff);
+       E32(ehdr->e_flags);
+       E16(ehdr->e_ehsize);
+       E16(ehdr->e_phentsize);
+       E16(ehdr->e_phnum);
+       E16(ehdr->e_shentsize);
+       E16(ehdr->e_shnum);
+       E16(ehdr->e_shstrndx);
+#elif ELFSIZE == 64
+       E16(ehdr->e_type);
+       E16(ehdr->e_machine);
+       E32(ehdr->e_version);
+       E64(ehdr->e_entry);
+       E64(ehdr->e_phoff);
+       E64(ehdr->e_shoff);
+       E32(ehdr->e_flags);
+       E16(ehdr->e_ehsize);
+       E16(ehdr->e_phentsize);
+       E16(ehdr->e_phnum);
+       E16(ehdr->e_shentsize);
+       E16(ehdr->e_shnum);
+       E16(ehdr->e_shstrndx);
+#else
+#error ELFSIZE is not 32 or 64
+#endif
+}
+
+static void
+internalize_phdr(Elf_Byte bo, Elf_Phdr *phdr)
+{
+
+#if ELFSIZE == 32
+       I32(phdr->p_type);
+       I32(phdr->p_offset);
+       I32(phdr->p_vaddr);
+       I32(phdr->p_paddr);
+       I32(phdr->p_filesz);
+       I32(phdr->p_memsz);
+       I32(phdr->p_flags);
+       I32(phdr->p_align);
+#elif ELFSIZE == 64
+       I32(phdr->p_type);
+       I32(phdr->p_offset);
+       I64(phdr->p_vaddr);
+       I64(phdr->p_paddr);
+       I64(phdr->p_filesz);
+       I64(phdr->p_memsz);
+       I64(phdr->p_flags);
+       I64(phdr->p_align);
+#else
+#error ELFSIZE is not 32 or 64
+#endif
+}
+
+static void
+internalize_shdr(Elf_Byte bo, Elf_Shdr *shdr)
+{
+
+#if ELFSIZE == 32
+       I32(shdr->sh_name);
+       I32(shdr->sh_type);
+       I32(shdr->sh_flags);
+       I32(shdr->sh_addr);
+       I32(shdr->sh_offset);
+       I32(shdr->sh_size);
+       I32(shdr->sh_link);
+       I32(shdr->sh_info);
+       I32(shdr->sh_addralign);
+       I32(shdr->sh_entsize);
+#elif ELFSIZE == 64
+       I32(shdr->sh_name);
+       I32(shdr->sh_type);
+       I64(shdr->sh_flags);
+       I64(shdr->sh_addr);
+       I64(shdr->sh_offset);
+       I64(shdr->sh_size);
+       I32(shdr->sh_link);
+       I32(shdr->sh_info);
+       I64(shdr->sh_addralign);
+       I64(shdr->sh_entsize);
+#else
+#error ELFSIZE is not 32 or 64
+#endif
+}
+
+static void
+externalize_shdr(Elf_Byte bo, Elf_Shdr *shdr)
+{
+
+#if ELFSIZE == 32
+       E32(shdr->sh_name);
+       E32(shdr->sh_type);
+       E32(shdr->sh_flags);
+       E32(shdr->sh_addr);
+       E32(shdr->sh_offset);
+       E32(shdr->sh_size);
+       E32(shdr->sh_link);
+       E32(shdr->sh_info);
+       E32(shdr->sh_addralign);
+       E32(shdr->sh_entsize);
+#elif ELFSIZE == 64
+       E32(shdr->sh_name);
+       E32(shdr->sh_type);
+       E64(shdr->sh_flags);
+       E64(shdr->sh_addr);
+       E64(shdr->sh_offset);
+       E64(shdr->sh_size);
+       E32(shdr->sh_link);
+       E32(shdr->sh_info);
+       E64(shdr->sh_addralign);
+       E64(shdr->sh_entsize);
+#else
+#error ELFSIZE is not 32 or 64
+#endif
+}
+#else /* _STANDALONE */
+/*
+ * Byte swapping is never necessary in the _STANDALONE case because
+ * we are being built with the target compiler.
+ */
+#define        internalize_ehdr(bo, ehdr)      /* nothing */
+#define        externalize_ehdr(bo, ehdr)      /* nothing */
+
+#define        internalize_phdr(bo, phdr)      /* nothing */
+
+#define        internalize_shdr(bo, shdr)      /* nothing */
+#define        externalize_shdr(bo, shdr)      /* nothing */
+#endif /* _STANDALONE */
+
 int
 ELFNAMEEND(loadfile)(fd, elf, marks, flags)
        int fd;
@@ -117,6 +314,8 @@
        paddr_t minp = ~0, maxp = 0, pos = 0;
        paddr_t offset = marks[MARK_START], shpp, elfp = NULL;
 
+       internalize_ehdr(elf->e_ident[EI_DATA], elf);
+
        for (first = 1, i = 0; i < elf->e_phnum; i++) {
                Elf_Phdr phdr;
                if (lseek(fd, elf->e_phoff + sizeof(phdr) * i, SEEK_SET)
@@ -128,6 +327,7 @@
                        WARN(("read phdr"));
                        return 1;
                }
+               internalize_phdr(elf->e_ident[EI_DATA], &phdr);
                if (phdr.p_type != PT_LOAD ||
                    (phdr.p_flags & (PF_W|PF_X)) == 0)
                        continue;
@@ -207,6 +407,12 @@
                shpp = maxp;
                maxp += roundup(sz, ELFROUND);
 
+#ifndef _STANDALONE
+               /* Internalize the section headers. */
+               for (i = 0; i < elf->e_shnum; i++)
+                       internalize_shdr(elf->e_ident[EI_DATA], &shp[i]);
+#endif /* ! _STANDALONE */
+
                /*
                 * Now load the symbol sections themselves.  Make sure
                 * the sections are aligned. Don't bother with any
@@ -251,6 +457,12 @@
                        shp[i].sh_name = 0;
                }
                if (flags & LOAD_SYM) {
+#ifndef _STANDALONE
+                       /* Externalize the section headers. */
+                       for (i = 0; i < elf->e_shnum; i++)
+                               externalize_shdr(elf->e_ident[EI_DATA],
+                                   &shp[i]);
+#endif /* ! _STANDALONE */
                        BCOPY(shp, shpp, sz);
 
                        if (first == 0)
@@ -269,7 +481,9 @@
                elf->e_phentsize = 0;
                elf->e_phnum = 0;
                elf->e_shstrndx = SHN_UNDEF;
+               externalize_ehdr(elf->e_ident[EI_DATA], elf);
                BCOPY(elf, elfp, sizeof(*elf));
+               internalize_ehdr(elf->e_ident[EI_DATA], elf);
        }
 
        marks[MARK_START] = LOADADDR(minp);



Home | Main Index | Thread Index | Old Index