Subversion Repositories Kolibri OS

Rev

Rev 5222 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5222 serge 1
/* seh pdata/xdata coff object file format
6324 serge 2
   Copyright (C) 2009-2015 Free Software Foundation, Inc.
5222 serge 3
 
4
   This file is part of GAS.
5
 
6
   GAS is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3, or (at your option)
9
   any later version.
10
 
11
   GAS is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
   GNU General Public License for more details.
15
 
16
   You should have received a copy of the GNU General Public License
17
   along with GAS; see the file COPYING.  If not, write to the Free
18
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19
   02110-1301, USA.  */
20
 
21
/* Short overview:
22
  There are at the moment three different function entry formats preset.
23
  The first is the MIPS one. The second version
24
  is for ARM, PPC, SH3, and SH4 mainly for Windows CE.
25
  The third is the IA64 and x64 version. Note, the IA64 isn't implemented yet,
26
  but to find information about it, please see specification about IA64 on
27
  http://download.intel.com/design/Itanium/Downloads/245358.pdf file.
28
 
29
  The first version has just entries in the pdata section: BeginAddress,
30
  EndAddress, ExceptionHandler, HandlerData, and PrologueEndAddress. Each
31
  value is a pointer to the corresponding data and has size of 4 bytes.
32
 
33
  The second variant has the following entries in the pdata section.
34
  BeginAddress, PrologueLength (8 bits), EndAddress (22 bits),
35
  Use-32-bit-instruction (1 bit), and Exception-Handler-Exists (1 bit).
36
  If the FunctionLength is zero, or the Exception-Handler-Exists bit
37
  is true, a PDATA_EH block is placed directly before function entry.
38
 
39
  The third version has a function entry block of BeginAddress (RVA),
40
  EndAddress (RVA), and UnwindData (RVA). The description of the
41
  prologue, excepetion-handler, and additional SEH data is stored
42
  within the UNWIND_DATA field in the xdata section.
43
 
44
  The pseudos:
45
  .seh_proc 
46
  .seh_endprologue
47
  .seh_handler [,@unwind][,@except]	(x64)
48
  .seh_handler [,]	(others)
49
  .seh_handlerdata
50
  .seh_eh
51
  .seh_32/.seh_no32
52
  .seh_endproc
53
  .seh_setframe ,
54
  .seh_stackalloc
55
  .seh_pushreg
56
  .seh_savereg
57
  .seh_savexmm
58
  .seh_pushframe
6324 serge 59
  .seh_code
5222 serge 60
*/
61
 
62
/* architecture specific pdata/xdata handling.  */
63
#define SEH_CMDS \
64
        {"seh_proc", obj_coff_seh_proc, 0}, \
65
        {"seh_endproc", obj_coff_seh_endproc, 0}, \
66
        {"seh_pushreg", obj_coff_seh_pushreg, 0}, \
67
        {"seh_savereg", obj_coff_seh_save, 1}, \
68
        {"seh_savexmm", obj_coff_seh_save, 2}, \
69
        {"seh_pushframe", obj_coff_seh_pushframe, 0}, \
70
        {"seh_endprologue", obj_coff_seh_endprologue, 0}, \
71
        {"seh_setframe", obj_coff_seh_setframe, 0}, \
72
        {"seh_stackalloc", obj_coff_seh_stackalloc, 0}, \
73
	{"seh_eh", obj_coff_seh_eh, 0}, \
74
	{"seh_32", obj_coff_seh_32, 1}, \
75
	{"seh_no32", obj_coff_seh_32, 0}, \
76
	{"seh_handler", obj_coff_seh_handler, 0}, \
6324 serge 77
	{"seh_code", obj_coff_seh_code, 0}, \
5222 serge 78
	{"seh_handlerdata", obj_coff_seh_handlerdata, 0},
79
 
80
/* Type definitions.  */
81
 
82
typedef struct seh_prologue_element
83
{
84
  int code;
85
  int info;
86
  offsetT off;
87
  symbolS *pc_addr;
88
} seh_prologue_element;
89
 
90
typedef struct seh_context
91
{
92
  struct seh_context *next;
93
 
94
  /* Initial code-segment.  */
95
  segT code_seg;
96
  /* Function name.  */
97
  char *func_name;
98
  /* BeginAddress.  */
99
  symbolS *start_addr;
100
  /* EndAddress.  */
101
  symbolS *end_addr;
102
  /* Unwind data.  */
103
  symbolS *xdata_addr;
104
  /* PrologueEnd.  */
105
  symbolS *endprologue_addr;
106
  /* ExceptionHandler.  */
107
  expressionS handler;
108
  /* ExceptionHandlerData. (arm, mips)  */
109
  expressionS handler_data;
110
 
111
  /* ARM .seh_eh directive seen.  */
112
  int handler_written;
113
 
114
  /* WinCE specific data.  */
115
  int use_instruction_32;
116
  /* Was record already processed.  */
117
  int done;
118
 
119
  /* x64 flags for the xdata header.  */
120
  int handler_flags;
121
  int subsection;
122
 
123
  /* x64 framereg and frame offset information.  */
124
  int framereg;
125
  int frameoff;
126
 
127
  /* Information about x64 specific unwind data fields.  */
128
  int elems_count;
129
  int elems_max;
130
  seh_prologue_element *elems;
131
} seh_context;
132
 
