image_private.h 9.09 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
/*
 * 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
 */

#define IMAGE_NO_MAP  ((void*)-1)

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
struct elf_header
{
    UINT8   e_ident[16];  /* Magic number and other info */
    UINT16  e_type;       /* Object file type */
    UINT16  e_machine;    /* Architecture */
    UINT32  e_version;    /* Object file version */
    UINT64  e_entry;      /* Entry point virtual address */
    UINT64  e_phoff;      /* Program header table file offset */
    UINT64  e_shoff;      /* Section header table file offset */
    UINT32  e_flags;      /* Processor-specific flags */
    UINT16  e_ehsize;     /* ELF header size in bytes */
    UINT16  e_phentsize;  /* Program header table entry size */
    UINT16  e_phnum;      /* Program header table entry count */
    UINT16  e_shentsize;  /* Section header table entry size */
    UINT16  e_shnum;      /* Section header table entry count */
    UINT16  e_shstrndx;   /* Section header string table index */
};

42 43 44 45 46 47 48 49 50 51 52 53 54 55
struct elf_section_header
{
    UINT32  sh_name;       /* Section name (string tbl index) */
    UINT32  sh_type;       /* Section type */
    UINT64  sh_flags;      /* Section flags */
    UINT64  sh_addr;       /* Section virtual addr at execution */
    UINT64  sh_offset;     /* Section file offset */
    UINT64  sh_size;       /* Section size in bytes */
    UINT32  sh_link;       /* Link to another section */
    UINT32  sh_info;       /* Additional section information */
    UINT64  sh_addralign;  /* Section alignment */
    UINT64  sh_entsize;    /* Entry size if section holds table */
};

56 57 58 59 60 61 62 63 64 65 66 67 68
struct macho_load_command
{
    UINT32  cmd;           /* type of load command */
    UINT32  cmdsize;       /* total size of command in bytes */
};

struct macho_uuid_command
{
    UINT32  cmd;           /* LC_UUID */
    UINT32  cmdsize;
    UINT8   uuid[16];
};

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
struct macho_section
{
    char    sectname[16];  /* name of this section */
    char    segname[16];   /* segment this section goes in */
    UINT64  addr;          /* memory address of this section */
    UINT64  size;          /* size in bytes of this section */
    UINT32  offset;        /* file offset of this section */
    UINT32  align;         /* section alignment (power of 2) */
    UINT32  reloff;        /* file offset of relocation entries */
    UINT32  nreloc;        /* number of relocation entries */
    UINT32  flags;         /* flags (section type and attributes)*/
    UINT32  reserved1;     /* reserved (for offset or index) */
    UINT32  reserved2;     /* reserved (for count or sizeof) */
    UINT32  reserved3;     /* reserved */
};

struct macho_section32
{
    char    sectname[16];  /* name of this section */
    char    segname[16];   /* segment this section goes in */
    UINT32  addr;          /* memory address of this section */
    UINT32  size;          /* size in bytes of this section */
    UINT32  offset;        /* file offset of this section */
    UINT32  align;         /* section alignment (power of 2) */
    UINT32  reloff;        /* file offset of relocation entries */
    UINT32  nreloc;        /* number of relocation entries */
    UINT32  flags;         /* flags (section type and attributes)*/
    UINT32  reserved1;     /* reserved (for offset or index) */
    UINT32  reserved2;     /* reserved (for count or sizeof) */
};

100 101 102
/* structure holding information while handling an ELF image
 * allows one by one section mapping for memory savings
 */
