image_private.h 5.96 KB
Newer Older
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
/*
 * File elf_private.h - definitions for processing of ELF files
 *
 * Copyright (C) 1996, Eric Youngdale.
 *		 1999-2007 Eric Pouech
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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 A 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
 */

#ifdef HAVE_ELF_H
# include <elf.h>
#endif
#ifdef HAVE_SYS_ELF32_H
# include <sys/elf32.h>
#endif
#ifdef HAVE_SYS_EXEC_ELF_H
# include <sys/exec_elf.h>
#endif
#if !defined(DT_NUM)
# if defined(DT_COUNT)
#  define DT_NUM DT_COUNT
# else
/* this seems to be a satisfactory value on Solaris, which doesn't support this AFAICT */
#  define DT_NUM 24
# endif
#endif
#ifdef HAVE_LINK_H
# include <link.h>
#endif
#ifdef HAVE_SYS_LINK_H
# include <sys/link.h>
#endif

#define IMAGE_NO_MAP  ((void*)-1)

#ifdef __ELF__

#ifdef _WIN64
#define         Elf_Ehdr        Elf64_Ehdr
#define         Elf_Shdr        Elf64_Shdr
#define         Elf_Phdr        Elf64_Phdr
#define         Elf_Dyn         Elf64_Dyn
#define         Elf_Sym         Elf64_Sym
56
#define         Elf_auxv_t      Elf64_auxv_t
57 58 59 60 61 62
#else
#define         Elf_Ehdr        Elf32_Ehdr
#define         Elf_Shdr        Elf32_Shdr
#define         Elf_Phdr        Elf32_Phdr
#define         Elf_Dyn         Elf32_Dyn
#define         Elf_Sym         Elf32_Sym
63
#define         Elf_auxv_t      Elf32_auxv_t
64
#endif
65 66 67 68 69
#else
#ifndef SHT_NULL
#define SHT_NULL        0
#endif
#endif
70 71 72 73

/* structure holding information while handling an ELF image
 * allows one by one section mapping for memory savings
 */
74
struct image_file_map
75
{
76
    enum module_type            modtype;
77
    unsigned                    addr_size;      /* either 16 (not used), 32 or 64 */
78
    union
79
    {
80 81 82 83 84 85 86
        struct elf_file_map
        {
            size_t                      elf_size;
            size_t                      elf_start;
            int                         fd;
            const char*	                shstrtab;
            struct image_file_map*      alternate;      /* another ELF file (linked to this one) */
87
            char*                       target_copy;
88 89 90 91 92 93 94
#ifdef __ELF__
            Elf_Ehdr                    elfhdr;
            struct
            {
                Elf_Shdr                        shdr;
                const char*                     mapped;
            }*                          sect;
95
#endif
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
        } elf;
        struct pe_file_map
        {
            HANDLE                      hMap;
            IMAGE_NT_HEADERS            ntheader;
            unsigned                    full_count;
            void*                       full_map;
            struct
            {
                IMAGE_SECTION_HEADER            shdr;
                const char*                     mapped;
            }*                          sect;
            const char*	                strtable;
        } pe;
    } u;
111
};
112

113
struct image_section_map
114
{
115
    struct image_file_map*      fmap;
116 117 118
    long                        sidx;
};

119
extern BOOL         elf_find_section(struct image_file_map* fmap, const char* name,
120 121 122 123 124
                                     unsigned sht, struct image_section_map* ism) DECLSPEC_HIDDEN;
extern const char*  elf_map_section(struct image_section_map* ism) DECLSPEC_HIDDEN;
extern void         elf_unmap_section(struct image_section_map* ism) DECLSPEC_HIDDEN;
extern DWORD_PTR    elf_get_map_rva(const struct image_section_map* ism) DECLSPEC_HIDDEN;
extern unsigned     elf_get_map_size(const struct image_section_map* ism) DECLSPEC_HIDDEN;
125 126

extern BOOL         pe_find_section(struct image_file_map* fmap, const char* name,
127 128 129 130 131
                                    struct image_section_map* ism) DECLSPEC_HIDDEN;
extern const char*  pe_map_section(struct image_section_map* psm) DECLSPEC_HIDDEN;
extern void         pe_unmap_section(struct image_section_map* psm) DECLSPEC_HIDDEN;
extern DWORD_PTR    pe_get_map_rva(const struct image_section_map* psm) DECLSPEC_HIDDEN;
extern unsigned     pe_get_map_size(const struct image_section_map* psm) DECLSPEC_HIDDEN;
132 133 134

static inline BOOL image_find_section(struct image_file_map* fmap, const char* name,
                                      struct image_section_map* ism)
135
{
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
    switch (fmap->modtype)
    {
    case DMT_ELF: return elf_find_section(fmap, name, SHT_NULL, ism);
    case DMT_PE:  return pe_find_section(fmap, name, ism);
    default: assert(0); return FALSE;
    }
}

static inline const char* image_map_section(struct image_section_map* ism)
{
    if (!ism->fmap) return NULL;
    switch (ism->fmap->modtype)
    {
    case DMT_ELF: return elf_map_section(ism);
    case DMT_PE:  return pe_map_section(ism);
    default: assert(0); return NULL;
    }
}
154

155 156 157 158 159 160 161 162 163 164
static inline void image_unmap_section(struct image_section_map* ism)
{
    if (!ism->fmap) return;
    switch (ism->fmap->modtype)
    {
    case DMT_ELF: elf_unmap_section(ism); break;
    case DMT_PE:  pe_unmap_section(ism);   break;
    default: assert(0); return;
    }
}
165

166
static inline DWORD_PTR image_get_map_rva(const struct image_section_map* ism)
167 168 169 170 171 172 173 174 175 176
{
    if (!ism->fmap) return 0;
    switch (ism->fmap->modtype)
    {
    case DMT_ELF: return elf_get_map_rva(ism);
    case DMT_PE:  return pe_get_map_rva(ism);
    default: assert(0); return 0;
    }
}

177
static inline unsigned image_get_map_size(const struct image_section_map* ism)
178 179 180 181 182 183 184 185 186
{
    if (!ism->fmap) return 0;
    switch (ism->fmap->modtype)
    {
    case DMT_ELF: return elf_get_map_size(ism);
    case DMT_PE:  return pe_get_map_size(ism);
    default: assert(0); return 0;
    }
}