Initial commit

This commit is contained in:
Bahadir Balban
2008-01-13 13:53:52 +00:00
commit e2b791a3d8
789 changed files with 95825 additions and 0 deletions

42
libs/elf/SConstruct Normal file
View File

@@ -0,0 +1,42 @@
Import("*")
import os
import glob
libs = ["gcc"]
arch = 'arm'
# C library information
clibvariant = "baremetal"
clibroot = os.getcwd() + '/../c'
clibpath = os.getcwd() + clibroot + '/build/' + clibvariant
cincpath = [clibroot + '/include', clibroot + '/include/arch/%s' % arch]
env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
CCFLAGS = ['-g', '-nostdinc', '-nostdlib', '-ffreestanding'],
LINKFLAGS = ['-nostdlib'],
ENV = {'PATH' : os.environ['PATH']},
LIBS = ['gcc','c-' + clibvariant],
LIBPATH = clibpath,
CPPPATH = ['#include'] + cincpath)
def src_glob(search):
"""Src glob is used to find source files easily e.g: src_glob("src/*.c"),
the reason we can't just use glob is due to the way SCons handles out
of directory builds."""
dir = os.path.dirname(search)
if dir != "":
dir = dir + os.sep
src_path = Dir('.').srcnode().abspath
files = glob.glob(src_path + os.sep + search)
files = map(os.path.basename, files)
ret_files = []
for file in files:
ret_files.append(dir + file)
return ret_files
src = src_glob("src/*.c")
libelf = env.StaticLibrary('elf', src)

370
libs/elf/include/elf/elf.h Normal file
View File

@@ -0,0 +1,370 @@
/*
* Australian Public Licence B (OZPLB)
*
* Version 1-0
*
* Copyright (c) 1999-2004 University of New South Wales
*
* All rights reserved.
*
* Developed by: Operating Systems and Distributed Systems Group (DiSy)
* University of New South Wales
* http://www.disy.cse.unsw.edu.au
*
* Permission is granted by University of New South Wales, free of charge, to
* any person obtaining a copy of this software and any associated
* documentation files (the "Software") to deal with the Software without
* restriction, including (without limitation) the rights to use, copy,
* modify, adapt, merge, publish, distribute, communicate to the public,
* sublicense, and/or sell, lend or rent out copies of the Software, and
* to permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimers.
*
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials provided
* with the distribution.
*
* * Neither the name of University of New South Wales, nor the names of its
* contributors, may be used to endorse or promote products derived
* from this Software without specific prior written permission.
*
* EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
* PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
* NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
* WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
* REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
* THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
* ERRORS, WHETHER OR NOT DISCOVERABLE.
*
* TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
* NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
* THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
* LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
* OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
* OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
* OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
* CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
* CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
* DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
* CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
* DAMAGES OR OTHER LIABILITY.
*
* If applicable legislation implies representations, warranties, or
* conditions, or imposes obligations or liability on University of New South
* Wales or one of its contributors in respect of the Software that
* cannot be wholly or partly excluded, restricted or modified, the
* liability of University of New South Wales or the contributor is limited, to
* the full extent permitted by the applicable legislation, at its
* option, to:
* a. in the case of goods, any one or more of the following:
* i. the replacement of the goods or the supply of equivalent goods;
* ii. the repair of the goods;
* iii. the payment of the cost of replacing the goods or of acquiring
* equivalent goods;
* iv. the payment of the cost of having the goods repaired; or
* b. in the case of services:
* i. the supplying of the services again; or
* ii. the payment of the cost of having the services supplied again.
*
* The construction, validity and performance of this licence is governed
* by the laws in force in New South Wales, Australia.
*/
/*
Authors: Luke Deller, Ben Leslie
Created: 24/Sep/1999
*/
/**
\file
\brief Generic ELF library
The ELF library is designed to make the task of parsing and getting information
out of an ELF file easier.
It provides function to obtain the various different fields in the ELF header, and
the program and segment information.
Also importantly, it provides a function elf_loadFile which will load a given
ELF file into memory.
*/
#ifndef __ELF_ELF_H__
#define __ELF_ELF_H__
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include "elf32.h"
#include "elf64.h"
/*
* constants for Elf32_Phdr.p_flags
*/
#define PF_X 1 /* readable segment */
#define PF_W 2 /* writeable segment */
#define PF_R 4 /* executable segment */
/*
* constants for indexing into Elf64_Header_t.e_ident
*/
#define EI_MAG0 0
#define EI_MAG1 1
#define EI_MAG2 2
#define EI_MAG3 3
#define EI_CLASS 4
#define EI_DATA 5
#define EI_VERSION 6
#define ELFMAG0 '\177'
#define ELFMAG1 'E'
#define ELFMAG2 'L'
#define ELFMAG3 'F'
#define ELFCLASS32 1
#define ELFCLASS64 2
#define PT_NULL 0
#define PT_LOAD 1
#define PT_DYNAMIC 2
#define PT_INTERP 3
#define PT_NOTE 4
#define ELFDATA2LSB 1
#define ELFDATA2MSB 2
/* Section Header type bits */
#define SHT_PROGBITS 1
#define SHT_SYMTAB 2
#define SHT_NOBITS 8
#define SHT_REL 9
/* Section Header flag bits */
#define SHF_WRITE 1
#define SHF_ALLOC 2
#define SHF_EXECINSTR 4
/**/
#define ELF_PRINT_PROGRAM_HEADERS 1
#define ELF_PRINT_SECTIONS 2
#define ELF_PRINT_ALL (ELF_PRINT_PROGRAM_HEADERS | ELF_PRINT_SECTIONS)
/**
* Checks that elfFile points to a valid elf file.
*
* @param elfFile Potential ELF file to check
*
* \return 0 on success. -1 if not and elf, -2 if not 32 bit.
*/
int elf_checkFile(void *elfFile);
/**
* Determine number of sections in an ELF file.
*
* @param elfFile Pointer to a valid ELF header.
*
* \return Number of sections in the ELF file.
*/
unsigned elf_getNumSections(void *elfFile);
/**
* Determine number of program headers in an ELF file.
*
* @param elfFile Pointer to a valid ELF header.
*
* \return Number of program headers in the ELF file.
*/
uint16_t elf_getNumProgramHeaders(void *elfFile);
/**
* Return the base physical address of given program header in an ELF file
*
* @param elfFile Pointer to a valid ELF header
* @param ph Index of the program header
*
* \return The memory size of the specified program header
*/
uint64_t elf_getProgramHeaderPaddr(void *elfFile, uint16_t ph);
/**
* Return the base virtual address of given program header in an ELF file
*
* @param elfFile Pointer to a valid ELF header
* @param ph Index of the program header
*
* \return The memory size of the specified program header
*/
uint64_t elf_getProgramHeaderVaddr(void *elfFile, uint16_t ph);
/**
* Return the memory size of a given program header in an ELF file
*
* @param elfFile Pointer to a valid ELF header
* @param ph Index of the program header
*
* \return The memory size of the specified program header
*/
uint64_t elf_getProgramHeaderMemorySize(void *elfFile, uint16_t ph);
/**
* Return the file size of a given program header in an ELF file
*
* @param elfFile Pointer to a valid ELF header
* @param ph Index of the program header
*
* \return The file size of the specified program header
*/
uint64_t elf_getProgramHeaderFileSize(void *elfFile, uint16_t ph);
/**
* Return the start offset of he file
*
* @param elfFile Pointer to a valid ELF header
* @param ph Index of the program header
*
* \return The offset of this program header with relation to the start
* of the elfFile.
*/
uint64_t elf_getProgramHeaderOffset(void *elfFile, uint16_t ph);
/**
* Return the flags for a given program header
*
* @param elfFile Pointer to a valid ELF header
* @param ph Index of the program header
*
* \return The flags of a given program header
*/
uint32_t elf_getProgramHeaderFlags(void *elfFile, uint16_t ph);
/**
* Return the type for a given program header
*
* @param elfFile Pointer to a valid ELF header
* @param ph Index of the program header
*
* \return The type of a given program header
*/
uint32_t elf_getProgramHeaderType(void *elfFile, uint16_t ph);
/**
* Return the physical translation of a physical address, with respect
* to a given program header
*
*/
uint64_t elf_vtopProgramHeader(void *elfFile, uint16_t ph, uint64_t vaddr);
/**
*
* \return true if the address in in this program header
*/
bool elf_vaddrInProgramHeader(void *elfFile, uint16_t ph, uint64_t vaddr);
/**
* Determine the memory bounds of an ELF file
*
* @param elfFile Pointer to a valid ELF header
* @param phys If true return bounds of physical memory, otherwise return
* bounds of virtual memory
* @param min Pointer to return value of the minimum
* @param max Pointer to return value of the maximum
*
* \return true on success. false on failure, if for example, it is an invalid ELF file
*/
bool elf_getMemoryBounds(void *elfFile, bool phys, uint64_t *min, uint64_t *max);
/**
* Find the entry point of an ELF file.
*
* @param elfFile Pointer to a valid ELF header
*
* \return The entry point address as a 64-bit integer.
*/
uint64_t elf_getEntryPoint(void *elfFile);
/**
* Load an ELF file into memory
*
* @param elfFile Pointer to a valid ELF file
* @param phys If true load using the physical address, otherwise using the virtual addresses
*
* \return true on success, false on failure.
*
* The function assumes that the ELF file is loaded in memory at some
* address different to the target address at which it will be loaded.
* It also assumes direct access to the source and destination address, i.e:
* Memory must be ale to me loaded with a simple memcpy.
*
* Obviously this also means that if we are loading a 64bit ELF on a 32bit
* platform, we assume that any memory address are within the first 4GB.
*
*/
bool elf_loadFile(void *elfFile, bool phys);
char *elf_getStringTable(void *elfFile, int string_segment);
char *elf_getSegmentStringTable(void *elfFile);
void *elf_getSectionNamed(void *elfFile, char *str);
char *elf_getSectionName(void *elfFile, int i);
uint64_t elf_getSectionSize(void *elfFile, int i);
uint64_t elf_getSectionAddr(void *elfFile, int i);
/**
* Return the flags for a given sections
*
* @param elfFile Pointer to a valid ELF header
* @param i Index of the sections
*
* \return The flags of a given section
*/
uint32_t elf_getSectionFlags(void *elfFile, int i);
/**
* Return the type for a given sections
*
* @param elfFile Pointer to a valid ELF header
* @param i Index of the sections
*
* \return The type of a given section
*/
uint32_t elf_getSectionType(void *elfFile, int i);
void *elf_getSection(void *elfFile, int i);
void elf_getProgramHeaderInfo(void *elfFile, uint16_t ph, uint64_t *p_vaddr,
uint64_t *p_paddr, uint64_t *p_filesz,
uint64_t *p_offset, uint64_t *p_memsz);
/**
* output the details of an ELF file to the stream f
*/
void elf_fprintf(FILE *f, void *elfFile, int size, const char *name, int flags);
#if 0
/*
* Returns a pointer to the program segment table, which is an array of
* ELF64_Phdr_t structs. The size of the array can be found by calling
* getNumProgramSegments.
*/
struct Elf32_Phdr *elf_getProgramSegmentTable(void *elfFile);
#endif
#if 0
/**
* Returns a pointer to the program segment table, which is an array of
* ELF64_Phdr_t structs. The size of the array can be found by calling
* getNumProgramSegments.
*/
struct Elf32_Shdr *elf_getSectionTable(void *elfFile);
#endif
#endif

