1d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org/*
245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ELF object machine specific format helpers
345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *  Copyright (C) 2004-2007  Michael Urman
545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Redistribution and use in source and binary forms, with or without
745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * modification, are permitted provided that the following conditions
845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * are met:
945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 1. Redistributions of source code must retain the above copyright
1045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    notice, this list of conditions and the following disclaimer.
1145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 2. Redistributions in binary form must reproduce the above copyright
1245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    notice, this list of conditions and the following disclaimer in the
1345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    documentation and/or other materials provided with the distribution.
1445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
1545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
1645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
1945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * POSSIBILITY OF SUCH DAMAGE.
2645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
2745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
2845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#ifndef ELF_MACHINE_H_INCLUDED
2945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define ELF_MACHINE_H_INCLUDED
3045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define YASM_WRITE_32I_L(p, i) do {\
3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    assert(yasm_intnum_check_size(i, 32, 0, 2)); \
3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum_get_sized(i, p, 4, 32, 0, 0, 0); \
3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    p += 4; } while (0)
3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define YASM_WRITE_64I_L(p, i) do {\
3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    assert(yasm_intnum_check_size(i, 64, 0, 2)); \
3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum_get_sized(i, p, 8, 64, 0, 0, 0); \
3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    p += 8; } while (0)
4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define YASM_WRITE_64C_L(p, hi, lo) do {\
4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    YASM_WRITE_32_L(p, lo); \
4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    YASM_WRITE_32_L(p, hi); } while (0)
4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define YASM_WRITE_64Z_L(p, i)          YASM_WRITE_64C_L(p, 0, i)
4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
47a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.orgtypedef int(*func_accepts_reloc)(size_t val, yasm_symrec *wrt);
4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef void(*func_write_symtab_entry)(unsigned char *bufp,
4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                       elf_symtab_entry *entry,
5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                       yasm_intnum *value_intn,
5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                       yasm_intnum *size_intn);
5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef void(*func_write_secthead)(unsigned char *bufp, elf_secthead *shead);
5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef void(*func_write_secthead_rel)(unsigned char *bufp,
5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                       elf_secthead *shead,
5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                       elf_section_index symtab_idx,
5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                       elf_section_index sindex);
5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef void(*func_handle_reloc_addend)(yasm_intnum *intn,
59a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                                        elf_reloc_entry *reloc,
60a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.org                                        unsigned long offset);
61a1b5233e6d340f45f4846131fec9d0b92e203ce4hbono@chromium.orgtypedef unsigned int(*func_map_reloc_info_to_type)(elf_reloc_entry *reloc);
6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef void(*func_write_reloc)(unsigned char *bufp,
6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                elf_reloc_entry *reloc,
6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                unsigned int r_type,
6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                unsigned int r_sym);
6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef void (*func_write_proghead)(unsigned char **bufpp,
6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                    elf_offset secthead_addr,
6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                    unsigned long secthead_count,
6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                    elf_section_index shstrtab_index);
7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgenum {
7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    ELF_SSYM_SYM_RELATIVE = 1 << 0,
7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    ELF_SSYM_CURPOS_ADJUST = 1 << 1,
7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    ELF_SSYM_THREAD_LOCAL = 1 << 2
7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org};
7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct {
7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const char *name;       /* should be something like ..name */
7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const int sym_rel;      /* symbol or section-relative? */
8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const unsigned int reloc;   /* relocation type */
8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const unsigned int size;    /* legal data size */
8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} elf_machine_ssym;
8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstruct elf_machine_handler {
8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const char *arch;
8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const char *machine;
8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const char *reloc_section_prefix;
8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const unsigned long symtab_entry_size;
8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const unsigned long symtab_entry_align;
9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const unsigned long reloc_entry_size;
9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const unsigned long secthead_size;
9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const unsigned long proghead_size;
9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    func_accepts_reloc accepts_reloc;
9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    func_write_symtab_entry write_symtab_entry;
9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    func_write_secthead write_secthead;
9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    func_write_secthead_rel write_secthead_rel;
9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    func_handle_reloc_addend handle_reloc_addend;
9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    func_map_reloc_info_to_type map_reloc_info_to_type;
9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    func_write_reloc write_reloc;
10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    func_write_proghead write_proghead;
10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
102d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org    elf_machine_ssym *ssyms;            /* array of "special" syms */
10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const size_t num_ssyms;             /* size of array */
10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const int bits;                     /* usually 32 or 64 */
10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org};
10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif /* ELF_MACHINE_H_INCLUDED */
109