1/*
2 * ELF object machine specific format helpers
3 *
4 *  Copyright (C) 2004-2007  Michael Urman
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifndef ELF_MACHINE_H_INCLUDED
29#define ELF_MACHINE_H_INCLUDED
30
31#define YASM_WRITE_32I_L(p, i) do {\
32    assert(yasm_intnum_check_size(i, 32, 0, 2)); \
33    yasm_intnum_get_sized(i, p, 4, 32, 0, 0, 0); \
34    p += 4; } while (0)
35
36#define YASM_WRITE_64I_L(p, i) do {\
37    assert(yasm_intnum_check_size(i, 64, 0, 2)); \
38    yasm_intnum_get_sized(i, p, 8, 64, 0, 0, 0); \
39    p += 8; } while (0)
40
41#define YASM_WRITE_64C_L(p, hi, lo) do {\
42    YASM_WRITE_32_L(p, lo); \
43    YASM_WRITE_32_L(p, hi); } while (0)
44
45#define YASM_WRITE_64Z_L(p, i)          YASM_WRITE_64C_L(p, 0, i)
46
47typedef int(*func_accepts_reloc)(size_t val, yasm_symrec *wrt);
48typedef void(*func_write_symtab_entry)(unsigned char *bufp,
49                                       elf_symtab_entry *entry,
50                                       yasm_intnum *value_intn,
51                                       yasm_intnum *size_intn);
52typedef void(*func_write_secthead)(unsigned char *bufp, elf_secthead *shead);
53typedef void(*func_write_secthead_rel)(unsigned char *bufp,
54                                       elf_secthead *shead,
55                                       elf_section_index symtab_idx,
56                                       elf_section_index sindex);
57
58typedef void(*func_handle_reloc_addend)(yasm_intnum *intn,
59                                        elf_reloc_entry *reloc,
60                                        unsigned long offset);
61typedef unsigned int(*func_map_reloc_info_to_type)(elf_reloc_entry *reloc);
62typedef void(*func_write_reloc)(unsigned char *bufp,
63                                elf_reloc_entry *reloc,
64                                unsigned int r_type,
65                                unsigned int r_sym);
66typedef void (*func_write_proghead)(unsigned char **bufpp,
67                                    elf_offset secthead_addr,
68                                    unsigned long secthead_count,
69                                    elf_section_index shstrtab_index);
70
71enum {
72    ELF_SSYM_SYM_RELATIVE = 1 << 0,
73    ELF_SSYM_CURPOS_ADJUST = 1 << 1,
74    ELF_SSYM_THREAD_LOCAL = 1 << 2
75};
76
77typedef struct {
78    const char *name;       /* should be something like ..name */
79    const int sym_rel;      /* symbol or section-relative? */
80    const unsigned int reloc;   /* relocation type */
81    const unsigned int size;    /* legal data size */
82} elf_machine_ssym;
83
84struct elf_machine_handler {
85    const char *arch;
86    const char *machine;
87    const char *reloc_section_prefix;
88    const unsigned long symtab_entry_size;
89    const unsigned long symtab_entry_align;
90    const unsigned long reloc_entry_size;
91    const unsigned long secthead_size;
92    const unsigned long proghead_size;
93    func_accepts_reloc accepts_reloc;
94    func_write_symtab_entry write_symtab_entry;
95    func_write_secthead write_secthead;
96    func_write_secthead_rel write_secthead_rel;
97    func_handle_reloc_addend handle_reloc_addend;
98    func_map_reloc_info_to_type map_reloc_info_to_type;
99    func_write_reloc write_reloc;
100    func_write_proghead write_proghead;
101
102    elf_machine_ssym *ssyms;            /* array of "special" syms */
103    const size_t num_ssyms;             /* size of array */
104
105    const int bits;                     /* usually 32 or 64 */
106};
107
108#endif /* ELF_MACHINE_H_INCLUDED */
109