View File

@@ -0,0 +1,242 @@
/*
* Australian Public Licence B (OZPLB)
*
* Version 1-0
*
* Copyright (c) 2004 University of New South Wales
*
* All rights reserved.
*
* Developed by: Operating Systems and Distributed Systems Group (DiSy)
* University of New South Wales
* http://www.disy.cse.unsw.edu.au
*
* Permission is granted by University of New South Wales, free of charge, to
* any person obtaining a copy of this software and any associated
* documentation files (the "Software") to deal with the Software without
* restriction, including (without limitation) the rights to use, copy,
* modify, adapt, merge, publish, distribute, communicate to the public,
* sublicense, and/or sell, lend or rent out copies of the Software, and
* to permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimers.
*
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials provided
* with the distribution.
*
* * Neither the name of University of New South Wales, nor the names of its
* contributors, may be used to endorse or promote products derived
* from this Software without specific prior written permission.
*
* EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
* PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
* NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
* WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
* REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
* THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
* ERRORS, WHETHER OR NOT DISCOVERABLE.
*
* TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
* NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
* THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
* LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
* OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
* OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
* OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
* CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
* CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
* DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
* CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
* DAMAGES OR OTHER LIABILITY.
*
* If applicable legislation implies representations, warranties, or
* conditions, or imposes obligations or liability on University of New South
* Wales or one of its contributors in respect of the Software that
* cannot be wholly or partly excluded, restricted or modified, the
* liability of University of New South Wales or the contributor is limited, to
* the full extent permitted by the applicable legislation, at its
* option, to:
* a. in the case of goods, any one or more of the following:
* i. the replacement of the goods or the supply of equivalent goods;
* ii. the repair of the goods;
* iii. the payment of the cost of replacing the goods or of acquiring
* equivalent goods;
* iv. the payment of the cost of having the goods repaired; or
* b. in the case of services:
* i. the supplying of the services again; or
* ii. the payment of the cost of having the services supplied again.
*
* The construction, validity and performance of this licence is governed
* by the laws in force in New South Wales, Australia.
*/
#ifndef __ELF_ELF_32_H__
#define __ELF_ELF_32_H__
#include <stdint.h>
/*
* File header
*/
struct Elf32_Header {
unsigned char e_ident[16];
uint16_t e_type; /* Relocatable=1, Executable=2 (+ some
* more ..) */
uint16_t e_machine; /* Target architecture: MIPS=8 */
uint32_t e_version; /* Elf version (should be 1) */
uint32_t e_entry; /* Code entry point */
uint32_t e_phoff; /* Program header table */
uint32_t e_shoff; /* Section header table */
uint32_t e_flags; /* Flags */
uint16_t e_ehsize; /* ELF header size */
uint16_t e_phentsize; /* Size of one program segment
* header */
uint16_t e_phnum; /* Number of program segment
* headers */
uint16_t e_shentsize; /* Size of one section header */
uint16_t e_shnum; /* Number of section headers */
uint16_t e_shstrndx; /* Section header index of the
* string table for section header
* * names */
};
/*
* Section header
*/
struct Elf32_Shdr {
uint32_t sh_name;
uint32_t sh_type;
uint32_t sh_flags;
uint32_t sh_addr;
uint32_t sh_offset;
uint32_t sh_size;
uint32_t sh_link;
uint32_t sh_info;
uint32_t sh_addralign;
uint32_t sh_entsize;
};
/*
* Program header
*/
struct Elf32_Phdr {
uint32_t p_type; /* Segment type: Loadable segment = 1 */
uint32_t p_offset; /* Offset of segment in file */
uint32_t p_vaddr; /* Reqd virtual address of segment
* when loading */
uint32_t p_paddr; /* Reqd physical address of
* segment (ignore) */
uint32_t p_filesz; /* How many bytes this segment
* occupies in file */
uint32_t p_memsz; /* How many bytes this segment
* should occupy in * memory (when
* * loading, expand the segment
* by * concatenating enough zero
* bytes to it) */
uint32_t p_flags; /* Flags: logical "or" of PF_
* constants below */
uint32_t p_align; /* Reqd alignment of segment in
* memory */
};
int elf32_checkFile(struct Elf32_Header *file);
struct Elf32_Phdr * elf32_getProgramSegmentTable(struct Elf32_Header *file);
unsigned elf32_getNumSections(struct Elf32_Header *file);
char * elf32_getStringTable(struct Elf32_Header *file);
char * elf32_getSegmentStringTable(struct Elf32_Header *file);
static inline struct Elf32_Shdr *
elf32_getSectionTable(struct Elf32_Header *file)
{
/* Cast heaven! */
return (struct Elf32_Shdr*) (uintptr_t) (((uintptr_t) file) + file->e_shoff);
}
/* accessor functions */
static inline uint32_t
elf32_getSectionType(struct Elf32_Header *file, uint16_t s)
{
return elf32_getSectionTable(file)[s].sh_type;
}
static inline uint32_t
elf32_getSectionFlags(struct Elf32_Header *file, uint16_t s)
{
return elf32_getSectionTable(file)[s].sh_flags;
}
char * elf32_getSectionName(struct Elf32_Header *file, int i);
uint32_t elf32_getSectionSize(struct Elf32_Header *file, int i);
uint32_t elf32_getSectionAddr(struct Elf32_Header *elfFile, int i);
void * elf32_getSection(struct Elf32_Header *file, int i);
void * elf32_getSectionNamed(struct Elf32_Header *file, char *str);
int elf32_getSegmentType (struct Elf32_Header *file, int segment);
void elf32_getSegmentInfo(struct Elf32_Header *file, int segment, uint64_t *p_vaddr,
uint64_t *p_paddr, uint64_t *p_filesz,
uint64_t *p_offset, uint64_t *p_memsz);
void elf32_fprintf(FILE *f, struct Elf32_Header *file, int size, const char *name, int flags);
uint32_t elf32_getEntryPoint (struct Elf32_Header *file);
/* Program header functions */
uint16_t elf32_getNumProgramHeaders(struct Elf32_Header *file);
static inline struct Elf32_Phdr *
elf32_getProgramHeaderTable(struct Elf32_Header *file)
{
/* Cast heaven! */
return (struct Elf32_Phdr*) (uintptr_t) (((uintptr_t) file) + file->e_phoff);
}
/* accessor functions */
static inline uint32_t
elf32_getProgramHeaderFlags(struct Elf32_Header *file, uint16_t ph)
{
return elf32_getProgramHeaderTable(file)[ph].p_flags;
}
static inline uint32_t
elf32_getProgramHeaderType(struct Elf32_Header *file, uint16_t ph)
{
return elf32_getProgramHeaderTable(file)[ph].p_type;
}
static inline uint32_t
elf32_getProgramHeaderFileSize(struct Elf32_Header *file, uint16_t ph)
{
return elf32_getProgramHeaderTable(file)[ph].p_filesz;
}
static inline uint32_t
elf32_getProgramHeaderMemorySize(struct Elf32_Header *file, uint16_t ph)
{
return elf32_getProgramHeaderTable(file)[ph].p_memsz;
}
static inline uint32_t
elf32_getProgramHeaderVaddr(struct Elf32_Header *file, uint16_t ph)
{
return elf32_getProgramHeaderTable(file)[ph].p_vaddr;
}
static inline uint32_t
elf32_getProgramHeaderPaddr(struct Elf32_Header *file, uint16_t ph)
{
return elf32_getProgramHeaderTable(file)[ph].p_paddr;
}
static inline uint32_t
elf32_getProgramHeaderOffset(struct Elf32_Header *file, uint16_t ph)
{
return elf32_getProgramHeaderTable(file)[ph].p_offset;
}
#endif /* __ELF_ELF_32_H__ */

