chromium/third_party/nasm/output/outelf.c

/* ----------------------------------------------------------------------- *
 *
 *   Copyright 1996-2019 The NASM Authors - All Rights Reserved
 *   See the file AUTHORS included with the NASM distribution for
 *   the specific copyright holders.
 *
 *   Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following
 *   conditions are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *
 *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ----------------------------------------------------------------------- */

/*
 * Common code for outelf32 and outelf64
 */

#include "compiler.h"


#include "nasm.h"
#include "nasmlib.h"
#include "error.h"
#include "saa.h"
#include "raa.h"
#include "stdscan.h"
#include "eval.h"
#include "outform.h"
#include "outlib.h"
#include "rbtree.h"
#include "hashtbl.h"
#include "ver.h"

#include "dwarf.h"
#include "stabs.h"
#include "outelf.h"
#include "elf.h"

#if defined(OF_ELF32) || defined(OF_ELF64) || defined(OF_ELFX32)

#define SECT_DELTA
static struct elf_section **sects;
static int nsects, sectlen;

#define SHSTR_DELTA
static char *shstrtab;
static int shstrtablen, shstrtabsize;

static struct SAA *syms;
static uint32_t nlocals, nglobs, ndebugs; /* Symbol counts */

static int32_t def_seg;

static struct RAA *bsym;

static struct SAA *symtab, *symtab_shndx;

static struct SAA *strs;
static uint32_t strslen;

static struct RAA *section_by_index;
static struct hash_table section_by_name;

static struct elf_symbol *fwds;

static char elf_module[FILENAME_MAX];

extern const struct ofmt of_elf32;
extern const struct ofmt of_elf64;
extern const struct ofmt of_elfx32;

static struct ELF_SECTDATA {} *elf_sects;

static int elf_nsect, nsections;
static int64_t elf_foffs;

static void elf_write(void);
static void elf_sect_write(struct elf_section *, const void *, size_t);
static void elf_sect_writeaddr(struct elf_section *, int64_t, size_t);
static void elf_section_header(int name, int type, uint64_t flags,
                               void *data, bool is_saa, uint64_t datalen,
                               int link, int info,
                               uint64_t align, uint64_t entsize);
static void elf_write_sections(void);
static size_t elf_build_symtab(void);
static int add_sectname(const char *, const char *);

/* First debugging section index */
static int sec_debug;

struct erel {};

struct symlininfo {};

struct linelist {};

struct sectlist {};

/* common debug variables */
static int currentline =;
static int debug_immcall =;

/* stabs debug variables */
static struct linelist *stabslines =;
static int numlinestabs =;
static char *stabs_filename =;
static uint8_t *stabbuf =, *stabstrbuf =, *stabrelbuf =;
static int stablen, stabstrlen, stabrellen;

/* dwarf debug variables */
static struct linelist *dwarf_flist =, *dwarf_clist =, *dwarf_elist =;
static struct sectlist *dwarf_fsect =, *dwarf_csect =, *dwarf_esect =;
static int dwarf_numfiles =, dwarf_nsections;
static uint8_t *arangesbuf =, *arangesrelbuf =, *pubnamesbuf =, *infobuf =,  *inforelbuf =,
               *abbrevbuf =, *linebuf =, *linerelbuf =, *framebuf =, *locbuf =;
static int8_t line_base =, line_range =, opcode_base =;
static int arangeslen, arangesrellen, pubnameslen, infolen, inforellen,
           abbrevlen, linelen, linerellen, framelen, loclen;
static int64_t dwarf_infosym, dwarf_abbrevsym, dwarf_linesym;

static struct elf_symbol *lastsym;

/* common debugging routines */
static void debug_typevalue(int32_t);

/* stabs debugging routines */
static void stabs_linenum(const char *filename, int32_t linenumber, int32_t);
static void stabs_output(int, void *);
static void stabs_generate(void);
static void stabs_cleanup(void);

/* dwarf debugging routines */

