2 There are at the moment three different function entry formats preset.
3 The first is the MIPS one. The second version
4 is for ARM, PPC, SH3, and SH4 mainly for Windows CE.
5 The third is the IA64 and x64 version. Note, the IA64 isn't implemented yet,
6 but to find information about it, please see specification about IA64 on
7 http://download.intel.com/design/Itanium/Downloads/245358.pdf file.
9 The first version has just entries in the pdata section: BeginAddress,
10 EndAddress, ExceptionHandler, HandlerData, and PrologueEndAddress. Each
11 value is a pointer to the corresponding data and has size of 4 bytes.
13 The second variant has the following entries in the pdata section.
14 BeginAddress, PrologueLength (8 bits), EndAddress (22 bits),
15 Use-32-bit-instruction (1 bit), and Exception-Handler-Exists (1 bit).
16 If the FunctionLength is zero, or the Exception-Handler-Exists bit
17 is true, a PDATA_EH block is placed directly before function entry.
19 The third version has a function entry block of BeginAddress (RVA),
20 EndAddress (RVA), and UnwindData (RVA). The description of the
21 prologue, excepetion-handler, and additional SEH data is stored
22 within the UNWIND_DATA field in the xdata section.
27 .seh_handler <handler>[,<handler-data>]]
31 .seh_setframe <reg>,<offset>
41 /* architecture specific pdata/xdata handling. */
43 {"seh_proc", obj_coff_seh_proc, 0}, \
44 {"seh_endproc", obj_coff_seh_endproc, 0}, \
45 {"seh_pushreg", obj_coff_seh_push, 0}, \
46 {"seh_savereg", obj_coff_seh_save, 0}, \
47 {"seh_savemm", obj_coff_seh_save, 1}, \
48 {"seh_savexmm", obj_coff_seh_save, 2}, \
49 {"seh_pushframe", obj_coff_seh_push, 1}, \
50 {"seh_endprologue", obj_coff_seh_endprologue, 0}, \
51 {"seh_setframe", obj_coff_seh_setframe, 0}, \
52 {"seh_stackalloc", obj_coff_seh_stack_alloc, 0}, \
53 {"seh_handler", obj_coff_seh_handler, 0}, \
54 {"seh_eh", obj_coff_seh_eh, 0}, \
55 {"seh_32", obj_coff_seh_32, 1}, \
56 {"seh_no32", obj_coff_seh_32, 0}, \
57 {"seh_scope", obj_coff_seh_scope, 0},
59 /* Type definitions. */
61 typedef struct seh_prologue_element
68 } seh_prologue_element;
70 typedef struct seh_scope_elem {
77 typedef struct seh_context
79 struct seh_context *next;
80 /* Was record alread processed. */
93 char *endprologue_symbol;
94 symbolS *endprologue_addr;
95 bfd_vma endprologue_offset;
96 /* ExceptionHandler. */
98 /* ExceptionHandlerData. */
99 char *handler_data_name;
101 /* WinCE specific data. */
102 int use_instruction_32;
104 /* the bfd to store data within. */
106 /* the current section to generate data within. */
108 /* Relocations for section. */
109 unsigned int count_reloc;
110 /* Symbols within section. */
111 unsigned int count_syms;
112 /* Iterator for text lable generation. */
113 unsigned int tlbl_count;
114 /* Iterator for xdata lable generation. */
115 unsigned int xlbl_count;
116 /* The name of the first xdata label. */
118 /* FIelds used for x64 generation of chained information. */
121 int *xdata_elm_start;
122 /* Size and offset within current generated xdata section. */
125 /* x64 framereg and frame offset information. */
128 /* Information about x64 specific unwind data fields. */
131 seh_prologue_element *elems;
134 seh_scope_elem *scopes;
137 typedef enum seh_kind {
138 seh_kind_unknown = 0,
139 seh_kind_mips = 1, /* Used for MIPS and x86 pdata generation. */
140 seh_kind_arm = 2, /* Used for ARM, PPC, SH3, and SH4 pdata (PDATA_EH) generation. */
141 seh_kind_x64 = 3 /* Used for IA64 and x64 pdata/xdata generation. */
144 /* Forward declarations. */
145 static void obj_coff_seh_stack_alloc (int);
146 static void obj_coff_seh_setframe (int);
147 static void obj_coff_seh_endprologue (int);
148 static void obj_coff_seh_save (int);
149 static void obj_coff_seh_push (int);
150 static void obj_coff_seh_endproc (int);
151 static void obj_coff_seh_eh (int);
152 static void obj_coff_seh_32 (int);
153 static void obj_coff_seh_proc (int);
154 static void obj_coff_seh_handler (int);
155 static void obj_coff_seh_scope (int);
156 static int seh_read_offset (const char *, bfd_vma *);
157 static int seh_x64_read_reg (const char *, int, int *);
158 static void seh_x64_make_prologue_element (int, int, bfd_vma);
159 static void make_function_entry_pdata (seh_context *c);
161 #define UNDSEC (asection *) &bfd_und_section