X-Git-Url: https://oss.titaniummirror.com/gitweb?p=msp430-binutils.git;a=blobdiff_plain;f=gas%2Fconfig%2Fobj-coff-seh.h;fp=gas%2Fconfig%2Fobj-coff-seh.h;h=aa151cd9fdeb899f9194a870f54f609b317f5c21;hp=0000000000000000000000000000000000000000;hb=d5da4f291af551c0b8b79e1d4a9b173d60e5c10e;hpb=7b5ea4fcdf2819e070665ab5610f8b48e3867c10 diff --git a/gas/config/obj-coff-seh.h b/gas/config/obj-coff-seh.h new file mode 100644 index 0000000..aa151cd --- /dev/null +++ b/gas/config/obj-coff-seh.h @@ -0,0 +1,234 @@ +/* seh pdata/xdata coff object file format + Copyright 2009 + Free Software Foundation, Inc. + + This file is part of GAS. + + GAS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GAS 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GAS; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ + +/* Short overview: + There are at the moment three different function entry formats preset. + The first is the MIPS one. The second version + is for ARM, PPC, SH3, and SH4 mainly for Windows CE. + The third is the IA64 and x64 version. Note, the IA64 isn't implemented yet, + but to find information about it, please see specification about IA64 on + http://download.intel.com/design/Itanium/Downloads/245358.pdf file. + + The first version has just entries in the pdata section: BeginAddress, + EndAddress, ExceptionHandler, HandlerData, and PrologueEndAddress. Each + value is a pointer to the corresponding data and has size of 4 bytes. + + The second variant has the following entries in the pdata section. + BeginAddress, PrologueLength (8 bits), EndAddress (22 bits), + Use-32-bit-instruction (1 bit), and Exception-Handler-Exists (1 bit). + If the FunctionLength is zero, or the Exception-Handler-Exists bit + is true, a PDATA_EH block is placed directly before function entry. + + The third version has a function entry block of BeginAddress (RVA), + EndAddress (RVA), and UnwindData (RVA). The description of the + prologue, excepetion-handler, and additional SEH data is stored + within the UNWIND_DATA field in the xdata section. + + The pseudos: + .seh_proc + .seh_endprologue + .seh_handler [,]] + .seh_eh + .seh_32/.seh_no32 + .seh_endproc + .seh_setframe , + .seh_stackalloc + .seh_pushreg + .seh_savereg + .seh_savemm + .seh_savexmm + .seh_pushframe + .seh_scope + */ + +/* architecture specific pdata/xdata handling. */ +#define SEH_CMDS \ + {"seh_proc", obj_coff_seh_proc, 0}, \ + {"seh_endproc", obj_coff_seh_endproc, 0}, \ + {"seh_pushreg", obj_coff_seh_push, 0}, \ + {"seh_savereg", obj_coff_seh_save, 0}, \ + {"seh_savemm", obj_coff_seh_save, 1}, \ + {"seh_savexmm", obj_coff_seh_save, 2}, \ + {"seh_pushframe", obj_coff_seh_push, 1}, \ + {"seh_endprologue", obj_coff_seh_endprologue, 0}, \ + {"seh_setframe", obj_coff_seh_setframe, 0}, \ + {"seh_stackalloc", obj_coff_seh_stack_alloc, 0}, \ + {"seh_handler", obj_coff_seh_handler, 0}, \ + {"seh_eh", obj_coff_seh_eh, 0}, \ + {"seh_32", obj_coff_seh_32, 1}, \ + {"seh_no32", obj_coff_seh_32, 0}, \ + {"seh_scope", obj_coff_seh_scope, 0}, + +/* Type definitions. */ + +typedef struct seh_prologue_element +{ + symbolS *pc_addr; + char *pc_symbol; + int kind; + int reg; + bfd_vma offset; +} seh_prologue_element; + +typedef struct seh_scope_elem { + char *begin_addr; + char *end_addr; + char *handler_addr; + char *jump_addr; +} seh_scope_elem; + +typedef struct seh_context +{ + struct seh_context *next; + /* Was record alread processed. */ + int done; + /* Function name. */ + char *func_name; + /* BeginAddress. */ + char *start_symbol; + symbolS *start_addr; + bfd_vma start_offset; + /* EndAddress. */ + char *end_symbol; + symbolS *end_addr; + bfd_vma end_offset; + /* PrologueEnd. */ + char *endprologue_symbol; + symbolS *endprologue_addr; + bfd_vma endprologue_offset; + /* ExceptionHandler. */ + char *handler_name; + /* ExceptionHandlerData. */ + char *handler_data_name; + int handler_written; + /* WinCE specific data. */ + int use_instruction_32; + + /* the bfd to store data within. */ + bfd *abfd; + /* the current section to generate data within. */ + asection *section; + /* Relocations for section. */ + unsigned int count_reloc; + /* Symbols within section. */ + unsigned int count_syms; + /* Iterator for text lable generation. */ + unsigned int tlbl_count; + /* Iterator for xdata lable generation. */ + unsigned int xlbl_count; + /* The name of the first xdata label. */ + char *xdata_first; + /* FIelds used for x64 generation of chained information. */ + char **xdata_names; + char **xdata_pcsyms; + int *xdata_elm_start; + /* Size and offset within current generated xdata section. */ + size_t xdata_sz; + size_t xdata_offset; + /* x64 framereg and frame offset information. */ + int framereg; + bfd_vma frameoff; + /* Information about x64 specific unwind data fields. */ + size_t elems_count; + size_t elems_max; + seh_prologue_element *elems; + size_t scope_max; + size_t scope_count; + seh_scope_elem *scopes; +} seh_context; + +typedef enum seh_kind { + seh_kind_unknown = 0, + seh_kind_mips = 1, /* Used for MIPS and x86 pdata generation. */ + seh_kind_arm = 2, /* Used for ARM, PPC, SH3, and SH4 pdata (PDATA_EH) generation. */ + seh_kind_x64 = 3 /* Used for IA64 and x64 pdata/xdata generation. */ +} seh_kind; + +/* Forward declarations. */ +static void obj_coff_seh_stack_alloc (int); +static void obj_coff_seh_setframe (int); +static void obj_coff_seh_endprologue (int); +static void obj_coff_seh_save (int); +static void obj_coff_seh_push (int); +static void obj_coff_seh_endproc (int); +static void obj_coff_seh_eh (int); +static void obj_coff_seh_32 (int); +static void obj_coff_seh_proc (int); +static void obj_coff_seh_handler (int); +static void obj_coff_seh_scope (int); +static int seh_read_offset (const char *, bfd_vma *); +static int seh_x64_read_reg (const char *, int, int *); +static void seh_x64_make_prologue_element (int, int, bfd_vma); +static void make_function_entry_pdata (seh_context *c); + +#define UNDSEC (asection *) &bfd_und_section + +/* Check if x64 UNW_... macros are already defined. */ +#ifndef PEX64_FLAG_NHANDLER +/* We can't include here coff/pe.h header. So we have to copy macros + from coff/pe.h here. */ +#define PEX64_UNWCODE_CODE(VAL) ((VAL) & 0xf) +#define PEX64_UNWCODE_INFO(VAL) (((VAL) >> 4) & 0xf) + +/* The unwind info. */ +#define UNW_FLAG_NHANDLER 0 +#define UNW_FLAG_EHANDLER 1 +#define UNW_FLAG_UHANDLER 2 +#define UNW_FLAG_FHANDLER 3 +#define UNW_FLAG_CHAININFO 4 + +#define UNW_FLAG_MASK 0x1f + +/* The unwind codes. */ +#define UWOP_PUSH_NONVOL 0 +#define UWOP_ALLOC_LARGE 1 +#define UWOP_ALLOC_SMALL 2 +#define UWOP_SET_FPREG 3 +#define UWOP_SAVE_NONVOL 4 +#define UWOP_SAVE_NONVOL_FAR 5 +#define UWOP_SAVE_XMM 6 +#define UWOP_SAVE_XMM_FAR 7 +#define UWOP_SAVE_XMM128 8 +#define UWOP_SAVE_XMM128_FAR 9 +#define UWOP_PUSH_MACHFRAME 10 + +#define PEX64_UWI_VERSION(VAL) ((VAL) & 7) +#define PEX64_UWI_FLAGS(VAL) (((VAL) >> 3) & 0x1f) +#define PEX64_UWI_FRAMEREG(VAL) ((VAL) & 0xf) +#define PEX64_UWI_FRAMEOFF(VAL) (((VAL) >> 4) & 0xf) +#define PEX64_UWI_SIZEOF_UWCODE_ARRAY(VAL) \ + ((((VAL) + 1) & ~1) * 2) + +#define PEX64_OFFSET_TO_UNWIND_CODE 0x4 + +#define PEX64_OFFSET_TO_HANDLER_RVA (COUNTOFUNWINDCODES) \ + (PEX64_OFFSET_TO_UNWIND_CODE + \ + PEX64_UWI_SIZEOF_UWCODE_ARRAY(COUNTOFUNWINDCODES)) + +#define PEX64_OFFSET_TO_SCOPE_COUNT(COUNTOFUNWINDCODES) \ + (PEX64_OFFSET_TO_HANDLER_RVA(COUNTOFUNWINDCODES) + 4) + +#define PEX64_SCOPE_ENTRY(COUNTOFUNWINDCODES, IDX) \ + (PEX64_OFFSET_TO_SCOPE_COUNT(COUNTOFUNWINDCODES) + \ + PEX64_SCOPE_ENTRY_SIZE * (IDX)) + +#endif +