diff options
Diffstat (limited to 'qemu/roms/SLOF/lib/libelf')
-rw-r--r-- | qemu/roms/SLOF/lib/libelf/Makefile | 47 | ||||
-rw-r--r-- | qemu/roms/SLOF/lib/libelf/elf.c | 190 | ||||
-rw-r--r-- | qemu/roms/SLOF/lib/libelf/elf32.c | 193 | ||||
-rw-r--r-- | qemu/roms/SLOF/lib/libelf/elf64.c | 473 | ||||
-rw-r--r-- | qemu/roms/SLOF/lib/libelf/elf_claim.c | 28 | ||||
-rw-r--r-- | qemu/roms/SLOF/lib/libelf/libelf.code | 43 | ||||
-rw-r--r-- | qemu/roms/SLOF/lib/libelf/libelf.in | 18 |
7 files changed, 0 insertions, 992 deletions
diff --git a/qemu/roms/SLOF/lib/libelf/Makefile b/qemu/roms/SLOF/lib/libelf/Makefile deleted file mode 100644 index 34a8f20b6..000000000 --- a/qemu/roms/SLOF/lib/libelf/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# ***************************************************************************** -# * Copyright (c) 2004, 2011 IBM Corporation -# * All rights reserved. -# * This program and the accompanying materials -# * are made available under the terms of the BSD License -# * which accompanies this distribution, and is available at -# * http://www.opensource.org/licenses/bsd-license.php -# * -# * Contributors: -# * IBM Corporation - initial implementation -# ****************************************************************************/ - -TOPCMNDIR ?= ../.. - -include $(TOPCMNDIR)/make.rules - -CPPFLAGS = -I../libc/include $(CPUARCHDEF) -I$(INCLCMNDIR) -I$(INCLCMNDIR)/$(CPUARCH) -LDFLAGS= -nostdlib - -TARGET = ../libelf.a - -all: $(TARGET) - -SRCS = elf.c elf32.c elf64.c elf_claim.c - -OBJS = $(SRCS:%.c=%.o) - -$(TARGET): $(OBJS) - $(AR) -rc $@ $(OBJS) - $(RANLIB) $@ - -clean: - $(RM) $(TARGET) $(OBJS) - -distclean: clean - $(RM) Makefile.dep - -# Rules for creating the dependency file: -depend: - $(RM) Makefile.dep - $(MAKE) Makefile.dep - -Makefile.dep: Makefile - $(CC) -MM $(CPPFLAGS) $(CFLAGS) $(SRCS) > Makefile.dep - -# Include dependency file if available: --include Makefile.dep diff --git a/qemu/roms/SLOF/lib/libelf/elf.c b/qemu/roms/SLOF/lib/libelf/elf.c deleted file mode 100644 index db2d2abc9..000000000 --- a/qemu/roms/SLOF/lib/libelf/elf.c +++ /dev/null @@ -1,190 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2011 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -/* - * ELF loader - */ - -#include <string.h> -#include <cache.h> -#include <libelf.h> -#include <byteorder.h> - -/** - * elf_check_file tests if the file at file_addr is - * a correct endian, ELF PPC executable - * @param file_addr pointer to the start of the ELF file - * @return the class (1 for 32 bit, 2 for 64 bit) - * -1 if it is not an ELF file - * -2 if it has the wrong endianness - * -3 if it is not an ELF executable - * -4 if it is not for PPC - */ -static int -elf_check_file(unsigned long *file_addr) -{ - struct ehdr *ehdr = (struct ehdr *) file_addr; - uint8_t native_endian; - - /* check if it is an ELF image at all */ - if (cpu_to_be32(ehdr->ei_ident) != 0x7f454c46) - return -1; - -#ifdef __BIG_ENDIAN__ - native_endian = ELFDATA2MSB; -#else - native_endian = ELFDATA2LSB; -#endif - - if (native_endian != ehdr->ei_data) { - switch (ehdr->ei_class) { - case 1: - elf_byteswap_header32(file_addr); - break; - case 2: - elf_byteswap_header64(file_addr); - break; - } - } - - /* check if it is an ELF executable ... and also - * allow DYN files, since this is specified by ePAPR */ - if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) - return -3; - - /* check if it is a PPC ELF executable */ - if (ehdr->e_machine != 0x14 && ehdr->e_machine != 0x15) - return -4; - - return ehdr->ei_class; -} - -/** - * load_elf_file tries to load the ELF file specified in file_addr - * - * it first checks if the file is a PPC ELF executable and then loads - * the segments depending if it is a 64bit or 32 bit ELF file - * - * @param file_addr pointer to the start of the elf file - * @param entry pointer where the ELF loader will store - * the entry point - * @param pre_load handler that is called before copying a segment - * @param post_load handler that is called after copying a segment - * @return 1 for a 32 bit file - * 2 for a 64 bit BE file - * 3 for a 64 bit LE ABIv1 file - * 4 for a 64 bit LE ABIv2 file - * 5 for a 32 bit LE ABIv1 file - * anything else means an error during load - */ -int -elf_load_file(void *file_addr, unsigned long *entry, - int (*pre_load)(void*, long), - void (*post_load)(void*, long)) -{ - int type = elf_check_file(file_addr); - struct ehdr *ehdr = (struct ehdr *) file_addr; - - switch (type) { - case 1: - *entry = elf_load_segments32(file_addr, 0, pre_load, post_load); - if (ehdr->ei_data != ELFDATA2MSB) { - type = 5; /* LE32 ABIv1 */ - } - break; - case 2: - *entry = elf_load_segments64(file_addr, 0, pre_load, post_load); - if (ehdr->ei_data != ELFDATA2MSB) { - uint32_t flags = elf_get_eflags_64(file_addr); - if ((flags & 0x3) == 2) - type = 4; /* LE64 ABIv2 */ - else - type = 3; /* LE64 ABIv1 */ - } - break; - } - if (*entry == 0) - type = 0; - - return type; -} - - -/** - * load_elf_file_to_addr loads an ELF file to given address. - * This is useful for 64-bit vmlinux images that use the virtual entry - * point address in their headers, and thereby need a special treatment. - * - * @param file_addr pointer to the start of the elf file - * @param entry pointer where the ELF loader will store - * the entry point - * @param pre_load handler that is called before copying a segment - * @param post_load handler that is called after copying a segment - * @return 1 for a 32 bit file - * 2 for a 64 bit file - * anything else means an error during load - */ -int -elf_load_file_to_addr(void *file_addr, void *addr, unsigned long *entry, - int (*pre_load)(void*, long), - void (*post_load)(void*, long)) -{ - int type; - long offset; - - type = elf_check_file(file_addr); - - switch (type) { - case 1: - /* Parse 32-bit image */ - offset = (long)addr - elf_get_base_addr32(file_addr); - *entry = elf_load_segments32(file_addr, offset, pre_load, - post_load) + offset; - // TODO: elf_relocate32(...) - break; - case 2: - /* Parse 64-bit image */ - offset = (long)addr - elf_get_base_addr64(file_addr); - *entry = elf_load_segments64(file_addr, offset, pre_load, - post_load) + offset; - elf_relocate64(file_addr, offset); - break; - } - - return type; -} - - -/** - * Get the base load address of the ELF image - * @return The base address or -1 for error - */ -long -elf_get_base_addr(void *file_addr) -{ - int type; - - type = elf_check_file(file_addr); - - switch (type) { - case 1: - /* Return 32-bit image base address */ - return elf_get_base_addr32(file_addr); - break; - case 2: - /* Return 64-bit image base address */ - return elf_get_base_addr64(file_addr); - break; - } - - return -1; -} diff --git a/qemu/roms/SLOF/lib/libelf/elf32.c b/qemu/roms/SLOF/lib/libelf/elf32.c deleted file mode 100644 index fea5cf420..000000000 --- a/qemu/roms/SLOF/lib/libelf/elf32.c +++ /dev/null @@ -1,193 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2011 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -/* - * 32-bit ELF loader - */ -#include <stdio.h> -#include <string.h> -#include <libelf.h> -#include <byteorder.h> - -struct ehdr32 { - uint32_t ei_ident; - uint8_t ei_class; - uint8_t ei_data; - uint8_t ei_version; - uint8_t ei_pad[9]; - uint16_t e_type; - uint16_t e_machine; - uint32_t e_version; - uint32_t e_entry; - uint32_t e_phoff; - uint32_t e_shoff; - uint32_t e_flags; - uint16_t e_ehsize; - uint16_t e_phentsize; - uint16_t e_phnum; - uint16_t e_shentsize; - uint16_t e_shnum; - uint16_t e_shstrndx; -}; - -struct phdr32 { - uint32_t p_type; - uint32_t p_offset; - uint32_t p_vaddr; - uint32_t p_paddr; - uint32_t p_filesz; - uint32_t p_memsz; - uint32_t p_flags; - uint32_t p_align; -}; - - -static struct phdr32* -get_phdr32(void *file_addr) -{ - return (struct phdr32 *) (((unsigned char *)file_addr) - + ((struct ehdr32 *)file_addr)->e_phoff); -} - -static void -load_segment(void *file_addr, struct phdr32 *phdr, signed long offset, - int (*pre_load)(void*, long), - void (*post_load)(void*, long)) -{ - unsigned long src = phdr->p_offset + (unsigned long) file_addr; - unsigned long destaddr; - - destaddr = (unsigned long)phdr->p_paddr; - destaddr = destaddr + offset; - - /* check if we're allowed to copy */ - if (pre_load != NULL) { - if (pre_load((void*)destaddr, phdr->p_memsz) != 0) - return; - } - - /* copy into storage */ - memmove((void *)destaddr, (void *)src, phdr->p_filesz); - - /* clear bss */ - memset((void *)(destaddr + phdr->p_filesz), 0, - phdr->p_memsz - phdr->p_filesz); - - if (phdr->p_memsz && post_load) { - post_load((void*)destaddr, phdr->p_memsz); - } -} - -unsigned int -elf_load_segments32(void *file_addr, signed long offset, - int (*pre_load)(void*, long), - void (*post_load)(void*, long)) -{ - struct ehdr32 *ehdr = (struct ehdr32 *) file_addr; - /* Calculate program header address */ - struct phdr32 *phdr = get_phdr32(file_addr); - int i; - - /* loop e_phnum times */ - for (i = 0; i <= ehdr->e_phnum; i++) { - /* PT_LOAD ? */ - if (phdr->p_type == 1) { - if (phdr->p_paddr != phdr->p_vaddr) { - printf("ELF32: VirtAddr(%lx) != PhysAddr(%lx) not supported, aborting\n", - (long)phdr->p_vaddr, (long)phdr->p_paddr); - return 0; - } - - /* copy segment */ - load_segment(file_addr, phdr, offset, pre_load, - post_load); - } - /* step to next header */ - phdr = (struct phdr32 *)(((uint8_t *)phdr) + ehdr->e_phentsize); - } - - /* Entry point is always a virtual address, so translate it - * to physical before returning it */ - return ehdr->e_entry; -} - -/** - * Return the base address for loading (i.e. the address of the first PT_LOAD - * segment) - * @param file_addr pointer to the ELF file in memory - * @return the base address - */ -long -elf_get_base_addr32(void *file_addr) -{ - struct ehdr32 *ehdr = (struct ehdr32 *) file_addr; - struct phdr32 *phdr = get_phdr32(file_addr); - int i; - - /* loop e_phnum times */ - for (i = 0; i <= ehdr->e_phnum; i++) { - /* PT_LOAD ? */ - if (phdr->p_type == 1) { - return phdr->p_paddr; - } - /* step to next header */ - phdr = (struct phdr32 *)(((uint8_t *)phdr) + ehdr->e_phentsize); - } - - return 0; -} - -uint32_t elf_get_eflags_32(void *file_addr) -{ - struct ehdr32 *ehdr = (struct ehdr32 *) file_addr; - - return ehdr->e_flags; -} - -void -elf_byteswap_header32(void *file_addr) -{ - struct ehdr32 *ehdr = (struct ehdr32 *) file_addr; - struct phdr32 *phdr; - int i; - - bswap_16p(&ehdr->e_type); - bswap_16p(&ehdr->e_machine); - bswap_32p(&ehdr->e_version); - bswap_32p(&ehdr->e_entry); - bswap_32p(&ehdr->e_phoff); - bswap_32p(&ehdr->e_shoff); - bswap_32p(&ehdr->e_flags); - bswap_16p(&ehdr->e_ehsize); - bswap_16p(&ehdr->e_phentsize); - bswap_16p(&ehdr->e_phnum); - bswap_16p(&ehdr->e_shentsize); - bswap_16p(&ehdr->e_shnum); - bswap_16p(&ehdr->e_shstrndx); - - phdr = get_phdr32(file_addr); - - /* loop e_phnum times */ - for (i = 0; i <= ehdr->e_phnum; i++) { - bswap_32p(&phdr->p_type); - bswap_32p(&phdr->p_offset); - bswap_32p(&phdr->p_vaddr); - bswap_32p(&phdr->p_paddr); - bswap_32p(&phdr->p_filesz); - bswap_32p(&phdr->p_memsz); - bswap_32p(&phdr->p_flags); - bswap_32p(&phdr->p_align); - - /* step to next header */ - phdr = (struct phdr32 *)(((uint8_t *)phdr) + ehdr->e_phentsize); - } -} diff --git a/qemu/roms/SLOF/lib/libelf/elf64.c b/qemu/roms/SLOF/lib/libelf/elf64.c deleted file mode 100644 index 37e9c10a9..000000000 --- a/qemu/roms/SLOF/lib/libelf/elf64.c +++ /dev/null @@ -1,473 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2011 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -/* - * 64-bit ELF loader for PowerPC. - * See the "64-bit PowerPC ELF Application Binary Interface Supplement" and - * the "ELF-64 Object File Format" documentation for details. - */ - -#include <string.h> -#include <stdio.h> -#include <libelf.h> -#include <byteorder.h> - -struct ehdr64 -{ - uint32_t ei_ident; - uint8_t ei_class; - uint8_t ei_data; - uint8_t ei_version; - uint8_t ei_pad[9]; - uint16_t e_type; - uint16_t e_machine; - uint32_t e_version; - uint64_t e_entry; - uint64_t e_phoff; - uint64_t e_shoff; - uint32_t e_flags; - uint16_t e_ehsize; - uint16_t e_phentsize; - uint16_t e_phnum; - uint16_t e_shentsize; - uint16_t e_shnum; - uint16_t e_shstrndx; -}; - -struct phdr64 -{ - uint32_t p_type; - uint32_t p_flags; - uint64_t p_offset; - uint64_t p_vaddr; - uint64_t p_paddr; - uint64_t p_filesz; - uint64_t p_memsz; - uint64_t p_align; -}; - -struct shdr64 -{ - uint32_t sh_name; /* Section name */ - uint32_t sh_type; /* Section type */ - uint64_t sh_flags; /* Section attributes */ - uint64_t sh_addr; /* Virtual address in memory */ - uint64_t sh_offset; /* Offset in file */ - uint64_t sh_size; /* Size of section */ - uint32_t sh_link; /* Link to other section */ - uint32_t sh_info; /* Miscellaneous information */ - uint64_t sh_addralign; /* Address alignment boundary */ - uint64_t sh_entsize; /* Size of entries, if section has table */ -}; - -struct rela /* RelA relocation table entry */ -{ - uint64_t r_offset; /* Address of reference */ - uint64_t r_info; /* Symbol index and type of relocation */ - int64_t r_addend; /* Constant part of expression */ -}; - -struct sym64 -{ - uint32_t st_name; /* Symbol name */ - uint8_t st_info; /* Type and Binding attributes */ - uint8_t st_other; /* Reserved */ - uint16_t st_shndx; /* Section table index */ - uint64_t st_value; /* Symbol value */ - uint64_t st_size; /* Size of object (e.g., common) */ -}; - - -/* For relocations */ -#define ELF_R_SYM(i) ((i)>>32) -#define ELF_R_TYPE(i) ((uint32_t)(i) & 0xFFFFFFFF) -#define ELF_R_INFO(s,t) ((((uint64_t) (s)) << 32) + (t)) - -/* - * Relocation types for PowerPC64. - */ -#define R_PPC64_NONE 0 -#define R_PPC64_ADDR32 1 -#define R_PPC64_ADDR24 2 -#define R_PPC64_ADDR16 3 -#define R_PPC64_ADDR16_LO 4 -#define R_PPC64_ADDR16_HI 5 -#define R_PPC64_ADDR16_HA 6 -#define R_PPC64_ADDR14 7 -#define R_PPC64_ADDR14_BRTAKEN 8 -#define R_PPC64_ADDR14_BRNTAKEN 9 -#define R_PPC64_REL24 10 -#define R_PPC64_REL14 11 -#define R_PPC64_REL14_BRTAKEN 12 -#define R_PPC64_REL14_BRNTAKEN 13 -#define R_PPC64_GOT16 14 -#define R_PPC64_GOT16_LO 15 -#define R_PPC64_GOT16_HI 16 -#define R_PPC64_GOT16_HA 17 -#define R_PPC64_COPY 19 -#define R_PPC64_GLOB_DAT 20 -#define R_PPC64_JMP_SLOT 21 -#define R_PPC64_RELATIVE 22 -#define R_PPC64_UADDR32 24 -#define R_PPC64_UADDR16 25 -#define R_PPC64_REL32 26 -#define R_PPC64_PLT32 27 -#define R_PPC64_PLTREL32 28 -#define R_PPC64_PLT16_LO 29 -#define R_PPC64_PLT16_HI 30 -#define R_PPC64_PLT16_HA 31 -#define R_PPC64_SECTOFF 33 -#define R_PPC64_SECTOFF_LO 34 -#define R_PPC64_SECTOFF_HI 35 -#define R_PPC64_SECTOFF_HA 36 -#define R_PPC64_ADDR30 37 -#define R_PPC64_ADDR64 38 -#define R_PPC64_ADDR16_HIGHER 39 -#define R_PPC64_ADDR16_HIGHERA 40 -#define R_PPC64_ADDR16_HIGHEST 41 -#define R_PPC64_ADDR16_HIGHESTA 42 -#define R_PPC64_UADDR64 43 -#define R_PPC64_REL64 44 -#define R_PPC64_PLT64 45 -#define R_PPC64_PLTREL64 46 -#define R_PPC64_TOC16 47 -#define R_PPC64_TOC16_LO 48 -#define R_PPC64_TOC16_HI 49 -#define R_PPC64_TOC16_HA 50 -#define R_PPC64_TOC 51 -#define R_PPC64_PLTGOT16 52 -#define R_PPC64_PLTGOT16_LO 53 -#define R_PPC64_PLTGOT16_HI 54 -#define R_PPC64_PLTGOT16_HA 55 -#define R_PPC64_ADDR16_DS 56 -#define R_PPC64_ADDR16_LO_DS 57 -#define R_PPC64_GOT16_DS 58 -#define R_PPC64_GOT16_LO_DS 59 -#define R_PPC64_PLT16_LO_DS 60 -#define R_PPC64_SECTOFF_DS 61 -#define R_PPC64_SECTOFF_LO_DS 62 -#define R_PPC64_TOC16_DS 63 -#define R_PPC64_TOC16_LO_DS 64 -#define R_PPC64_PLTGOT16_DS 65 -#define R_PPC64_PLTGOT16_LO_DS 66 -#define R_PPC64_TLS 67 -#define R_PPC64_DTPMOD64 68 -#define R_PPC64_TPREL16 69 -#define R_PPC64_TPREL16_LO 60 -#define R_PPC64_TPREL16_HI 71 -#define R_PPC64_TPREL16_HA 72 -#define R_PPC64_TPREL64 73 -#define R_PPC64_DTPREL16 74 -#define R_PPC64_DTPREL16_LO 75 -#define R_PPC64_DTPREL16_HI 76 -#define R_PPC64_DTPREL16_HA 77 -#define R_PPC64_DTPREL64 78 -#define R_PPC64_GOT_TLSGD16 79 -#define R_PPC64_GOT_TLSGD16_LO 80 -#define R_PPC64_GOT_TLSGD16_HI 81 -#define R_PPC64_GOT_TLSGD16_HA 82 -#define R_PPC64_GOT_TLSLD16 83 -#define R_PPC64_GOT_TLSLD16_LO 84 -#define R_PPC64_GOT_TLSLD16_HI 85 -#define R_PPC64_GOT_TLSLD16_HA 86 -#define R_PPC64_GOT_TPREL16_DS 87 -#define R_PPC64_GOT_TPREL16_LO_ DS 88 -#define R_PPC64_GOT_TPREL16_HI 89 -#define R_PPC64_GOT_TPREL16_HA 90 -#define R_PPC64_GOT_DTPREL16_DS 91 -#define R_PPC64_GOT_DTPREL16_LO_DS 92 -#define R_PPC64_GOT_DTPREL16_HI 93 -#define R_PPC64_GOT_DTPREL16_HA 94 -#define R_PPC64_TPREL16_DS 95 -#define R_PPC64_TPREL16_LO_DS 96 -#define R_PPC64_TPREL16_HIGHER 97 -#define R_PPC64_TPREL16_HIGHERA 98 -#define R_PPC64_TPREL16_HIGHEST 99 -#define R_PPC64_TPREL16_HIGHESTA 100 -#define R_PPC64_DTPREL16_DS 101 -#define R_PPC64_DTPREL16_LO_DS 102 -#define R_PPC64_DTPREL16_HIGHER 103 -#define R_PPC64_DTPREL16_HIGHERA 104 -#define R_PPC64_DTPREL16_HIGHEST 105 -#define R_PPC64_DTPREL16_HIGHESTA 106 - - -static struct phdr64* -get_phdr64(unsigned long *file_addr) -{ - return (struct phdr64 *) (((unsigned char *) file_addr) - + ((struct ehdr64 *)file_addr)->e_phoff); -} - -static void -load_segment64(unsigned long *file_addr, struct phdr64 *phdr, signed long offset, - int (*pre_load)(void*, long), - void (*post_load)(void*, long)) -{ - unsigned long src = phdr->p_offset + (unsigned long) file_addr; - unsigned long destaddr; - - destaddr = phdr->p_paddr + offset; - - /* check if we're allowed to copy */ - if (pre_load != NULL) { - if (pre_load((void*)destaddr, phdr->p_memsz) != 0) - return; - } - - /* copy into storage */ - memmove((void*)destaddr, (void*)src, phdr->p_filesz); - - /* clear bss */ - memset((void*)(destaddr + phdr->p_filesz), 0, - phdr->p_memsz - phdr->p_filesz); - - if (phdr->p_memsz && post_load != NULL) { - post_load((void*)destaddr, phdr->p_memsz); - } -} - -unsigned long -elf_load_segments64(void *file_addr, signed long offset, - int (*pre_load)(void*, long), - void (*post_load)(void*, long)) -{ - struct ehdr64 *ehdr = (struct ehdr64 *) file_addr; - /* Calculate program header address */ - struct phdr64 *phdr = get_phdr64(file_addr); - int i; - - /* loop e_phnum times */ - for (i = 0; i <= ehdr->e_phnum; i++) { - /* PT_LOAD ? */ - if (phdr->p_type == PT_LOAD) { - if (phdr->p_paddr != phdr->p_vaddr) { - printf("ELF64: VirtAddr(%lx) != PhysAddr(%lx) not supported, aborting\n", - (long)phdr->p_vaddr, (long)phdr->p_paddr); - return 0; - } - - /* copy segment */ - load_segment64(file_addr, phdr, offset, pre_load, post_load); - } - /* step to next header */ - phdr = (struct phdr64 *)(((uint8_t *)phdr) + ehdr->e_phentsize); - } - - /* Entry point is always a virtual address, so translate it - * to physical before returning it */ - return ehdr->e_entry; -} - -/** - * Return the base address for loading (i.e. the address of the first PT_LOAD - * segment) - * @param file_addr pointer to the ELF file in memory - * @return the base address - */ -long -elf_get_base_addr64(void *file_addr) -{ - struct ehdr64 *ehdr = (struct ehdr64 *) file_addr; - /* Calculate program header address */ - struct phdr64 *phdr = get_phdr64(file_addr); - int i; - - /* loop e_phnum times */ - for (i = 0; i <= ehdr->e_phnum; i++) { - /* PT_LOAD ? */ - if (phdr->p_type == PT_LOAD) { - /* Return base address */ - return phdr->p_paddr; - } - /* step to next header */ - phdr = (struct phdr64 *)(((uint8_t *)phdr) + ehdr->e_phentsize); - } - - return 0; -} - - -/** - * Apply one relocation entry. - */ -static void -elf_apply_rela64(void *file_addr, signed long offset, struct rela *relaentry, - struct sym64 *symtabentry) -{ - void *addr; - unsigned long s_a; - unsigned long base_addr; - - base_addr = elf_get_base_addr64(file_addr); - - /* Sanity check */ - if (relaentry->r_offset < base_addr) { - printf("\nELF relocation out of bounds!\n"); - return; - } - - base_addr += offset; - - /* Actual address where the relocation will be applied at. */ - addr = (void*)(relaentry->r_offset + offset); - - /* Symbol value (S) + Addend (A) */ - s_a = symtabentry->st_value + offset + relaentry->r_addend; - - switch (ELF_R_TYPE(relaentry->r_info)) { - case R_PPC64_ADDR32: /* S + A */ - *(uint32_t *)addr = (uint32_t) s_a; - break; - case R_PPC64_ADDR64: /* S + A */ - *(uint64_t *)addr = (uint64_t) s_a; - break; - case R_PPC64_TOC: /* .TOC */ - *(uint64_t *)addr += offset; - break; - case R_PPC64_ADDR16_HIGHEST: /* #highest(S + A) */ - *(uint16_t *)addr = ((s_a >> 48) & 0xffff); - break; - case R_PPC64_ADDR16_HIGHER: /* #higher(S + A) */ - *(uint16_t *)addr = ((s_a >> 32) & 0xffff); - break; - case R_PPC64_ADDR16_HI: /* #hi(S + A) */ - *(uint16_t *)addr = ((s_a >> 16) & 0xffff); - break; - case R_PPC64_ADDR16_LO: /* #lo(S + A) */ - *(uint16_t *)addr = s_a & 0xffff; - break; - case R_PPC64_ADDR16_LO_DS: - *(uint16_t *)addr = (s_a & 0xfffc); - break; - case R_PPC64_ADDR16_HA: /* #ha(S + A) */ - *(uint16_t *)addr = (((s_a >> 16) + ((s_a & 0x8000) ? 1 : 0)) - & 0xffff); - break; - - case R_PPC64_TOC16: /* half16* S + A - .TOC. */ - case R_PPC64_TOC16_LO_DS: - case R_PPC64_TOC16_LO: /* #lo(S + A - .TOC.) */ - case R_PPC64_TOC16_HI: /* #hi(S + A - .TOC.) */ - case R_PPC64_TOC16_HA: - case R_PPC64_TOC16_DS: /* (S + A - .TOC) >> 2 */ - case R_PPC64_REL14: - case R_PPC64_REL24: /* (S + A - P) >> 2 */ - case R_PPC64_REL64: /* S + A - P */ - case R_PPC64_GOT16_DS: - case R_PPC64_GOT16_LO_DS: - // printf("\t\tignoring relocation type %i\n", - // ELF_R_TYPE(relaentry->r_info)); - break; - default: - printf("ERROR: Unhandled relocation (A) type %i\n", - ELF_R_TYPE(relaentry->r_info)); - } -} - - -/** - * Step through all relocation entries and apply them one by one. - */ -static void -elf_apply_all_rela64(void *file_addr, signed long offset, struct shdr64 *shdrs, int idx) -{ - struct shdr64 *rela_shdr = &shdrs[idx]; - struct shdr64 *dst_shdr = &shdrs[rela_shdr->sh_info]; - struct shdr64 *sym_shdr = &shdrs[rela_shdr->sh_link]; - struct rela *relaentry; - struct sym64 *symtabentry; - uint32_t symbolidx; - int i; - - /* If the referenced section has not been allocated, then it has - * not been loaded and thus does not need to be relocated. */ - if ((dst_shdr->sh_flags & SHF_ALLOC) != SHF_ALLOC) - return; - - for (i = 0; i < rela_shdr->sh_size; i += rela_shdr->sh_entsize) { - relaentry = (struct rela *)(file_addr + rela_shdr->sh_offset + i); - - symbolidx = ELF_R_SYM(relaentry->r_info); - symtabentry = (struct sym64*)(file_addr + sym_shdr->sh_offset) + symbolidx; - - elf_apply_rela64(file_addr, offset, relaentry, symtabentry); - } -} - - -/** - * Apply ELF relocations - */ -void -elf_relocate64(void *file_addr, signed long offset) -{ - struct ehdr64 *ehdr = (struct ehdr64 *) file_addr; - /* Calculate section header address */ - struct shdr64 *shdrs = (struct shdr64 *) - (((unsigned char *) file_addr) + ehdr->e_shoff); - int i; - - /* loop over all segments */ - for (i = 0; i <= ehdr->e_shnum; i++) { - /* Skip if it is not a relocation segment */ - if (shdrs[i].sh_type == SHT_RELA) { - elf_apply_all_rela64(file_addr, offset, shdrs, i); - } - } -} - -void -elf_byteswap_header64(void *file_addr) -{ - struct ehdr64 *ehdr = (struct ehdr64 *) file_addr; - struct phdr64 *phdr; - int i; - - bswap_16p(&ehdr->e_type); - bswap_16p(&ehdr->e_machine); - bswap_32p(&ehdr->e_version); - bswap_64p(&ehdr->e_entry); - bswap_64p(&ehdr->e_phoff); - bswap_64p(&ehdr->e_shoff); - bswap_32p(&ehdr->e_flags); - bswap_16p(&ehdr->e_ehsize); - bswap_16p(&ehdr->e_phentsize); - bswap_16p(&ehdr->e_phnum); - bswap_16p(&ehdr->e_shentsize); - bswap_16p(&ehdr->e_shnum); - bswap_16p(&ehdr->e_shstrndx); - - phdr = get_phdr64(file_addr); - - /* loop e_phnum times */ - for (i = 0; i <= ehdr->e_phnum; i++) { - bswap_32p(&phdr->p_type); - bswap_32p(&phdr->p_flags); - bswap_64p(&phdr->p_offset); - bswap_64p(&phdr->p_vaddr); - bswap_64p(&phdr->p_paddr); - bswap_64p(&phdr->p_filesz); - bswap_64p(&phdr->p_memsz); - bswap_64p(&phdr->p_align); - - /* step to next header */ - phdr = (struct phdr64 *)(((uint8_t *)phdr) + ehdr->e_phentsize); - } -} - -uint32_t elf_get_eflags_64(void *file_addr) -{ - struct ehdr64 *ehdr = (struct ehdr64 *) file_addr; - - return ehdr->e_flags; -} diff --git a/qemu/roms/SLOF/lib/libelf/elf_claim.c b/qemu/roms/SLOF/lib/libelf/elf_claim.c deleted file mode 100644 index 43540f9b6..000000000 --- a/qemu/roms/SLOF/lib/libelf/elf_claim.c +++ /dev/null @@ -1,28 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2009, 2011 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#include <string.h> -#include <libelf.h> -#include "../../slof/paflof.h" - - -/** - * Call Forth code to try to claim the memory region - */ -int -elf_forth_claim(void *addr, long size) -{ - forth_push((long)addr); - forth_push(size); - forth_eval("elf-claim-segment"); - return forth_pop(); -} diff --git a/qemu/roms/SLOF/lib/libelf/libelf.code b/qemu/roms/SLOF/lib/libelf/libelf.code deleted file mode 100644 index 551468bdd..000000000 --- a/qemu/roms/SLOF/lib/libelf/libelf.code +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2011 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -/* - * libelf Forth wrapper - */ - -#include <libelf.h> - -// : elf-load-file ( fileaddr -- entry type ) -PRIM(ELF_X2d_LOAD_X2d_FILE) -{ - void *file_addr = TOS.a; - int type; - unsigned long entry; - type = elf_load_file(file_addr, &entry, elf_forth_claim, flush_cache); - TOS.u = entry; - PUSH; TOS.n = type; -} -MIRP - -// : elf-load-file-to-addr ( fileaddr destaddr -- entry type ) -PRIM(ELF_X2d_LOAD_X2d_FILE_X2d_TO_X2d_ADDR) -{ - void *dest_addr = TOS.a; POP; - void *file_addr = TOS.a; - int type; - unsigned long entry; - type = elf_load_file_to_addr(file_addr, dest_addr, &entry, - elf_forth_claim, flush_cache); - TOS.u = entry; - PUSH; TOS.n = type; -} -MIRP diff --git a/qemu/roms/SLOF/lib/libelf/libelf.in b/qemu/roms/SLOF/lib/libelf/libelf.in deleted file mode 100644 index 9c5f019ce..000000000 --- a/qemu/roms/SLOF/lib/libelf/libelf.in +++ /dev/null @@ -1,18 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2004, 2011 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -/* - * libelf bindings for Forth - definitions - */ - -cod(ELF-LOAD-FILE) -cod(ELF-LOAD-FILE-TO-ADDR) |