View File

@@ -0,0 +1,240 @@
/*
* Australian Public Licence B (OZPLB)
*
* Version 1-0
*
* Copyright (c) 2004 University of New South Wales
*
* All rights reserved.
*
* Developed by: Operating Systems and Distributed Systems Group (DiSy)
* University of New South Wales
* http://www.disy.cse.unsw.edu.au
*
* Permission is granted by University of New South Wales, free of charge, to
* any person obtaining a copy of this software and any associated
* documentation files (the "Software") to deal with the Software without
* restriction, including (without limitation) the rights to use, copy,
* modify, adapt, merge, publish, distribute, communicate to the public,
* sublicense, and/or sell, lend or rent out copies of the Software, and
* to permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimers.
*
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials provided
* with the distribution.
*
* * Neither the name of University of New South Wales, nor the names of its
* contributors, may be used to endorse or promote products derived
* from this Software without specific prior written permission.
*
* EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
* PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
* NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
* WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
* REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
* THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
* ERRORS, WHETHER OR NOT DISCOVERABLE.
*
* TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
* NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
* THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
* LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
* OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
* OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
* OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
* CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
* CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
* DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
* CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
* DAMAGES OR OTHER LIABILITY.
*
* If applicable legislation implies representations, warranties, or
* conditions, or imposes obligations or liability on University of New South
* Wales or one of its contributors in respect of the Software that
* cannot be wholly or partly excluded, restricted or modified, the
* liability of University of New South Wales or the contributor is limited, to
* the full extent permitted by the applicable legislation, at its
* option, to:
* a. in the case of goods, any one or more of the following:
* i. the replacement of the goods or the supply of equivalent goods;
* ii. the repair of the goods;
* iii. the payment of the cost of replacing the goods or of acquiring
* equivalent goods;
* iv. the payment of the cost of having the goods repaired; or
* b. in the case of services:
* i. the supplying of the services again; or
* ii. the payment of the cost of having the services supplied again.
*
* The construction, validity and performance of this licence is governed
* by the laws in force in New South Wales, Australia.
*/
#ifndef __LIBELF_64_H__
#define __LIBELF_64_H__
#include <stdint.h>
/*
* File header
*/
struct Elf64_Header {
unsigned char e_ident[16];
uint16_t e_type; /* Relocatable=1, Executable=2 (+ some
* more ..) */
uint16_t e_machine; /* Target architecture: MIPS=8 */
uint32_t e_version; /* Elf version (should be 1) */
uint64_t e_entry; /* Code entry point */
uint64_t e_phoff; /* Program header table */
uint64_t e_shoff; /* Section header table */
uint32_t e_flags; /* Flags */
uint16_t e_ehsize; /* ELF header size */
uint16_t e_phentsize; /* Size of one program segment
* header */
uint16_t e_phnum; /* Number of program segment
* headers */
uint16_t e_shentsize; /* Size of one section header */
uint16_t e_shnum; /* Number of section headers */
uint16_t e_shstrndx; /* Section header index of the
* string table for section header
* * names */
};
/*
* Section header
*/
struct Elf64_Shdr {
uint32_t sh_name;
uint32_t sh_type;
uint64_t sh_flags;
uint64_t sh_addr;
uint64_t sh_offset;
uint64_t sh_size;
uint32_t sh_link;
uint32_t sh_info;
uint64_t sh_addralign;
uint64_t sh_entsize;
};
/*
* Program header
*/
struct Elf64_Phdr {
uint32_t p_type; /* Segment type: Loadable segment = 1 */
uint32_t p_flags; /* Flags: logical "or" of PF_
* constants below */
uint64_t p_offset; /* Offset of segment in file */
uint64_t p_vaddr; /* Reqd virtual address of segment
* when loading */
uint64_t p_paddr; /* Reqd physical address of
* segment */
uint64_t p_filesz; /* How many bytes this segment
* occupies in file */
uint64_t p_memsz; /* How many bytes this segment
* should occupy in * memory (when
* * loading, expand the segment
* by * concatenating enough zero
* bytes to it) */
uint64_t p_align; /* Reqd alignment of segment in
* memory */
};
int elf64_checkFile(void *elfFile);
struct Elf64_Phdr * elf64_getProgramSegmentTable(void *elfFile);
unsigned elf64_getNumSections(void *elfFile);
char * elf64_getStringTable(void *elfFile, int string_segment);
char * elf64_getSegmentStringTable(void *elfFile);
static inline struct Elf64_Shdr *
elf64_getSectionTable(struct Elf64_Header *file)
{
/* Cast heaven! */
return (struct Elf64_Shdr*) (uintptr_t) (((uintptr_t) file) + file->e_shoff);
}
/* accessor functions */
static inline uint32_t
elf64_getSectionType(struct Elf64_Header *file, uint16_t s)
{
return elf64_getSectionTable(file)[s].sh_type;
}
static inline uint32_t
elf64_getSectionFlags(struct Elf64_Header *file, uint16_t s)
{
return elf64_getSectionTable(file)[s].sh_flags;
}
char * elf64_getSectionName(void *elfFile, int i);
uint64_t elf64_getSectionSize(void *elfFile, int i);
uint64_t elf64_getSectionAddr(struct Elf64_Header *elfFile, int i);
void * elf64_getSection(void *elfFile, int i);
void * elf64_getSectionNamed(void *elfFile, char *str);
int elf64_getSegmentType (void *elfFile, int segment);
void elf64_getSegmentInfo(void *elfFile, int segment, uint64_t *p_vaddr,
uint64_t *p_paddr, uint64_t *p_filesz,
uint64_t *p_offset, uint64_t *p_memsz);
void elf64_showDetails(void *elfFile, int size, char *name);
uint64_t elf64_getEntryPoint (struct Elf64_Header *elfFile);
/* Program Headers functions */
/* Program header functions */
uint16_t elf64_getNumProgramHeaders(struct Elf64_Header *file);
static inline struct Elf64_Phdr *
elf64_getProgramHeaderTable(struct Elf64_Header *file)
{
/* Cast hell! */
return (struct Elf64_Phdr*) (uintptr_t) (((uintptr_t) file) + file->e_phoff);
}
/* accessor functions */
static inline uint32_t
elf64_getProgramHeaderFlags(struct Elf64_Header *file, uint16_t ph)
{
return elf64_getProgramHeaderTable(file)[ph].p_flags;
}
static inline uint32_t
elf64_getProgramHeaderType(struct Elf64_Header *file, uint16_t ph)
{
return elf64_getProgramHeaderTable(file)[ph].p_type;
}
static inline uint64_t
elf64_getProgramHeaderFileSize(struct Elf64_Header *file, uint16_t ph)
{
return elf64_getProgramHeaderTable(file)[ph].p_filesz;
}
static inline uint64_t
elf64_getProgramHeaderMemorySize(struct Elf64_Header *file, uint16_t ph)
{
return elf64_getProgramHeaderTable(file)[ph].p_memsz;
}
static inline uint64_t
elf64_getProgramHeaderVaddr(struct Elf64_Header *file, uint16_t ph)
{
return elf64_getProgramHeaderTable(file)[ph].p_vaddr;
}
static inline uint64_t
elf64_getProgramHeaderPaddr(struct Elf64_Header *file, uint16_t ph)
{
return elf64_getProgramHeaderTable(file)[ph].p_paddr;
}
static inline uint64_t
elf64_getProgramHeaderOffset(struct Elf64_Header *file, uint16_t ph)
{
return elf64_getProgramHeaderTable(file)[ph].p_offset;
}
#endif /* __LIBELF_64_H__ */

