1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
/*
Title: Export memory as an ELF object file
Author: David C. J. Matthews.
Copyright (c) 2006, 2016 David C. J. Matthews
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License version 2.1 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR H PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ELFExport_H_INCLUDED
#define ELFExport_H_INCLUDED
#include "config.h"
#include "scanaddrs.h" // For base class
#include "exporter.h"
#ifdef HAVE_ELF_H
#include <elf.h>
#endif
#ifdef HAVE_ELF_ABI_H
#include <elf_abi.h>
#endif
// Select 32 or 64 bit version depending on the word length
#if (SIZEOF_VOIDP == 8)
#define ElfXX_Addr Elf64_Addr
#define ElfXX_Rel Elf64_Rel
#define ElfXX_Rela Elf64_Rela
#define ElfXX_Sym Elf64_Sym
#define ElfXX_Ehdr Elf64_Ehdr
#define ElfXX_Shdr Elf64_Shdr
// Include a cast on the next line. Linux includes this anyway but it's needed for FreeBSD.
#define ELFXX_R_INFO(_y, _z) ELF64_R_INFO((Elf64_Xword)(_y), _z)
#define ELFXX_ST_INFO(_y, _z) ELF64_ST_INFO(_y, _z)
#define ELFCLASSXX ELFCLASS64
#else
#define ElfXX_Addr Elf32_Addr
#define ElfXX_Rel Elf32_Rel
#define ElfXX_Rela Elf32_Rela
#define ElfXX_Sym Elf32_Sym
#define ElfXX_Ehdr Elf32_Ehdr
#define ElfXX_Shdr Elf32_Shdr
#define ELFXX_R_INFO(_y, _z) ELF32_R_INFO(_y, _z)
#define ELFXX_ST_INFO(_y, _z) ELF32_ST_INFO(_y, _z)
#define ELFCLASSXX ELFCLASS32
#endif
#ifdef HOSTARCHITECTURE_MIPS64
/* MIPS N64 ABI has a different Elf64_Rel/Rela layout */
typedef struct
{
Elf64_Addr r_offset; /* Address */
Elf64_Word r_sym; /* Symbol index */
unsigned char r_ssym; /* Special symbol */
unsigned char r_type3; /* Third relocation type */
unsigned char r_type2; /* Second relocation type */
unsigned char r_type; /* First relocation type */
} Elf64_Mips_Rel;
typedef struct
{
Elf64_Addr r_offset; /* Address */
Elf64_Word r_sym; /* Symbol index */
unsigned char r_ssym; /* Special symbol */
unsigned char r_type3; /* Third relocation type */
unsigned char r_type2; /* Second relocation type */
unsigned char r_type; /* First relocation type */
Elf64_Sxword r_addend; /* Addend */
} Elf64_Mips_Rela;
#undef ElfXX_Rel
#define ElfXX_Rel Elf64_Mips_Rel
#undef ElfXX_Rela
#define ElfXX_Rela Elf64_Mips_Rela
/* Elf64_Mips_Rel/Rela has no r_info, so this macro is meaningless */
#undef ELFXX_R_INFO
#endif
class TaskData;
class ELFExport: public Exporter, public ScanAddress
{
public:
ELFExport(): relocationCount(0), symbolNum(0) {}
public:
virtual void exportStore(void);
private:
// ScanAddress overrides
virtual void ScanConstant(PolyObject *base, byte *addrOfConst, ScanRelocationKind code);
// At the moment we should only get calls to ScanConstant.
virtual PolyObject *ScanObjectAddress(PolyObject *base) { return base; }
virtual void addExternalReference(void *addr, const char *name);
private:
void setRelocationAddress(void *p, ElfXX_Addr *reloc);
PolyWord createRelocation(PolyWord p, void *relocAddr);
PolyWord writeRelocation(POLYUNSIGNED offset, void *relocAddr, unsigned symbolNum, bool isFuncPtr);
void writeSymbol(const char *symbolName, long value, long size, int binding, int sttype, int section);
unsigned long makeStringTableEntry(const char *str, ExportStringTable *stab);
void alignFile(int align);
void createStructsRelocation(unsigned area, POLYUNSIGNED offset, POLYSIGNED addend);
unsigned relocationCount;
// There are two tables - one is used for section names, the other for symbol names.
ExportStringTable symStrings, sectionStrings;
// Table and count for external references.
ExportStringTable externTable;
unsigned symbolNum;
};
#endif
|