133
typedef enum seh_kind {
134
  seh_kind_unknown = 0,
135
  seh_kind_mips = 1,  /* Used for MIPS and x86 pdata generation.  */
136
  seh_kind_arm = 2,   /* Used for ARM, PPC, SH3, and SH4 pdata (PDATA_EH) generation.  */
137
  seh_kind_x64 = 3    /* Used for IA64 and x64 pdata/xdata generation.  */
138
} seh_kind;
139
 
140
/* Forward declarations.  */
141
static void obj_coff_seh_stackalloc (int);
142
static void obj_coff_seh_setframe (int);
143
static void obj_coff_seh_endprologue (int);
144
static void obj_coff_seh_save (int);
145
static void obj_coff_seh_pushreg (int);
146
static void obj_coff_seh_pushframe (int);
147
static void obj_coff_seh_endproc  (int);
148
static void obj_coff_seh_eh (int);
149
static void obj_coff_seh_32 (int);
150
static void obj_coff_seh_proc  (int);
151
static void obj_coff_seh_handler (int);
152
static void obj_coff_seh_handlerdata (int);
6324 serge 153
static void obj_coff_seh_code (int);
5222 serge 154
 
155
#define UNDSEC bfd_und_section_ptr
156
 
157
/* Check if x64 UNW_... macros are already defined.  */
158
#ifndef PEX64_FLAG_NHANDLER
159
/* We can't include here coff/pe.h header. So we have to copy macros
160
   from coff/pe.h here.  */
161
#define PEX64_UNWCODE_CODE(VAL) ((VAL) & 0xf)
162
#define PEX64_UNWCODE_INFO(VAL) (((VAL) >> 4) & 0xf)
163
 
164
/* The unwind info.  */
165
#define UNW_FLAG_NHANDLER     0
166
#define UNW_FLAG_EHANDLER     1
167
#define UNW_FLAG_UHANDLER     2
168
#define UNW_FLAG_FHANDLER     3
169
#define UNW_FLAG_CHAININFO    4
170
 
171
#define UNW_FLAG_MASK         0x1f
172
 
173
/* The unwind codes.  */
174
#define UWOP_PUSH_NONVOL      0
175
#define UWOP_ALLOC_LARGE      1
176
#define UWOP_ALLOC_SMALL      2
177
#define UWOP_SET_FPREG        3
178
#define UWOP_SAVE_NONVOL      4
179
#define UWOP_SAVE_NONVOL_FAR  5
180
#define UWOP_SAVE_XMM         6
181
#define UWOP_SAVE_XMM_FAR     7
182
#define UWOP_SAVE_XMM128      8
183
#define UWOP_SAVE_XMM128_FAR  9
184
#define UWOP_PUSH_MACHFRAME   10
185
 
186
#define PEX64_UWI_VERSION(VAL)  ((VAL) & 7)
187
#define PEX64_UWI_FLAGS(VAL)    (((VAL) >> 3) & 0x1f)
188
#define PEX64_UWI_FRAMEREG(VAL) ((VAL) & 0xf)
189
#define PEX64_UWI_FRAMEOFF(VAL) (((VAL) >> 4) & 0xf)
190
#define PEX64_UWI_SIZEOF_UWCODE_ARRAY(VAL) \
191
  ((((VAL) + 1) & ~1) * 2)
192
 
193
#define PEX64_OFFSET_TO_UNWIND_CODE 0x4
194
 
195
#define PEX64_OFFSET_TO_HANDLER_RVA (COUNTOFUNWINDCODES) \
196
  (PEX64_OFFSET_TO_UNWIND_CODE + \
197
   PEX64_UWI_SIZEOF_UWCODE_ARRAY(COUNTOFUNWINDCODES))
198
 
199
#define PEX64_OFFSET_TO_SCOPE_COUNT(COUNTOFUNWINDCODES) \
200
  (PEX64_OFFSET_TO_HANDLER_RVA(COUNTOFUNWINDCODES) + 4)
201
 
202
#define PEX64_SCOPE_ENTRY(COUNTOFUNWINDCODES, IDX) \
203
  (PEX64_OFFSET_TO_SCOPE_COUNT(COUNTOFUNWINDCODES) + \
204
   PEX64_SCOPE_ENTRY_SIZE * (IDX))
205
 
206
#endif