/* This should match the order in elf_write() */
enum dwarf_sect {};

struct dwarf_format {};
const struct dwarf_format *dwfmt;

static void dwarf32_init(void);
static void dwarfx32_init(void);
static void dwarf64_init(void);
static void dwarf_linenum(const char *filename, int32_t linenumber, int32_t);
static void dwarf_output(int, void *);
static void dwarf_generate(void);
static void dwarf_cleanup(void);
static void dwarf_findfile(const char *);
static void dwarf_findsect(const int);

struct elf_format_info {};
static const struct elf_format_info *efmt;

static void elf32_sym(const struct elf_symbol *sym);
static void elf64_sym(const struct elf_symbol *sym);

static struct SAA *elf32_build_reltab(const struct elf_reloc *r);
static struct SAA *elfx32_build_reltab(const struct elf_reloc *r);
static struct SAA *elf64_build_reltab(const struct elf_reloc *r);

static bool dfmt_is_stabs(void);
static bool dfmt_is_dwarf(void);

/*
 * Special NASM section numbers which are used to define ELF special
 * symbols.
 */
static int32_t elf_gotpc_sect, elf_gotoff_sect;
static int32_t elf_got_sect, elf_plt_sect;
static int32_t elf_sym_sect, elf_gottpoff_sect, elf_tlsie_sect;

uint8_t elf_osabi =;      /* Default OSABI = 0 (System V or Linux) */
uint8_t elf_abiver =;     /* Current ABI version */

/* Known sections with nonstandard defaults. -n means n*pointer size. */
struct elf_known_section {};

static const struct elf_known_section elf_known_sections[] =;

struct size_unit {};
static const struct size_unit size_units[] =;

static inline size_t to_bytes(int val)
{}

/* parse section attributes */
static void elf_section_attrib(char *name, char *attr, uint32_t *flags_and, uint32_t *flags_or,
                               uint64_t *alignp, uint64_t *entsize, int *type)
{}

static enum directive_result
elf_directive(enum directive directive, char *value)
{}

static void elf_init(void);

static void elf32_init(void)
{}

static void elfx32_init(void)
{}

static void elf64_init(void)
{}

static void elf_init(void)
{}

static void elf_cleanup(void)
{}

/*
 * Add entry to the elf .shstrtab section and increment nsections.
 * Returns the section index for this new section.
 *
 * IMPORTANT: this needs to match the order the section headers are
 * emitted.
 */
static int add_sectname(const char *firsthalf, const char *secondhalf)
{}

static struct elf_section *
elf_make_section(char *name, int type, int flags, uint64_t align)
{}

static int32_t elf_section_names(char *name, int *bits)
{}

static inline bool sym_type_local(int type)
{}

static void elf_deflabel(char *name, int32_t segment, int64_t offset,
                         int is_global, char *special)
{}

static void elf_add_reloc(struct elf_section *sect, int32_t segment,
                          int64_t offset, int type)
{}

/*
 * This routine deals with ..got and ..sym relocations: the more
 * complicated kinds. In shared-library writing, some relocations
 * with respect to global symbols must refer to the precise symbol
 * rather than referring to an offset from the base of the section
 * _containing_ the symbol. Such relocations call to this routine,
 * which searches the symbol list for the symbol in question.
 *
 * R_386_GOT32 | R_X86_64_GOT32 references require the _exact_ symbol address to be
 * used; R_386_32 | R_X86_64_32 references can be at an offset from the symbol.
 * The boolean argument `exact' tells us this.
 *
 * Return value is the adjusted value of `addr', having become an
 * offset from the symbol rather than the section. Should always be
 * zero when returning from an exact call.
 *
 * Limitation: if you define two symbols at the same place,
 * confusion will occur.
 *
 * Inefficiency: we search, currently, using a linked list which
 * isn't even necessarily sorted.
 */
static int64_t elf_add_gsym_reloc(struct elf_section *sect,
                                  int32_t segment, uint64_t offset,
                                  int64_t pcrel, int type, bool exact)
{}