383
libs/elf/src/elf.c Normal file
View File

@@ -0,0 +1,383 @@
/*
* Australian Public Licence B (OZPLB)
*
* Version 1-0
*
* Copyright (c) 2004 University of New South Wales
*
* All rights reserved.
*
* Developed by: Operating Systems and Distributed Systems Group (DiSy)
* University of New South Wales
* http://www.disy.cse.unsw.edu.au
*
* Permission is granted by University of New South Wales, free of charge, to
* any person obtaining a copy of this software and any associated
* documentation files (the "Software") to deal with the Software without
* restriction, including (without limitation) the rights to use, copy,
* modify, adapt, merge, publish, distribute, communicate to the public,
* sublicense, and/or sell, lend or rent out copies of the Software, and
* to permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimers.
*
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials provided
* with the distribution.
*
* * Neither the name of University of New South Wales, nor the names of its
* contributors, may be used to endorse or promote products derived
* from this Software without specific prior written permission.
*
* EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
* PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
* NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
* WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
* REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
* THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
* ERRORS, WHETHER OR NOT DISCOVERABLE.
*
* TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
* NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
* THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
* LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
* OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
* OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
* OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
* CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
* CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
* DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
* CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
* DAMAGES OR OTHER LIABILITY.
*
* If applicable legislation implies representations, warranties, or
* conditions, or imposes obligations or liability on University of New South
* Wales or one of its contributors in respect of the Software that
* cannot be wholly or partly excluded, restricted or modified, the
* liability of University of New South Wales or the contributor is limited, to
* the full extent permitted by the applicable legislation, at its
* option, to:
* a. in the case of goods, any one or more of the following:
* i. the replacement of the goods or the supply of equivalent goods;
* ii. the repair of the goods;
* iii. the payment of the cost of replacing the goods or of acquiring
* equivalent goods;
* iv. the payment of the cost of having the goods repaired; or
* b. in the case of services:
* i. the supplying of the services again; or
* ii. the payment of the cost of having the services supplied again.
*
* The construction, validity and performance of this licence is governed
* by the laws in force in New South Wales, Australia.
*/
void *str;
#include <elf/elf.h>
#include <string.h>
#include <stdio.h>
/*
* Checks that elfFile points to a valid elf file. Returns 0 if the elf
* file is valid, < 0 if invalid.
*/
#define ISELF32(elfFile) ( ((struct Elf32_Header*)elfFile)->e_ident[EI_CLASS] == ELFCLASS32 )
#define ISELF64(elfFile) ( ((struct Elf64_Header*)elfFile)->e_ident[EI_CLASS] == ELFCLASS64 )
int
elf_checkFile(void *elfFile)
{
return ISELF32 (elfFile)
? elf32_checkFile(elfFile)
: elf64_checkFile(elfFile);
}
/* Program Headers Access functions */
uint16_t
elf_getNumProgramHeaders(void *elfFile)
{
return ISELF32 (elfFile)
? elf32_getNumProgramHeaders(elfFile)
: elf64_getNumProgramHeaders(elfFile);
}
uint32_t
elf_getProgramHeaderFlags(void *elfFile, uint16_t ph)
{
return ISELF32 (elfFile)
? elf32_getProgramHeaderFlags(elfFile, ph)
: elf64_getProgramHeaderFlags(elfFile, ph);
}
uint32_t
elf_getProgramHeaderType(void *elfFile, uint16_t ph)
{
return ISELF32 (elfFile)
? elf32_getProgramHeaderType(elfFile, ph)
: elf64_getProgramHeaderType(elfFile, ph);
}
uint64_t
elf_getProgramHeaderPaddr(void *elfFile, uint16_t ph)
{
return ISELF32 (elfFile)
? elf32_getProgramHeaderPaddr(elfFile, ph)
: elf64_getProgramHeaderPaddr(elfFile, ph);
}
uint64_t
elf_getProgramHeaderVaddr(void *elfFile, uint16_t ph)
{
return ISELF32 (elfFile)
? elf32_getProgramHeaderVaddr(elfFile, ph)
: elf64_getProgramHeaderVaddr(elfFile, ph);
}
uint64_t
elf_getProgramHeaderMemorySize(void *elfFile, uint16_t ph)
{
return ISELF32 (elfFile)
? elf32_getProgramHeaderMemorySize(elfFile, ph)
: elf64_getProgramHeaderMemorySize(elfFile, ph);
}
uint64_t
elf_getProgramHeaderFileSize(void *elfFile, uint16_t ph)
{
return ISELF32 (elfFile)
? elf32_getProgramHeaderFileSize(elfFile, ph)
: elf64_getProgramHeaderFileSize(elfFile, ph);
}
uint64_t
elf_getProgramHeaderOffset(void *elfFile, uint16_t ph)
{
return ISELF32 (elfFile)
? elf32_getProgramHeaderOffset(elfFile, ph)
: elf64_getProgramHeaderOffset(elfFile, ph);
}
char *
elf_getSegmentStringTable(void *elfFile)
{
return ISELF32 (elfFile)
? elf32_getSegmentStringTable(elfFile)
: elf64_getSegmentStringTable(elfFile);
}
char *
elf_getStringTable(void *elfFile, int string_segment)
{
return ISELF32 (elfFile)
? elf32_getStringTable(elfFile)
: elf64_getStringTable(elfFile, string_segment);
}
unsigned
elf_getNumSections(void *elfFile)
{
return ISELF32 (elfFile)
? elf32_getNumSections(elfFile)
: elf64_getNumSections(elfFile);
}
char *
elf_getSectionName(void *elfFile, int i)
{
return ISELF32 (elfFile)
? elf32_getSectionName(elfFile, i)
: elf64_getSectionName(elfFile, i);
}
uint32_t
elf_getSectionFlags(void *elfFile, int i)
{
return ISELF32 (elfFile)
? elf32_getSectionFlags(elfFile, i)
: elf64_getSectionFlags(elfFile, i);
}
uint32_t
elf_getSectionType(void *elfFile, int i)
{
return ISELF32 (elfFile)
? elf32_getSectionType(elfFile, i)
: elf64_getSectionType(elfFile, i);
}
uint64_t
elf_getSectionSize(void *elfFile, int i)
{
return ISELF32 (elfFile)
? elf32_getSectionSize(elfFile, i)
: elf64_getSectionSize(elfFile, i);
}
uint64_t
elf_getSectionAddr(void *elfFile, int i)
{
return ISELF32 (elfFile)
? elf32_getSectionAddr(elfFile, i)
: elf64_getSectionAddr(elfFile, i);
}
void *
elf_getSection(void *elfFile, int i)
{
return ISELF32 (elfFile)
? elf32_getSection(elfFile, i)
: elf64_getSection(elfFile, i);
}
void *
elf_getSectionNamed(void *elfFile, char *_str)
{
return ISELF32 (elfFile)
? elf32_getSectionNamed(elfFile, _str)
: elf64_getSectionNamed(elfFile, _str);
}
void
elf_getProgramHeaderInfo(void *elfFile, uint16_t ph, uint64_t *p_vaddr,
uint64_t *p_paddr, uint64_t *p_filesz, uint64_t *p_offset,
uint64_t *p_memsz)
{
*p_vaddr = elf_getProgramHeaderVaddr(elfFile, ph);
*p_paddr = elf_getProgramHeaderPaddr(elfFile, ph);
*p_filesz = elf_getProgramHeaderFileSize(elfFile, ph);
*p_offset = elf_getProgramHeaderOffset(elfFile, ph);
*p_memsz = elf_getProgramHeaderMemorySize(elfFile, ph);
}
uint64_t
elf_getEntryPoint(void *elfFile)
{
return ISELF32 (elfFile)
? elf32_getEntryPoint (elfFile)
: elf64_getEntryPoint (elfFile);
}
void
elf_fprintf(FILE *f, void *file, int size, const char *name, int flags)
{
elf32_fprintf(f, file, size, name, flags);
}
bool
elf_getMemoryBounds(void *elfFile, bool phys, uint64_t *min, uint64_t *max)
{
uint64_t mem_min = UINT64_MAX;
uint64_t mem_max = 0;
int i;
if (elf_checkFile(elfFile) != 0) {
return false;
}
for(i=0; i < elf_getNumProgramHeaders(elfFile); i++) {
uint64_t sect_min, sect_max;
if (elf_getProgramHeaderMemorySize(elfFile, i) == 0) {
continue;
}
if (phys) {
sect_min = elf_getProgramHeaderPaddr(elfFile, i);
} else {
sect_min = elf_getProgramHeaderVaddr(elfFile, i);
}
sect_max = sect_min + elf_getProgramHeaderMemorySize(elfFile, i);
if (sect_max > mem_max) {
mem_max = sect_max;
}
if (sect_min < mem_min) {
mem_min = sect_min;
}
}
*min = mem_min;
*max = mem_max;
return true;
};
bool
elf_vaddrInProgramHeader(void *elfFile, uint16_t ph, uint64_t vaddr)
{
uint64_t min = elf_getProgramHeaderVaddr(elfFile, ph);
uint64_t max = min + elf_getProgramHeaderMemorySize(elfFile, ph);
if (vaddr >= min && vaddr < max) {
return true;
} else {
return false;
}
}
uint64_t
elf_vtopProgramHeader(void *elfFile, uint16_t ph, uint64_t vaddr)
{
uint64_t ph_phys = elf_getProgramHeaderPaddr(elfFile, ph);
uint64_t ph_virt = elf_getProgramHeaderVaddr(elfFile, ph);
uint64_t paddr;
paddr = vaddr - ph_virt + ph_phys;
return paddr;
}
bool
elf_loadFile(void *elfFile, bool phys)
{
int i;
int num_pheaders;
int pheader_offset;
int pheader_type;
if (elf_checkFile(elfFile) != 0) {
return false;
}
num_pheaders = elf_getNumProgramHeaders(elfFile);
pheader_offset = elf_getProgramHeaderOffset(elfFile, 0);
//printf("Number of program headers: %d\n", num_pheaders);
//printf("Program header offset of first header from file beginning: 0x%p\n",pheader_offset);
for(i=0; i < num_pheaders; i++) {
/* Load that section */
uint64_t dest, src;
uint32_t clrsize;
size_t len;
if (phys) {
dest = elf_getProgramHeaderPaddr(elfFile, i);
// printf("Elf file pheader physical: %p\n", dest);
// printf("Elf file pheader virtual: %p\n",
// elf_getProgramHeaderVaddr(elfFile,i));
} else {
// printf("Elf file pheader virtual: %p\n", dest);
dest = elf_getProgramHeaderVaddr(elfFile, i);
}
len = elf_getProgramHeaderFileSize(elfFile, i);
// printf("This section's size in file: %p\n", len);
src = (uint64_t) (uintptr_t) elfFile + elf_getProgramHeaderOffset(elfFile, i);
// printf("Elf program header offset: %p\n", src);
pheader_type = elf_getProgramHeaderType(elfFile, i);
// printf("Elf program header type: %p\n", pheader_type);
// printf("Copying from %x to %x of size: %p\n", (unsigned int)src, (unsigned int)dest, len);
memcpy((void*) (uintptr_t) dest, (void*) (uintptr_t) src, len);
dest += len;
clrsize = elf_getProgramHeaderMemorySize(elfFile, i) - len;
// printf("Clearing memory... starting from %x, size: %x\n", (unsigned int)dest, clrsize);
memset((void*) (uintptr_t) dest, 0, clrsize);
// printf("Memory cleared.\n");
}
return true;
}