103
struct image_file_map
104
{
105
    enum module_type            modtype;
106
    const struct image_file_map_ops *ops;
107
    unsigned                    addr_size;      /* either 16 (not used), 32 or 64 */
108
    struct image_file_map*      alternate;      /* another file linked to this one */
109
    union
110
    {
111 112 113 114
        struct elf_file_map
        {
            size_t                      elf_size;
            size_t                      elf_start;
115
            HANDLE                      handle;
116
            const char*	                shstrtab;
117
            char*                       target_copy;
118
            struct elf_header           elfhdr;
119 120
            struct
            {
121
                struct elf_section_header       shdr;
122 123 124
                const char*                     mapped;
            }*                          sect;
        } elf;
125 126 127 128
        struct macho_file_map
        {
            size_t                      segs_size;
            size_t                      segs_start;
129
            HANDLE                      handle;
130
            struct image_file_map*      dsym;   /* the debug symbols file associated with this one */
131 132
            size_t                      header_size; /* size of real header in file */
            size_t                      commands_size;
133
            unsigned int                commands_count;
134

135 136
            const struct macho_load_command*    load_commands;
            const struct macho_uuid_command*    uuid;
137 138 139 140 141 142 143 144

            /* The offset in the file which is this architecture.  mach_header was
             * read from arch_offset. */
            unsigned                    arch_offset;

            int                         num_sections;
            struct
            {
145
                struct macho_section            section;
146
                const char*                     mapped;
147
                unsigned int                    ignored : 1;
148 149
            }*                          sect;
        } macho;
150 151 152
        struct pe_file_map
        {
            HANDLE                      hMap;
153
            IMAGE_FILE_HEADER           file_header;
154 155 156 157 158
            union
            {
                IMAGE_OPTIONAL_HEADER32 header32;
                IMAGE_OPTIONAL_HEADER64 header64;
            } opt;
159
            BOOL                        builtin;
160 161 162 163 164 165 166 167 168 169
            unsigned                    full_count;
            void*                       full_map;
            struct
            {
                IMAGE_SECTION_HEADER            shdr;
                const char*                     mapped;
            }*                          sect;
            const char*	                strtable;
        } pe;
    } u;
170
};
171

172
struct image_section_map
173
{
174
    struct image_file_map*      fmap;
175
    LONG_PTR                    sidx;
176 177
};

178 179 180 181 182 183 184 185 186
struct stab_nlist
{
    unsigned            n_strx;
    unsigned char       n_type;
    char                n_other;
    short               n_desc;
    unsigned            n_value;
};

187 188 189 190 191 192 193 194 195
struct macho64_nlist
{
    unsigned            n_strx;
    unsigned char       n_type;
    char                n_other;
    short               n_desc;
    UINT64              n_value;
};

196
BOOL image_check_alternate(struct image_file_map* fmap, const struct module* module) DECLSPEC_HIDDEN;
197
struct image_file_map* image_load_debugaltlink(struct image_file_map* fmap, struct module* module) DECLSPEC_HIDDEN;
198 199

BOOL elf_map_handle(HANDLE handle, struct image_file_map* fmap) DECLSPEC_HIDDEN;
200
BOOL pe_map_file(HANDLE file, struct image_file_map* fmap, enum module_type mt) DECLSPEC_HIDDEN;
201

202 203 204 205 206 207 208
struct image_file_map_ops
{
    const char* (*map_section)(struct image_section_map* ism);
    void  (*unmap_section)(struct image_section_map* ism);
    BOOL (*find_section)(struct image_file_map* fmap, const char* name, struct image_section_map* ism);
    DWORD_PTR (*get_map_rva)(const struct image_section_map* ism);
    unsigned (*get_map_size)(const struct image_section_map* ism);
209
    void (*unmap_file)(struct image_file_map *fmap);
210
};
211 212 213

static inline BOOL image_find_section(struct image_file_map* fmap, const char* name,
                                      struct image_section_map* ism)
214
{
215
    while (fmap)
216
    {
217
        if (fmap->ops->find_section(fmap, name, ism)) return TRUE;
218
        fmap = fmap->alternate;
219
    }
220 221 222
    ism->fmap = NULL;
    ism->sidx = -1;
    return FALSE;
223 224
}

225 226 227 228 229 230 231 232 233
static inline void image_unmap_file(struct image_file_map* fmap)
{
    while (fmap)
    {
        fmap->ops->unmap_file(fmap);
        fmap = fmap->alternate;
    }
}

234 235
static inline const char* image_map_section(struct image_section_map* ism)
{
236
    return ism->fmap ? ism->fmap->ops->map_section(ism) : NULL;
237
}
238

239 240
static inline void image_unmap_section(struct image_section_map* ism)
{
241
    if (ism->fmap) ism->fmap->ops->unmap_section(ism);
242
}
243

244
static inline DWORD_PTR image_get_map_rva(const struct image_section_map* ism)
245
{
246
    return ism->fmap ? ism->fmap->ops->get_map_rva(ism) : 0;
247 248
}

249
static inline unsigned image_get_map_size(const struct image_section_map* ism)
250
{
251
    return ism->fmap ? ism->fmap->ops->get_map_size(ism) : 0;
252
}