static void elf32_out(int32_t segto, const void *data,
                      enum out_type type, uint64_t size,
                      int32_t segment, int32_t wrt)
{}
static void elf64_out(int32_t segto, const void *data,
                      enum out_type type, uint64_t size,
                      int32_t segment, int32_t wrt)
{}

static void elfx32_out(int32_t segto, const void *data,
                       enum out_type type, uint64_t size,
                       int32_t segment, int32_t wrt)
{}

/*
 * Section index/count with a specified overflow value (usually SHN_INDEX,
 * but 0 for e_shnum.
 */
static inline uint16_t elf_shndx(int section, uint16_t overflow)
{}

struct ehdr_common {};

ehdr;

static void elf_write(void)
{}

static size_t nsyms;

static void elf_sym(const struct elf_symbol *sym)
{}

static void elf32_sym(const struct elf_symbol *sym)
{}

static void elf64_sym(const struct elf_symbol *sym)
{}

static size_t elf_build_symtab(void)
{}

static struct SAA *elf32_build_reltab(const struct elf_reloc *r)
{}

static struct SAA *elfx32_build_reltab(const struct elf_reloc *r)
{}

static struct SAA *elf64_build_reltab(const struct elf_reloc *r)
{}

static void elf_section_header(int name, int type, uint64_t flags,
                               void *data, bool is_saa, uint64_t datalen,
                               int link, int info,
                               uint64_t align, uint64_t entsize)
{}

static void elf_write_sections(void)
{}

static void elf_sect_write(struct elf_section *sect, const void *data, size_t len)
{}

static void elf_sect_writeaddr(struct elf_section *sect, int64_t data, size_t len)
{}

static void elf_sectalign(int32_t seg, unsigned int value)
{}

extern macros_t elf_stdmac[];

/* Claim "elf" as a pragma namespace, for the future */
static const struct pragma_facility elf_pragma_list[] =;


static const struct dfmt elf32_df_dwarf =;

static const struct dfmt elf32_df_stabs =;

static const struct dfmt * const elf32_debugs_arr[3] =;

const struct ofmt of_elf32 =;

static const struct dfmt elf64_df_dwarf =;

static const struct dfmt elf64_df_stabs =;

static const struct dfmt * const elf64_debugs_arr[3] =;

const struct ofmt of_elf64 =;

static const struct dfmt elfx32_df_dwarf =;

static const struct dfmt elfx32_df_stabs =;

static const struct dfmt * const elfx32_debugs_arr[3] =;

const struct ofmt of_elfx32 =;

static bool is_elf64(void)
{}

static bool is_elf32(void)
{}

static bool is_elfx32(void)
{}

static bool dfmt_is_stabs(void)
{}

static bool dfmt_is_dwarf(void)
{}

/* common debugging routines */
static void debug_typevalue(int32_t type)
{}

/* stabs debugging routines */

static void stabs_linenum(const char *filename, int32_t linenumber, int32_t segto)
{}

static void stabs_output(int type, void *param)
{}

/* for creating the .stab , .stabstr and .rel.stab sections in memory */

static void stabs_generate(void)
{}

static void stabs_cleanup(void)
{}

/* dwarf routines */

static void dwarf_init_common(const struct dwarf_format *fmt)
{}

static void dwarf32_init(void)
{}

static void dwarfx32_init(void)
{}

static void dwarf64_init(void)
{}

static void dwarf_linenum(const char *filename, int32_t linenumber,
                            int32_t segto)
{}

/* called from elf_out with type == TY_DEBUGSYMLIN */
static void dwarf_output(int type, void *param)
{}


static void dwarf_generate(void)
{}

static void dwarf_cleanup(void)
{}

static void dwarf_findfile(const char * fname)
{}

static void dwarf_findsect(const int index)
{}

#endif /* defined(OF_ELF32) || defined(OF_ELF64) || defined(OF_ELFX32) */