324
libs/elf/src/elf32.c Normal file
View File

@@ -0,0 +1,324 @@
/*
* Australian Public Licence B (OZPLB)
*
* Version 1-0
*
* Copyright (c) 2004 University of New South Wales
*
* All rights reserved.
*
* Developed by: Operating Systems and Distributed Systems Group (DiSy)
* University of New South Wales
* http://www.disy.cse.unsw.edu.au
*
* Permission is granted by University of New South Wales, free of charge, to
* any person obtaining a copy of this software and any associated
* documentation files (the "Software") to deal with the Software without
* restriction, including (without limitation) the rights to use, copy,
* modify, adapt, merge, publish, distribute, communicate to the public,
* sublicense, and/or sell, lend or rent out copies of the Software, and
* to permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimers.
*
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials provided
* with the distribution.
*
* * Neither the name of University of New South Wales, nor the names of its
* contributors, may be used to endorse or promote products derived
* from this Software without specific prior written permission.
*
* EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
* PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
* NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
* WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
* REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
* THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
* ERRORS, WHETHER OR NOT DISCOVERABLE.
*
* TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
* NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
* THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
* LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
* OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
* OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
* OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
* CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
* CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
* DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
* CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
* DAMAGES OR OTHER LIABILITY.
*
* If applicable legislation implies representations, warranties, or
* conditions, or imposes obligations or liability on University of New South
* Wales or one of its contributors in respect of the Software that
* cannot be wholly or partly excluded, restricted or modified, the
* liability of University of New South Wales or the contributor is limited, to
* the full extent permitted by the applicable legislation, at its
* option, to:
* a. in the case of goods, any one or more of the following:
* i. the replacement of the goods or the supply of equivalent goods;
* ii. the repair of the goods;
* iii. the payment of the cost of replacing the goods or of acquiring
* equivalent goods;
* iv. the payment of the cost of having the goods repaired; or
* b. in the case of services:
* i. the supplying of the services again; or
* ii. the payment of the cost of having the services supplied again.
*
* The construction, validity and performance of this licence is governed
* by the laws in force in New South Wales, Australia.
*/
#include <elf/elf.h>
#include <string.h>
#include <inttypes.h>
int
elf32_checkFile(struct Elf32_Header *file)
{
if (file->e_ident[EI_MAG0] != ELFMAG0
|| file->e_ident[EI_MAG1] != ELFMAG1
|| file->e_ident[EI_MAG2] != ELFMAG2
|| file->e_ident[EI_MAG3] != ELFMAG3)
return -1; /* not an elf file */
if (file->e_ident[EI_CLASS] != ELFCLASS32)
return -2; /* not 32-bit file */
return 0; /* elf file looks OK */
}
/*
* Returns the number of program segments in this elf file.
*/
unsigned
elf32_getNumSections(struct Elf32_Header *elfFile)
{
return elfFile->e_shnum;
}
char *
elf32_getStringTable(struct Elf32_Header *elfFile)
{
struct Elf32_Shdr *sections = elf32_getSectionTable(elfFile);
return (char *)elfFile + sections[elfFile->e_shstrndx].sh_offset;
}
/* Returns a pointer to the program segment table, which is an array of
* ELF32_Phdr_t structs. The size of the array can be found by calling
* getNumProgramSegments. */
struct Elf32_Phdr *
elf32_getProgramSegmentTable(struct Elf32_Header *elfFile)
{
struct Elf32_Header *fileHdr = elfFile;
return (struct Elf32_Phdr *) (fileHdr->e_phoff + (long) elfFile);
}
/* Returns the number of program segments in this elf file. */
uint16_t
elf32_getNumProgramHeaders(struct Elf32_Header *elfFile)
{
struct Elf32_Header *fileHdr = elfFile;
return fileHdr->e_phnum;
}
char *
elf32_getSectionName(struct Elf32_Header *elfFile, int i)
{
struct Elf32_Shdr *sections = elf32_getSectionTable(elfFile);
char *str_table = elf32_getSegmentStringTable(elfFile);
if (str_table == NULL) {
return "<corrupted>";
} else {
return str_table + sections[i].sh_name;
}
}
uint32_t
elf32_getSectionSize(struct Elf32_Header *elfFile, int i)
{
struct Elf32_Shdr *sections = elf32_getSectionTable(elfFile);
return sections[i].sh_size;
}
uint32_t
elf32_getSectionAddr(struct Elf32_Header *elfFile, int i)
{
struct Elf32_Shdr *sections = elf32_getSectionTable(elfFile);
return sections[i].sh_addr;
}
void *
elf32_getSection(struct Elf32_Header *elfFile, int i)
{
struct Elf32_Shdr *sections = elf32_getSectionTable(elfFile);
return (char *)elfFile + sections[i].sh_offset;
}
void *
elf32_getSectionNamed(struct Elf32_Header *elfFile, char *str)
{
int numSections = elf32_getNumSections(elfFile);
int i;
for (i = 0; i < numSections; i++) {
if (strcmp(str, elf32_getSectionName(elfFile, i)) == 0) {
return elf32_getSection(elfFile, i);
}
}
return NULL;
}
char *
elf32_getSegmentStringTable(struct Elf32_Header *elfFile)
{
struct Elf32_Header *fileHdr = (struct Elf32_Header *) elfFile;
if (fileHdr->e_shstrndx == 0) {
return NULL;
} else {
return elf32_getStringTable(elfFile);
}
}
#ifdef ELF_DEBUG
void
elf32_printStringTable(struct Elf32_Header *elfFile)
{
int counter;
struct Elf32_Shdr *sections = elf32_getSectionTable(elfFile);
char * stringTable;
if (!sections) {
printf("No sections.\n");
return;
}
stringTable = ((void *)elfFile) + sections[elfFile->e_shstrndx].sh_offset;
printf("File is %p; sections is %p; string table is %p\n", elfFile, sections, stringTable);
for (counter=0; counter < sections[elfFile->e_shstrndx].sh_size; counter++) {
printf("%02x %c ", stringTable[counter],
stringTable[counter] >= 0x20 ? stringTable[counter] : '.');
}
}
#endif
int
elf32_getSegmentType (struct Elf32_Header *elfFile, int segment)
{
return elf32_getProgramSegmentTable(elfFile)[segment].p_type;
}
void
elf32_getSegmentInfo(struct Elf32_Header *elfFile, int segment, uint64_t *p_vaddr, uint64_t *p_addr, uint64_t *p_filesz, uint64_t *p_offset, uint64_t *p_memsz)
{
struct Elf32_Phdr *segments;
segments = elf32_getProgramSegmentTable(elfFile);
*p_addr = segments[segment].p_paddr;
*p_vaddr = segments[segment].p_vaddr;
*p_filesz = segments[segment].p_filesz;
*p_offset = segments[segment].p_offset;
*p_memsz = segments[segment].p_memsz;
}
uint32_t
elf32_getEntryPoint (struct Elf32_Header *elfFile)
{
return elfFile->e_entry;
}
/*
* Debugging functions
*/
/*
* prints out some details of one elf file
*/
void
elf32_fprintf(FILE *f, struct Elf32_Header *file, int size, const char *name, int flags)
{
struct Elf32_Phdr *segments;
unsigned numSegments;
struct Elf32_Shdr *sections;
unsigned numSections;
int i, r;
char *str_table;
fprintf(f, "Found an elf32 file called \"%s\" located "
"at address 0x%p\n", name, file);
if ((r = elf32_checkFile(file)) != 0) {
char *magic = (char*) file;
fprintf(f, "Invalid elf file (%d)\n", r);
fprintf(f, "Magic is: %2.2hhx %2.2hhx %2.2hhx %2.2hhx\n",
magic[0], magic[1], magic[2], magic[3]);
return;
}
/*
* get a pointer to the table of program segments
*/
segments = elf32_getProgramHeaderTable(file);
numSegments = elf32_getNumProgramHeaders(file);
sections = elf32_getSectionTable(file);
numSections = elf32_getNumSections(file);
if ((uintptr_t) sections > ((uintptr_t) file + size)) {
fprintf(f, "Corrupted elfFile..\n");
return;
}
/*
* print out info about each section
*/
if (flags & ELF_PRINT_PROGRAM_HEADERS) {
/*
* print out info about each program segment
*/
fprintf(f, "Program Headers:\n");
fprintf(f, " Type Offset VirtAddr PhysAddr "
"FileSiz MemSiz Flg Align\n");
for (i = 0; i < numSegments; i++) {
if (segments[i].p_type != 1) {
fprintf(f, "segment %d is not loadable, "
"skipping\n", i);
} else {
fprintf(f, " LOAD 0x%06" PRIx32 " 0x%08" PRIx32 " 0x%08" PRIx32 \
" 0x%05" PRIx32" 0x%05" PRIx32 " %c%c%c 0x%04" PRIx32 "\n",
//fprintf(f, " LOAD 0x%" PRIxPTR " 0x%" PRIxPTR " 0x%" PRIxPTR
// " 0x%" PRIxPTR" 0x%" PRIxPTR " %c%c%c 0x%" PRIxPTR "\n",
segments[i].p_offset, segments[i].p_vaddr,
segments[i].p_paddr,
segments[i].p_filesz, segments[i].p_memsz,
segments[i].p_flags & PF_R ? 'R' : ' ',
segments[i].p_flags & PF_W ? 'W' : ' ',
segments[i].p_flags & PF_X ? 'E' : ' ',
segments[i].p_align);
}
}
}
if (flags & ELF_PRINT_SECTIONS) {
str_table = elf32_getSegmentStringTable(file);
printf("Section Headers:\n");
printf(" [Nr] Name Type Addr Off\n");
for (i = 0; i < numSections; i++) {
//if (elf_checkSection(file, i) == 0) {
fprintf(f, "[%2d] %s %x %x\n", i, elf32_getSectionName(file, i),
//fprintf(f, "[%2d] %-17.17s %-15.15s %x %x\n", i, elf32_getSectionName(file, i), " ",
///fprintf(f, "%-17.17s %-15.15s %08x %06x\n", elf32_getSectionName(file, i), " " /* sections[i].sh_type
// */ ,
sections[i].sh_addr, sections[i].sh_offset);
//}
}
}
}

321
libs/elf/src/elf64.c Normal file
View File

@@ -0,0 +1,321 @@
/*
* Australian Public Licence B (OZPLB)
*
* Version 1-0
*
* Copyright (c) 2004 University of New South Wales
*
* All rights reserved.
*
* Developed by: Operating Systems and Distributed Systems Group (DiSy)
* University of New South Wales
* http://www.disy.cse.unsw.edu.au
*
* Permission is granted by University of New South Wales, free of charge, to
* any person obtaining a copy of this software and any associated
* documentation files (the "Software") to deal with the Software without
* restriction, including (without limitation) the rights to use, copy,
* modify, adapt, merge, publish, distribute, communicate to the public,
* sublicense, and/or sell, lend or rent out copies of the Software, and
* to permit persons to whom the Software is furnished to do so, subject
* to the following conditions:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimers.
*
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimers in the documentation and/or other materials provided
* with the distribution.
*
* * Neither the name of University of New South Wales, nor the names of its
* contributors, may be used to endorse or promote products derived
* from this Software without specific prior written permission.
*
* EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
* PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
* NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
* WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
* REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
* THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
* ERRORS, WHETHER OR NOT DISCOVERABLE.
*
* TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
* NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
* THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
* LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
* OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
* OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
* OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
* CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
* CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
* DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
* CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
* DAMAGES OR OTHER LIABILITY.
*
* If applicable legislation implies representations, warranties, or
* conditions, or imposes obligations or liability on University of New South
* Wales or one of its contributors in respect of the Software that
* cannot be wholly or partly excluded, restricted or modified, the
* liability of University of New South Wales or the contributor is limited, to
* the full extent permitted by the applicable legislation, at its
* option, to:
* a. in the case of goods, any one or more of the following:
* i. the replacement of the goods or the supply of equivalent goods;
* ii. the repair of the goods;
* iii. the payment of the cost of replacing the goods or of acquiring
* equivalent goods;
* iv. the payment of the cost of having the goods repaired; or
* b. in the case of services:
* i. the supplying of the services again; or
* ii. the payment of the cost of having the services supplied again.
*
* The construction, validity and performance of this licence is governed
* by the laws in force in New South Wales, Australia.
*/
#include <elf/elf.h>
#include <string.h>
int
elf64_checkFile(void *elfFile)
{
struct Elf64_Header *fileHdr = (struct Elf64_Header *) elfFile;
if (fileHdr->e_ident[EI_MAG0] != ELFMAG0
|| fileHdr->e_ident[EI_MAG1] != ELFMAG1
|| fileHdr->e_ident[EI_MAG2] != ELFMAG2
|| fileHdr->e_ident[EI_MAG3] != ELFMAG3)
return -1; /* not an elf file */
if (fileHdr->e_ident[EI_CLASS] != ELFCLASS64)
return -2; /* not 64-bit file */
#if 0
if (fileHdr->e_ident[EI_DATA] != ELFDATA2LSB)
return -3; /* not big-endian file */
if (fileHdr->e_ident[EI_VERSION] != 1)
return -4; /* wrong version of elf */
if (fileHdr->e_machine != 8)
return -5; /* wrong architecture (not MIPS) */
if (fileHdr->e_type != 2)
return -6; /* not an executable program */
if (fileHdr->e_phentsize != sizeof(struct Elf64_Phdr))
return -7; /* unexpected size of program segment
* header */
if (fileHdr->e_phnum == 0)
return -8; /* no program segments */
if ((fileHdr->e_flags & 0x7e) != 0)
return -9; /* wrong flags (did you forgot to compile
* with -mno-abicalls?) */
#endif
return 0; /* elf file looks OK */
}
struct Elf64_Phdr *
elf64_getProgramSegmentTable(void *elfFile)
/*
* Returns a pointer to the program segment table, which is an array of
* ELF64_Phdr_t structs. The size of the array can be found by calling
* getNumProgramSegments.
*/
{
struct Elf64_Header *fileHdr = (struct Elf64_Header *) elfFile;
return (struct Elf64_Phdr *) ((size_t)fileHdr->e_phoff + (size_t) elfFile);
}
unsigned
elf64_getNumSections(void *elfFile)
/*
* Returns the number of program segments in this elf file.
*/
{
struct Elf64_Header *fileHdr = (struct Elf64_Header *) elfFile;
return fileHdr->e_shnum;
}
char *
elf64_getStringTable(void *elfFile, int string_segment)
{
struct Elf64_Shdr *sections = elf64_getSectionTable(elfFile);
return (char *) elfFile + sections[string_segment].sh_offset;
}
char *
elf64_getSegmentStringTable(void *elfFile)
{
struct Elf64_Header *fileHdr = (struct Elf64_Header *) elfFile;
if (fileHdr->e_shstrndx == 0) {
return NULL;
} else {
return elf64_getStringTable(elfFile, fileHdr->e_shstrndx);
}
}
char *
elf64_getSectionName(void *elfFile, int i)
{
struct Elf64_Shdr *sections = elf64_getSectionTable(elfFile);
char *str_table = elf64_getSegmentStringTable(elfFile);
if (str_table == NULL) {
return "<corrupted>";
} else {
return str_table + sections[i].sh_name;
}
}
uint64_t
elf64_getSectionSize(void *elfFile, int i)
{
struct Elf64_Shdr *sections = elf64_getSectionTable(elfFile);
return sections[i].sh_size;
}
uint64_t
elf64_getSectionAddr(struct Elf64_Header *elfFile, int i)
{
struct Elf64_Shdr *sections = elf64_getSectionTable(elfFile);
return sections[i].sh_addr;
}
void *
elf64_getSection(void *elfFile, int i)
{
struct Elf64_Shdr *sections = elf64_getSectionTable(elfFile);
return (char *)elfFile + sections[i].sh_offset;
}
void *
elf64_getSectionNamed(void *elfFile, char *str)
{
int numSections = elf64_getNumSections(elfFile);
int i;
for (i = 0; i < numSections; i++) {
if (strcmp(str, elf64_getSectionName(elfFile, i)) == 0) {
return elf64_getSection(elfFile, i);
}
}
return NULL;
}
uint16_t
elf64_getNumProgramHeaders(struct Elf64_Header *elfFile)
{
return elfFile->e_phnum;
}
int
elf64_getSegmentType (void *elfFile, int segment)
{
return elf64_getProgramSegmentTable(elfFile)[segment].p_type;
}
void
elf64_getSegmentInfo(void *elfFile, int segment, uint64_t *p_vaddr,
uint64_t *p_paddr, uint64_t *p_filesz, uint64_t *p_offset,
uint64_t *p_memsz)
{
struct Elf64_Phdr *segments;
segments = elf64_getProgramSegmentTable(elfFile);
*p_vaddr = segments[segment].p_vaddr;
*p_paddr = segments[segment].p_paddr;
*p_filesz = segments[segment].p_filesz;
*p_offset = segments[segment].p_offset;
*p_memsz = segments[segment].p_memsz;
}
uint64_t
elf64_getEntryPoint (struct Elf64_Header *elfFile)
{
return elfFile->e_entry;
}
/*
* Debugging functions
*/
#if 0
/*
* prints out some details of one elf file
*/
void
elf64_showDetails(void *elfFile, int size, char *name)
{
struct Elf64_Phdr *segments;
unsigned numSegments;
struct Elf64_Shdr *sections;
unsigned numSections;
int i,
r;
char *str_table;
printf("Found an elf64 file called \"%s\" located "
"at address 0x%lx\n", name, elfFile);
if ((r = elf64_checkFile(elfFile)) != 0) {
char *magic = elfFile;
printf("Invalid elf file (%d)\n", r);
printf("Magic is: %02.2hhx %02.2hhx %02.2hhx %02.2hhx\n",
magic[0], magic[1], magic[2], magic[3]);
return;
}
str_table = elf64_getSegmentStringTable(elfFile);
printf("Got str_table... %p\n", str_table);
/*
* get a pointer to the table of program segments
*/
segments = elf64_getProgramSegmentTable(elfFile);
numSegments = elf64_getNumProgramSegments(elfFile);
sections = elf64_getSectionTable(elfFile);
numSections = elf64_getNumSections(elfFile);
if ((void *) sections > (void *) elfFile + size ||
(((uintptr_t) sections & 0xf) != 0)) {
printf("Corrupted elfFile..\n");
return;
}
printf("Sections: %p\n", sections);
/*
* print out info about each section
*/
/*
* print out info about each program segment
*/
printf("Program Headers:\n");
printf(" Type Offset VirtAddr PhysAddr "
"FileSiz MemSiz Flg Align\n");
for (i = 0; i < numSegments; i++) {
if (segments[i].p_type != 1) {
printf("segment %d is not loadable, "
"skipping\n", i);
} else {
printf(" LOAD 0x%06lx 0x%08lx 0x%08lx"
" 0x%05lx 0x%05lx %c%c%c 0x%04lx\n",
segments[i].p_offset, segments[i].p_vaddr,
segments[i].p_vaddr,
segments[i].p_filesz, segments[i].p_memsz,
segments[i].p_flags & PF_R ? 'R' : ' ',
segments[i].p_flags & PF_W ? 'W' : ' ',
segments[i].p_flags & PF_X ? 'E' : ' ',
segments[i].p_align);
}
}
printf("Section Headers:\n");
printf(" [Nr] Name Type Addr Off\n");
for (i = 0; i < numSections; i++) {
if (elf_checkSection(elfFile, i) == 0) {
printf("%-17.17s %-15.15s %08x %06x\n", elf64_getSectionName(elfFile, i), " " /* sections[i].sh_type
*/ ,
sections[i].sh_addr, sections[i].sh_offset);
}
}
}
#endif