1*fae548d3Szrj /* dw2gencfi.c - Support for generating Dwarf2 CFI information.
2*fae548d3Szrj Copyright (C) 2003-2020 Free Software Foundation, Inc.
3*fae548d3Szrj Contributed by Michal Ludvig <mludvig@suse.cz>
4*fae548d3Szrj
5*fae548d3Szrj This file is part of GAS, the GNU Assembler.
6*fae548d3Szrj
7*fae548d3Szrj GAS is free software; you can redistribute it and/or modify
8*fae548d3Szrj it under the terms of the GNU General Public License as published by
9*fae548d3Szrj the Free Software Foundation; either version 3, or (at your option)
10*fae548d3Szrj any later version.
11*fae548d3Szrj
12*fae548d3Szrj GAS is distributed in the hope that it will be useful,
13*fae548d3Szrj but WITHOUT ANY WARRANTY; without even the implied warranty of
14*fae548d3Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15*fae548d3Szrj GNU General Public License for more details.
16*fae548d3Szrj
17*fae548d3Szrj You should have received a copy of the GNU General Public License
18*fae548d3Szrj along with GAS; see the file COPYING. If not, write to the Free
19*fae548d3Szrj Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20*fae548d3Szrj 02110-1301, USA. */
21*fae548d3Szrj
22*fae548d3Szrj #include "as.h"
23*fae548d3Szrj #include "dw2gencfi.h"
24*fae548d3Szrj #include "subsegs.h"
25*fae548d3Szrj #include "dwarf2dbg.h"
26*fae548d3Szrj
27*fae548d3Szrj #ifdef TARGET_USE_CFIPOP
28*fae548d3Szrj
29*fae548d3Szrj /* By default, use difference expressions if DIFF_EXPR_OK is defined. */
30*fae548d3Szrj #ifndef CFI_DIFF_EXPR_OK
31*fae548d3Szrj # ifdef DIFF_EXPR_OK
32*fae548d3Szrj # define CFI_DIFF_EXPR_OK 1
33*fae548d3Szrj # else
34*fae548d3Szrj # define CFI_DIFF_EXPR_OK 0
35*fae548d3Szrj # endif
36*fae548d3Szrj #endif
37*fae548d3Szrj
38*fae548d3Szrj #ifndef CFI_DIFF_LSDA_OK
39*fae548d3Szrj #define CFI_DIFF_LSDA_OK CFI_DIFF_EXPR_OK
40*fae548d3Szrj #endif
41*fae548d3Szrj
42*fae548d3Szrj #if CFI_DIFF_EXPR_OK == 1 && CFI_DIFF_LSDA_OK == 0
43*fae548d3Szrj # error "CFI_DIFF_EXPR_OK should imply CFI_DIFF_LSDA_OK"
44*fae548d3Szrj #endif
45*fae548d3Szrj
46*fae548d3Szrj /* We re-use DWARF2_LINE_MIN_INSN_LENGTH for the code alignment field
47*fae548d3Szrj of the CIE. Default to 1 if not otherwise specified. */
48*fae548d3Szrj #ifndef DWARF2_LINE_MIN_INSN_LENGTH
49*fae548d3Szrj #define DWARF2_LINE_MIN_INSN_LENGTH 1
50*fae548d3Szrj #endif
51*fae548d3Szrj
52*fae548d3Szrj /* By default, use 32-bit relocations from .eh_frame into .text. */
53*fae548d3Szrj #ifndef DWARF2_FDE_RELOC_SIZE
54*fae548d3Szrj #define DWARF2_FDE_RELOC_SIZE 4
55*fae548d3Szrj #endif
56*fae548d3Szrj
57*fae548d3Szrj /* By default, use a read-only .eh_frame section. */
58*fae548d3Szrj #ifndef DWARF2_EH_FRAME_READ_ONLY
59*fae548d3Szrj #define DWARF2_EH_FRAME_READ_ONLY SEC_READONLY
60*fae548d3Szrj #endif
61*fae548d3Szrj
62*fae548d3Szrj #ifndef EH_FRAME_ALIGNMENT
63*fae548d3Szrj #define EH_FRAME_ALIGNMENT (bfd_get_arch_size (stdoutput) == 64 ? 3 : 2)
64*fae548d3Szrj #endif
65*fae548d3Szrj
66*fae548d3Szrj #ifndef tc_cfi_frame_initial_instructions
67*fae548d3Szrj #define tc_cfi_frame_initial_instructions() ((void)0)
68*fae548d3Szrj #endif
69*fae548d3Szrj
70*fae548d3Szrj #ifndef tc_cfi_startproc
71*fae548d3Szrj # define tc_cfi_startproc() ((void)0)
72*fae548d3Szrj #endif
73*fae548d3Szrj
74*fae548d3Szrj #ifndef tc_cfi_endproc
75*fae548d3Szrj # define tc_cfi_endproc(fde) ((void) (fde))
76*fae548d3Szrj #endif
77*fae548d3Szrj
78*fae548d3Szrj #define EH_FRAME_LINKONCE (SUPPORT_FRAME_LINKONCE || compact_eh)
79*fae548d3Szrj
80*fae548d3Szrj #ifndef DWARF2_FORMAT
81*fae548d3Szrj #define DWARF2_FORMAT(SEC) dwarf2_format_32bit
82*fae548d3Szrj #endif
83*fae548d3Szrj
84*fae548d3Szrj #ifndef DWARF2_ADDR_SIZE
85*fae548d3Szrj #define DWARF2_ADDR_SIZE(bfd) (bfd_arch_bits_per_address (bfd) / 8)
86*fae548d3Szrj #endif
87*fae548d3Szrj
88*fae548d3Szrj #if MULTIPLE_FRAME_SECTIONS
89*fae548d3Szrj #define CUR_SEG(structp) structp->cur_seg
90*fae548d3Szrj #define SET_CUR_SEG(structp, seg) structp->cur_seg = seg
91*fae548d3Szrj #define HANDLED(structp) structp->handled
92*fae548d3Szrj #define SET_HANDLED(structp, val) structp->handled = val
93*fae548d3Szrj #else
94*fae548d3Szrj #define CUR_SEG(structp) NULL
95*fae548d3Szrj #define SET_CUR_SEG(structp, seg) (void) (0 && seg)
96*fae548d3Szrj #define HANDLED(structp) 0
97*fae548d3Szrj #define SET_HANDLED(structp, val) (void) (0 && val)
98*fae548d3Szrj #endif
99*fae548d3Szrj
100*fae548d3Szrj #ifndef tc_cfi_reloc_for_encoding
101*fae548d3Szrj #define tc_cfi_reloc_for_encoding(e) BFD_RELOC_NONE
102*fae548d3Szrj #endif
103*fae548d3Szrj
104*fae548d3Szrj /* Private segment collection list. */
105*fae548d3Szrj struct dwcfi_seg_list
106*fae548d3Szrj {
107*fae548d3Szrj segT seg;
108*fae548d3Szrj int subseg;
109*fae548d3Szrj char * seg_name;
110*fae548d3Szrj };
111*fae548d3Szrj
112*fae548d3Szrj #ifdef SUPPORT_COMPACT_EH
113*fae548d3Szrj static bfd_boolean compact_eh;
114*fae548d3Szrj #else
115*fae548d3Szrj #define compact_eh 0
116*fae548d3Szrj #endif
117*fae548d3Szrj
118*fae548d3Szrj static struct hash_control *dwcfi_hash;
119*fae548d3Szrj
120*fae548d3Szrj /* Emit a single byte into the current segment. */
121*fae548d3Szrj
122*fae548d3Szrj static inline void
out_one(int byte)123*fae548d3Szrj out_one (int byte)
124*fae548d3Szrj {
125*fae548d3Szrj FRAG_APPEND_1_CHAR (byte);
126*fae548d3Szrj }
127*fae548d3Szrj
128*fae548d3Szrj /* Emit a two-byte word into the current segment. */
129*fae548d3Szrj
130*fae548d3Szrj static inline void
out_two(int data)131*fae548d3Szrj out_two (int data)
132*fae548d3Szrj {
133*fae548d3Szrj md_number_to_chars (frag_more (2), data, 2);
134*fae548d3Szrj }
135*fae548d3Szrj
136*fae548d3Szrj /* Emit a four byte word into the current segment. */
137*fae548d3Szrj
138*fae548d3Szrj static inline void
out_four(int data)139*fae548d3Szrj out_four (int data)
140*fae548d3Szrj {
141*fae548d3Szrj md_number_to_chars (frag_more (4), data, 4);
142*fae548d3Szrj }
143*fae548d3Szrj
144*fae548d3Szrj /* Emit an unsigned "little-endian base 128" number. */
145*fae548d3Szrj
146*fae548d3Szrj static void
out_uleb128(addressT value)147*fae548d3Szrj out_uleb128 (addressT value)
148*fae548d3Szrj {
149*fae548d3Szrj output_leb128 (frag_more (sizeof_leb128 (value, 0)), value, 0);
150*fae548d3Szrj }
151*fae548d3Szrj
152*fae548d3Szrj /* Emit an unsigned "little-endian base 128" number. */
153*fae548d3Szrj
154*fae548d3Szrj static void
out_sleb128(offsetT value)155*fae548d3Szrj out_sleb128 (offsetT value)
156*fae548d3Szrj {
157*fae548d3Szrj output_leb128 (frag_more (sizeof_leb128 (value, 1)), value, 1);
158*fae548d3Szrj }
159*fae548d3Szrj
160*fae548d3Szrj static unsigned int
encoding_size(unsigned char encoding)161*fae548d3Szrj encoding_size (unsigned char encoding)
162*fae548d3Szrj {
163*fae548d3Szrj if (encoding == DW_EH_PE_omit)
164*fae548d3Szrj return 0;
165*fae548d3Szrj switch (encoding & 0x7)
166*fae548d3Szrj {
167*fae548d3Szrj case 0:
168*fae548d3Szrj return bfd_get_arch_size (stdoutput) == 64 ? 8 : 4;
169*fae548d3Szrj case DW_EH_PE_udata2:
170*fae548d3Szrj return 2;
171*fae548d3Szrj case DW_EH_PE_udata4:
172*fae548d3Szrj return 4;
173*fae548d3Szrj case DW_EH_PE_udata8:
174*fae548d3Szrj return 8;
175*fae548d3Szrj default:
176*fae548d3Szrj abort ();
177*fae548d3Szrj }
178*fae548d3Szrj }
179*fae548d3Szrj
180*fae548d3Szrj /* Emit expression EXP in ENCODING. If EMIT_ENCODING is true, first
181*fae548d3Szrj emit a byte containing ENCODING. */
182*fae548d3Szrj
183*fae548d3Szrj static void
emit_expr_encoded(expressionS * exp,int encoding,bfd_boolean emit_encoding)184*fae548d3Szrj emit_expr_encoded (expressionS *exp, int encoding, bfd_boolean emit_encoding)
185*fae548d3Szrj {
186*fae548d3Szrj unsigned int size = encoding_size (encoding);
187*fae548d3Szrj bfd_reloc_code_real_type code;
188*fae548d3Szrj
189*fae548d3Szrj if (encoding == DW_EH_PE_omit)
190*fae548d3Szrj return;
191*fae548d3Szrj
192*fae548d3Szrj if (emit_encoding)
193*fae548d3Szrj out_one (encoding);
194*fae548d3Szrj
195*fae548d3Szrj code = tc_cfi_reloc_for_encoding (encoding);
196*fae548d3Szrj if (code != BFD_RELOC_NONE)
197*fae548d3Szrj {
198*fae548d3Szrj reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, code);
199*fae548d3Szrj char *p = frag_more (size);
200*fae548d3Szrj gas_assert (size == (unsigned) howto->bitsize / 8);
201*fae548d3Szrj md_number_to_chars (p, 0, size);
202*fae548d3Szrj fix_new (frag_now, p - frag_now->fr_literal, size, exp->X_add_symbol,
203*fae548d3Szrj exp->X_add_number, howto->pc_relative, code);
204*fae548d3Szrj }
205*fae548d3Szrj else if ((encoding & 0x70) == DW_EH_PE_pcrel)
206*fae548d3Szrj {
207*fae548d3Szrj #if CFI_DIFF_EXPR_OK
208*fae548d3Szrj expressionS tmp = *exp;
209*fae548d3Szrj tmp.X_op = O_subtract;
210*fae548d3Szrj tmp.X_op_symbol = symbol_temp_new_now ();
211*fae548d3Szrj emit_expr (&tmp, size);
212*fae548d3Szrj #elif defined (tc_cfi_emit_pcrel_expr)
213*fae548d3Szrj tc_cfi_emit_pcrel_expr (exp, size);
214*fae548d3Szrj #else
215*fae548d3Szrj abort ();
216*fae548d3Szrj #endif
217*fae548d3Szrj }
218*fae548d3Szrj else
219*fae548d3Szrj emit_expr (exp, size);
220*fae548d3Szrj }
221*fae548d3Szrj
222*fae548d3Szrj /* Build based on segment the derived .debug_...
223*fae548d3Szrj segment name containing origin segment's postfix name part. */
224*fae548d3Szrj
225*fae548d3Szrj static char *
get_debugseg_name(segT seg,const char * base_name)226*fae548d3Szrj get_debugseg_name (segT seg, const char *base_name)
227*fae548d3Szrj {
228*fae548d3Szrj const char * name;
229*fae548d3Szrj const char * dollar;
230*fae548d3Szrj const char * dot;
231*fae548d3Szrj
232*fae548d3Szrj if (!seg)
233*fae548d3Szrj return concat (base_name, NULL);
234*fae548d3Szrj
235*fae548d3Szrj name = bfd_section_name (seg);
236*fae548d3Szrj
237*fae548d3Szrj if (name == NULL || *name == 0)
238*fae548d3Szrj return concat (base_name, NULL);
239*fae548d3Szrj
240*fae548d3Szrj dollar = strchr (name, '$');
241*fae548d3Szrj dot = strchr (name + 1, '.');
242*fae548d3Szrj
243*fae548d3Szrj if (!dollar && !dot)
244*fae548d3Szrj {
245*fae548d3Szrj if (!strcmp (base_name, ".eh_frame_entry")
246*fae548d3Szrj && strcmp (name, ".text") != 0)
247*fae548d3Szrj return concat (base_name, ".", name, NULL);
248*fae548d3Szrj
249*fae548d3Szrj name = "";
250*fae548d3Szrj }
251*fae548d3Szrj else if (!dollar)
252*fae548d3Szrj name = dot;
253*fae548d3Szrj else if (!dot)
254*fae548d3Szrj name = dollar;
255*fae548d3Szrj else if (dot < dollar)
256*fae548d3Szrj name = dot;
257*fae548d3Szrj else
258*fae548d3Szrj name = dollar;
259*fae548d3Szrj
260*fae548d3Szrj return concat (base_name, name, NULL);
261*fae548d3Szrj }
262*fae548d3Szrj
263*fae548d3Szrj /* Allocate a dwcfi_seg_list structure. */
264*fae548d3Szrj
265*fae548d3Szrj static struct dwcfi_seg_list *
alloc_debugseg_item(segT seg,int subseg,char * name)266*fae548d3Szrj alloc_debugseg_item (segT seg, int subseg, char *name)
267*fae548d3Szrj {
268*fae548d3Szrj struct dwcfi_seg_list *r;
269*fae548d3Szrj
270*fae548d3Szrj r = (struct dwcfi_seg_list *)
271*fae548d3Szrj xmalloc (sizeof (struct dwcfi_seg_list) + strlen (name));
272*fae548d3Szrj r->seg = seg;
273*fae548d3Szrj r->subseg = subseg;
274*fae548d3Szrj r->seg_name = name;
275*fae548d3Szrj return r;
276*fae548d3Szrj }
277*fae548d3Szrj
278*fae548d3Szrj static segT
is_now_linkonce_segment(void)279*fae548d3Szrj is_now_linkonce_segment (void)
280*fae548d3Szrj {
281*fae548d3Szrj if (compact_eh)
282*fae548d3Szrj return now_seg;
283*fae548d3Szrj
284*fae548d3Szrj if ((bfd_section_flags (now_seg)
285*fae548d3Szrj & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
286*fae548d3Szrj | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE
287*fae548d3Szrj | SEC_LINK_DUPLICATES_SAME_CONTENTS)) != 0)
288*fae548d3Szrj return now_seg;
289*fae548d3Szrj return NULL;
290*fae548d3Szrj }
291*fae548d3Szrj
292*fae548d3Szrj /* Generate debug... segment with same linkonce properties
293*fae548d3Szrj of based segment. */
294*fae548d3Szrj
295*fae548d3Szrj static segT
make_debug_seg(segT cseg,char * name,int sflags)296*fae548d3Szrj make_debug_seg (segT cseg, char *name, int sflags)
297*fae548d3Szrj {
298*fae548d3Szrj segT save_seg = now_seg;
299*fae548d3Szrj int save_subseg = now_subseg;
300*fae548d3Szrj segT r;
301*fae548d3Szrj flagword flags;
302*fae548d3Szrj
303*fae548d3Szrj r = subseg_new (name, 0);
304*fae548d3Szrj
305*fae548d3Szrj /* Check if code segment is marked as linked once. */
306*fae548d3Szrj if (!cseg)
307*fae548d3Szrj flags = 0;
308*fae548d3Szrj else
309*fae548d3Szrj flags = (bfd_section_flags (cseg)
310*fae548d3Szrj & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
311*fae548d3Szrj | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE
312*fae548d3Szrj | SEC_LINK_DUPLICATES_SAME_CONTENTS));
313*fae548d3Szrj
314*fae548d3Szrj /* Add standard section flags. */
315*fae548d3Szrj flags |= sflags;
316*fae548d3Szrj
317*fae548d3Szrj /* Apply possibly linked once flags to new generated segment, too. */
318*fae548d3Szrj if (!bfd_set_section_flags (r, flags))
319*fae548d3Szrj as_bad (_("bfd_set_section_flags: %s"),
320*fae548d3Szrj bfd_errmsg (bfd_get_error ()));
321*fae548d3Szrj
322*fae548d3Szrj /* Restore to previous segment. */
323*fae548d3Szrj if (save_seg != NULL)
324*fae548d3Szrj subseg_set (save_seg, save_subseg);
325*fae548d3Szrj return r;
326*fae548d3Szrj }
327*fae548d3Szrj
328*fae548d3Szrj static void
dwcfi_hash_insert(const char * name,struct dwcfi_seg_list * item)329*fae548d3Szrj dwcfi_hash_insert (const char *name, struct dwcfi_seg_list *item)
330*fae548d3Szrj {
331*fae548d3Szrj const char *error_string;
332*fae548d3Szrj
333*fae548d3Szrj if ((error_string = hash_jam (dwcfi_hash, name, (char *) item)))
334*fae548d3Szrj as_fatal (_("Inserting \"%s\" into structure table failed: %s"),
335*fae548d3Szrj name, error_string);
336*fae548d3Szrj }
337*fae548d3Szrj
338*fae548d3Szrj static struct dwcfi_seg_list *
dwcfi_hash_find(char * name)339*fae548d3Szrj dwcfi_hash_find (char *name)
340*fae548d3Szrj {
341*fae548d3Szrj return (struct dwcfi_seg_list *) hash_find (dwcfi_hash, name);
342*fae548d3Szrj }
343*fae548d3Szrj
344*fae548d3Szrj static struct dwcfi_seg_list *
dwcfi_hash_find_or_make(segT cseg,const char * base_name,int flags)345*fae548d3Szrj dwcfi_hash_find_or_make (segT cseg, const char *base_name, int flags)
346*fae548d3Szrj {
347*fae548d3Szrj struct dwcfi_seg_list *item;
348*fae548d3Szrj char *name;
349*fae548d3Szrj
350*fae548d3Szrj /* Initialize dwcfi_hash once. */
351*fae548d3Szrj if (!dwcfi_hash)
352*fae548d3Szrj dwcfi_hash = hash_new ();
353*fae548d3Szrj
354*fae548d3Szrj name = get_debugseg_name (cseg, base_name);
355*fae548d3Szrj
356*fae548d3Szrj item = dwcfi_hash_find (name);
357*fae548d3Szrj if (!item)
358*fae548d3Szrj {
359*fae548d3Szrj item = alloc_debugseg_item (make_debug_seg (cseg, name, flags), 0, name);
360*fae548d3Szrj
361*fae548d3Szrj dwcfi_hash_insert (item->seg_name, item);
362*fae548d3Szrj }
363*fae548d3Szrj else
364*fae548d3Szrj free (name);
365*fae548d3Szrj
366*fae548d3Szrj return item;
367*fae548d3Szrj }
368*fae548d3Szrj
369*fae548d3Szrj /* ??? Share this with dwarf2cfg.c. */
370*fae548d3Szrj #ifndef TC_DWARF2_EMIT_OFFSET
371*fae548d3Szrj #define TC_DWARF2_EMIT_OFFSET generic_dwarf2_emit_offset
372*fae548d3Szrj
373*fae548d3Szrj /* Create an offset to .dwarf2_*. */
374*fae548d3Szrj
375*fae548d3Szrj static void
generic_dwarf2_emit_offset(symbolS * symbol,unsigned int size)376*fae548d3Szrj generic_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
377*fae548d3Szrj {
378*fae548d3Szrj expressionS exp;
379*fae548d3Szrj
380*fae548d3Szrj exp.X_op = O_symbol;
381*fae548d3Szrj exp.X_add_symbol = symbol;
382*fae548d3Szrj exp.X_add_number = 0;
383*fae548d3Szrj emit_expr (&exp, size);
384*fae548d3Szrj }
385*fae548d3Szrj #endif
386*fae548d3Szrj
387*fae548d3Szrj struct cfi_escape_data
388*fae548d3Szrj {
389*fae548d3Szrj struct cfi_escape_data *next;
390*fae548d3Szrj expressionS exp;
391*fae548d3Szrj };
392*fae548d3Szrj
393*fae548d3Szrj struct cie_entry
394*fae548d3Szrj {
395*fae548d3Szrj struct cie_entry *next;
396*fae548d3Szrj #if MULTIPLE_FRAME_SECTIONS
397*fae548d3Szrj segT cur_seg;
398*fae548d3Szrj #endif
399*fae548d3Szrj symbolS *start_address;
400*fae548d3Szrj unsigned int return_column;
401*fae548d3Szrj unsigned int signal_frame;
402*fae548d3Szrj unsigned char fde_encoding;
403*fae548d3Szrj unsigned char per_encoding;
404*fae548d3Szrj unsigned char lsda_encoding;
405*fae548d3Szrj expressionS personality;
406*fae548d3Szrj #ifdef tc_cie_entry_extras
407*fae548d3Szrj tc_cie_entry_extras
408*fae548d3Szrj #endif
409*fae548d3Szrj struct cfi_insn_data *first, *last;
410*fae548d3Szrj };
411*fae548d3Szrj
412*fae548d3Szrj /* List of FDE entries. */
413*fae548d3Szrj
414*fae548d3Szrj struct fde_entry *all_fde_data;
415*fae548d3Szrj static struct fde_entry **last_fde_data = &all_fde_data;
416*fae548d3Szrj
417*fae548d3Szrj /* List of CIEs so that they could be reused. */
418*fae548d3Szrj static struct cie_entry *cie_root;
419*fae548d3Szrj
420*fae548d3Szrj /* Construct a new FDE structure and add it to the end of the fde list. */
421*fae548d3Szrj
422*fae548d3Szrj static struct fde_entry *
alloc_fde_entry(void)423*fae548d3Szrj alloc_fde_entry (void)
424*fae548d3Szrj {
425*fae548d3Szrj struct fde_entry *fde = XCNEW (struct fde_entry);
426*fae548d3Szrj
427*fae548d3Szrj frchain_now->frch_cfi_data = XCNEW (struct frch_cfi_data);
428*fae548d3Szrj frchain_now->frch_cfi_data->cur_fde_data = fde;
429*fae548d3Szrj *last_fde_data = fde;
430*fae548d3Szrj last_fde_data = &fde->next;
431*fae548d3Szrj SET_CUR_SEG (fde, is_now_linkonce_segment ());
432*fae548d3Szrj SET_HANDLED (fde, 0);
433*fae548d3Szrj fde->last = &fde->data;
434*fae548d3Szrj fde->return_column = DWARF2_DEFAULT_RETURN_COLUMN;
435*fae548d3Szrj fde->per_encoding = DW_EH_PE_omit;
436*fae548d3Szrj fde->lsda_encoding = DW_EH_PE_omit;
437*fae548d3Szrj fde->eh_header_type = EH_COMPACT_UNKNOWN;
438*fae548d3Szrj #ifdef tc_fde_entry_init_extra
439*fae548d3Szrj tc_fde_entry_init_extra (fde)
440*fae548d3Szrj #endif
441*fae548d3Szrj
442*fae548d3Szrj return fde;
443*fae548d3Szrj }
444*fae548d3Szrj
445*fae548d3Szrj /* The following functions are available for a backend to construct its
446*fae548d3Szrj own unwind information, usually from legacy unwind directives. */
447*fae548d3Szrj
448*fae548d3Szrj /* Construct a new INSN structure and add it to the end of the insn list
449*fae548d3Szrj for the currently active FDE. */
450*fae548d3Szrj
451*fae548d3Szrj static bfd_boolean cfi_sections_set = FALSE;
452*fae548d3Szrj static int cfi_sections = CFI_EMIT_eh_frame;
453*fae548d3Szrj int all_cfi_sections = 0;
454*fae548d3Szrj static struct fde_entry *last_fde;
455*fae548d3Szrj
456*fae548d3Szrj static struct cfi_insn_data *
alloc_cfi_insn_data(void)457*fae548d3Szrj alloc_cfi_insn_data (void)
458*fae548d3Szrj {
459*fae548d3Szrj struct cfi_insn_data *insn = XCNEW (struct cfi_insn_data);
460*fae548d3Szrj struct fde_entry *cur_fde_data = frchain_now->frch_cfi_data->cur_fde_data;
461*fae548d3Szrj
462*fae548d3Szrj *cur_fde_data->last = insn;
463*fae548d3Szrj cur_fde_data->last = &insn->next;
464*fae548d3Szrj SET_CUR_SEG (insn, is_now_linkonce_segment ());
465*fae548d3Szrj return insn;
466*fae548d3Szrj }
467*fae548d3Szrj
468*fae548d3Szrj /* Construct a new FDE structure that begins at LABEL. */
469*fae548d3Szrj
470*fae548d3Szrj void
cfi_new_fde(symbolS * label)471*fae548d3Szrj cfi_new_fde (symbolS *label)
472*fae548d3Szrj {
473*fae548d3Szrj struct fde_entry *fde = alloc_fde_entry ();
474*fae548d3Szrj fde->start_address = label;
475*fae548d3Szrj frchain_now->frch_cfi_data->last_address = label;
476*fae548d3Szrj }
477*fae548d3Szrj
478*fae548d3Szrj /* End the currently open FDE. */
479*fae548d3Szrj
480*fae548d3Szrj void
cfi_end_fde(symbolS * label)481*fae548d3Szrj cfi_end_fde (symbolS *label)
482*fae548d3Szrj {
483*fae548d3Szrj frchain_now->frch_cfi_data->cur_fde_data->end_address = label;
484*fae548d3Szrj free (frchain_now->frch_cfi_data);
485*fae548d3Szrj frchain_now->frch_cfi_data = NULL;
486*fae548d3Szrj }
487*fae548d3Szrj
488*fae548d3Szrj /* Set the return column for the current FDE. */
489*fae548d3Szrj
490*fae548d3Szrj void
cfi_set_return_column(unsigned regno)491*fae548d3Szrj cfi_set_return_column (unsigned regno)
492*fae548d3Szrj {
493*fae548d3Szrj frchain_now->frch_cfi_data->cur_fde_data->return_column = regno;
494*fae548d3Szrj }
495*fae548d3Szrj
496*fae548d3Szrj void
cfi_set_sections(void)497*fae548d3Szrj cfi_set_sections (void)
498*fae548d3Szrj {
499*fae548d3Szrj frchain_now->frch_cfi_data->cur_fde_data->sections = all_cfi_sections;
500*fae548d3Szrj cfi_sections_set = TRUE;
501*fae548d3Szrj }
502*fae548d3Szrj
503*fae548d3Szrj /* Universal functions to store new instructions. */
504*fae548d3Szrj
505*fae548d3Szrj static void
cfi_add_CFA_insn(int insn)506*fae548d3Szrj cfi_add_CFA_insn (int insn)
507*fae548d3Szrj {
508*fae548d3Szrj struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
509*fae548d3Szrj
510*fae548d3Szrj insn_ptr->insn = insn;
511*fae548d3Szrj }
512*fae548d3Szrj
513*fae548d3Szrj static void
cfi_add_CFA_insn_reg(int insn,unsigned regno)514*fae548d3Szrj cfi_add_CFA_insn_reg (int insn, unsigned regno)
515*fae548d3Szrj {
516*fae548d3Szrj struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
517*fae548d3Szrj
518*fae548d3Szrj insn_ptr->insn = insn;
519*fae548d3Szrj insn_ptr->u.r = regno;
520*fae548d3Szrj }
521*fae548d3Szrj
522*fae548d3Szrj static void
cfi_add_CFA_insn_offset(int insn,offsetT offset)523*fae548d3Szrj cfi_add_CFA_insn_offset (int insn, offsetT offset)
524*fae548d3Szrj {
525*fae548d3Szrj struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
526*fae548d3Szrj
527*fae548d3Szrj insn_ptr->insn = insn;
528*fae548d3Szrj insn_ptr->u.i = offset;
529*fae548d3Szrj }
530*fae548d3Szrj
531*fae548d3Szrj static void
cfi_add_CFA_insn_reg_reg(int insn,unsigned reg1,unsigned reg2)532*fae548d3Szrj cfi_add_CFA_insn_reg_reg (int insn, unsigned reg1, unsigned reg2)
533*fae548d3Szrj {
534*fae548d3Szrj struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
535*fae548d3Szrj
536*fae548d3Szrj insn_ptr->insn = insn;
537*fae548d3Szrj insn_ptr->u.rr.reg1 = reg1;
538*fae548d3Szrj insn_ptr->u.rr.reg2 = reg2;
539*fae548d3Szrj }
540*fae548d3Szrj
541*fae548d3Szrj static void
cfi_add_CFA_insn_reg_offset(int insn,unsigned regno,offsetT offset)542*fae548d3Szrj cfi_add_CFA_insn_reg_offset (int insn, unsigned regno, offsetT offset)
543*fae548d3Szrj {
544*fae548d3Szrj struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data ();
545*fae548d3Szrj
546*fae548d3Szrj insn_ptr->insn = insn;
547*fae548d3Szrj insn_ptr->u.ri.reg = regno;
548*fae548d3Szrj insn_ptr->u.ri.offset = offset;
549*fae548d3Szrj }
550*fae548d3Szrj
551*fae548d3Szrj /* Add a CFI insn to advance the PC from the last address to LABEL. */
552*fae548d3Szrj
553*fae548d3Szrj void
cfi_add_advance_loc(symbolS * label)554*fae548d3Szrj cfi_add_advance_loc (symbolS *label)
555*fae548d3Szrj {
556*fae548d3Szrj struct cfi_insn_data *insn = alloc_cfi_insn_data ();
557*fae548d3Szrj
558*fae548d3Szrj insn->insn = DW_CFA_advance_loc;
559*fae548d3Szrj insn->u.ll.lab1 = frchain_now->frch_cfi_data->last_address;
560*fae548d3Szrj insn->u.ll.lab2 = label;
561*fae548d3Szrj
562*fae548d3Szrj frchain_now->frch_cfi_data->last_address = label;
563*fae548d3Szrj }
564*fae548d3Szrj
565*fae548d3Szrj /* Add a CFI insn to label the current position in the CFI segment. */
566*fae548d3Szrj
567*fae548d3Szrj void
cfi_add_label(const char * name)568*fae548d3Szrj cfi_add_label (const char *name)
569*fae548d3Szrj {
570*fae548d3Szrj unsigned int len = strlen (name) + 1;
571*fae548d3Szrj struct cfi_insn_data *insn = alloc_cfi_insn_data ();
572*fae548d3Szrj
573*fae548d3Szrj insn->insn = CFI_label;
574*fae548d3Szrj obstack_grow (¬es, name, len);
575*fae548d3Szrj insn->u.sym_name = (char *) obstack_finish (¬es);
576*fae548d3Szrj }
577*fae548d3Szrj
578*fae548d3Szrj /* Add a DW_CFA_offset record to the CFI data. */
579*fae548d3Szrj
580*fae548d3Szrj void
cfi_add_CFA_offset(unsigned regno,offsetT offset)581*fae548d3Szrj cfi_add_CFA_offset (unsigned regno, offsetT offset)
582*fae548d3Szrj {
583*fae548d3Szrj unsigned int abs_data_align;
584*fae548d3Szrj
585*fae548d3Szrj gas_assert (DWARF2_CIE_DATA_ALIGNMENT != 0);
586*fae548d3Szrj cfi_add_CFA_insn_reg_offset (DW_CFA_offset, regno, offset);
587*fae548d3Szrj
588*fae548d3Szrj abs_data_align = (DWARF2_CIE_DATA_ALIGNMENT < 0
589*fae548d3Szrj ? -DWARF2_CIE_DATA_ALIGNMENT : DWARF2_CIE_DATA_ALIGNMENT);
590*fae548d3Szrj if (offset % abs_data_align)
591*fae548d3Szrj as_bad (_("register save offset not a multiple of %u"), abs_data_align);
592*fae548d3Szrj }
593*fae548d3Szrj
594*fae548d3Szrj /* Add a DW_CFA_val_offset record to the CFI data. */
595*fae548d3Szrj
596*fae548d3Szrj void
cfi_add_CFA_val_offset(unsigned regno,offsetT offset)597*fae548d3Szrj cfi_add_CFA_val_offset (unsigned regno, offsetT offset)
598*fae548d3Szrj {
599*fae548d3Szrj unsigned int abs_data_align;
600*fae548d3Szrj
601*fae548d3Szrj gas_assert (DWARF2_CIE_DATA_ALIGNMENT != 0);
602*fae548d3Szrj cfi_add_CFA_insn_reg_offset (DW_CFA_val_offset, regno, offset);
603*fae548d3Szrj
604*fae548d3Szrj abs_data_align = (DWARF2_CIE_DATA_ALIGNMENT < 0
605*fae548d3Szrj ? -DWARF2_CIE_DATA_ALIGNMENT : DWARF2_CIE_DATA_ALIGNMENT);
606*fae548d3Szrj if (offset % abs_data_align)
607*fae548d3Szrj as_bad (_("register save offset not a multiple of %u"), abs_data_align);
608*fae548d3Szrj }
609*fae548d3Szrj
610*fae548d3Szrj /* Add a DW_CFA_def_cfa record to the CFI data. */
611*fae548d3Szrj
612*fae548d3Szrj void
cfi_add_CFA_def_cfa(unsigned regno,offsetT offset)613*fae548d3Szrj cfi_add_CFA_def_cfa (unsigned regno, offsetT offset)
614*fae548d3Szrj {
615*fae548d3Szrj cfi_add_CFA_insn_reg_offset (DW_CFA_def_cfa, regno, offset);
616*fae548d3Szrj frchain_now->frch_cfi_data->cur_cfa_offset = offset;
617*fae548d3Szrj }
618*fae548d3Szrj
619*fae548d3Szrj /* Add a DW_CFA_register record to the CFI data. */
620*fae548d3Szrj
621*fae548d3Szrj void
cfi_add_CFA_register(unsigned reg1,unsigned reg2)622*fae548d3Szrj cfi_add_CFA_register (unsigned reg1, unsigned reg2)
623*fae548d3Szrj {
624*fae548d3Szrj cfi_add_CFA_insn_reg_reg (DW_CFA_register, reg1, reg2);
625*fae548d3Szrj }
626*fae548d3Szrj
627*fae548d3Szrj /* Add a DW_CFA_def_cfa_register record to the CFI data. */
628*fae548d3Szrj
629*fae548d3Szrj void
cfi_add_CFA_def_cfa_register(unsigned regno)630*fae548d3Szrj cfi_add_CFA_def_cfa_register (unsigned regno)
631*fae548d3Szrj {
632*fae548d3Szrj cfi_add_CFA_insn_reg (DW_CFA_def_cfa_register, regno);
633*fae548d3Szrj }
634*fae548d3Szrj
635*fae548d3Szrj /* Add a DW_CFA_def_cfa_offset record to the CFI data. */
636*fae548d3Szrj
637*fae548d3Szrj void
cfi_add_CFA_def_cfa_offset(offsetT offset)638*fae548d3Szrj cfi_add_CFA_def_cfa_offset (offsetT offset)
639*fae548d3Szrj {
640*fae548d3Szrj cfi_add_CFA_insn_offset (DW_CFA_def_cfa_offset, offset);
641*fae548d3Szrj frchain_now->frch_cfi_data->cur_cfa_offset = offset;
642*fae548d3Szrj }
643*fae548d3Szrj
644*fae548d3Szrj void
cfi_add_CFA_restore(unsigned regno)645*fae548d3Szrj cfi_add_CFA_restore (unsigned regno)
646*fae548d3Szrj {
647*fae548d3Szrj cfi_add_CFA_insn_reg (DW_CFA_restore, regno);
648*fae548d3Szrj }
649*fae548d3Szrj
650*fae548d3Szrj void
cfi_add_CFA_undefined(unsigned regno)651*fae548d3Szrj cfi_add_CFA_undefined (unsigned regno)
652*fae548d3Szrj {
653*fae548d3Szrj cfi_add_CFA_insn_reg (DW_CFA_undefined, regno);
654*fae548d3Szrj }
655*fae548d3Szrj
656*fae548d3Szrj void
cfi_add_CFA_same_value(unsigned regno)657*fae548d3Szrj cfi_add_CFA_same_value (unsigned regno)
658*fae548d3Szrj {
659*fae548d3Szrj cfi_add_CFA_insn_reg (DW_CFA_same_value, regno);
660*fae548d3Szrj }
661*fae548d3Szrj
662*fae548d3Szrj void
cfi_add_CFA_remember_state(void)663*fae548d3Szrj cfi_add_CFA_remember_state (void)
664*fae548d3Szrj {
665*fae548d3Szrj struct cfa_save_data *p;
666*fae548d3Szrj
667*fae548d3Szrj cfi_add_CFA_insn (DW_CFA_remember_state);
668*fae548d3Szrj
669*fae548d3Szrj p = XNEW (struct cfa_save_data);
670*fae548d3Szrj p->cfa_offset = frchain_now->frch_cfi_data->cur_cfa_offset;
671*fae548d3Szrj p->next = frchain_now->frch_cfi_data->cfa_save_stack;
672*fae548d3Szrj frchain_now->frch_cfi_data->cfa_save_stack = p;
673*fae548d3Szrj }
674*fae548d3Szrj
675*fae548d3Szrj void
cfi_add_CFA_restore_state(void)676*fae548d3Szrj cfi_add_CFA_restore_state (void)
677*fae548d3Szrj {
678*fae548d3Szrj struct cfa_save_data *p;
679*fae548d3Szrj
680*fae548d3Szrj cfi_add_CFA_insn (DW_CFA_restore_state);
681*fae548d3Szrj
682*fae548d3Szrj p = frchain_now->frch_cfi_data->cfa_save_stack;
683*fae548d3Szrj if (p)
684*fae548d3Szrj {
685*fae548d3Szrj frchain_now->frch_cfi_data->cur_cfa_offset = p->cfa_offset;
686*fae548d3Szrj frchain_now->frch_cfi_data->cfa_save_stack = p->next;
687*fae548d3Szrj free (p);
688*fae548d3Szrj }
689*fae548d3Szrj else
690*fae548d3Szrj as_bad (_("CFI state restore without previous remember"));
691*fae548d3Szrj }
692*fae548d3Szrj
693*fae548d3Szrj
694*fae548d3Szrj /* Parse CFI assembler directives. */
695*fae548d3Szrj
696*fae548d3Szrj static void dot_cfi (int);
697*fae548d3Szrj static void dot_cfi_escape (int);
698*fae548d3Szrj static void dot_cfi_sections (int);
699*fae548d3Szrj static void dot_cfi_startproc (int);
700*fae548d3Szrj static void dot_cfi_endproc (int);
701*fae548d3Szrj static void dot_cfi_fde_data (int);
702*fae548d3Szrj static void dot_cfi_personality (int);
703*fae548d3Szrj static void dot_cfi_personality_id (int);
704*fae548d3Szrj static void dot_cfi_lsda (int);
705*fae548d3Szrj static void dot_cfi_val_encoded_addr (int);
706*fae548d3Szrj static void dot_cfi_inline_lsda (int);
707*fae548d3Szrj static void dot_cfi_label (int);
708*fae548d3Szrj
709*fae548d3Szrj const pseudo_typeS cfi_pseudo_table[] =
710*fae548d3Szrj {
711*fae548d3Szrj { "cfi_sections", dot_cfi_sections, 0 },
712*fae548d3Szrj { "cfi_startproc", dot_cfi_startproc, 0 },
713*fae548d3Szrj { "cfi_endproc", dot_cfi_endproc, 0 },
714*fae548d3Szrj { "cfi_fde_data", dot_cfi_fde_data, 0 },
715*fae548d3Szrj { "cfi_def_cfa", dot_cfi, DW_CFA_def_cfa },
716*fae548d3Szrj { "cfi_def_cfa_register", dot_cfi, DW_CFA_def_cfa_register },
717*fae548d3Szrj { "cfi_def_cfa_offset", dot_cfi, DW_CFA_def_cfa_offset },
718*fae548d3Szrj { "cfi_adjust_cfa_offset", dot_cfi, CFI_adjust_cfa_offset },
719*fae548d3Szrj { "cfi_offset", dot_cfi, DW_CFA_offset },
720*fae548d3Szrj { "cfi_rel_offset", dot_cfi, CFI_rel_offset },
721*fae548d3Szrj { "cfi_register", dot_cfi, DW_CFA_register },
722*fae548d3Szrj { "cfi_return_column", dot_cfi, CFI_return_column },
723*fae548d3Szrj { "cfi_restore", dot_cfi, DW_CFA_restore },
724*fae548d3Szrj { "cfi_undefined", dot_cfi, DW_CFA_undefined },
725*fae548d3Szrj { "cfi_same_value", dot_cfi, DW_CFA_same_value },
726*fae548d3Szrj { "cfi_remember_state", dot_cfi, DW_CFA_remember_state },
727*fae548d3Szrj { "cfi_restore_state", dot_cfi, DW_CFA_restore_state },
728*fae548d3Szrj { "cfi_window_save", dot_cfi, DW_CFA_GNU_window_save },
729*fae548d3Szrj { "cfi_negate_ra_state", dot_cfi, DW_CFA_AARCH64_negate_ra_state },
730*fae548d3Szrj { "cfi_escape", dot_cfi_escape, 0 },
731*fae548d3Szrj { "cfi_signal_frame", dot_cfi, CFI_signal_frame },
732*fae548d3Szrj { "cfi_personality", dot_cfi_personality, 0 },
733*fae548d3Szrj { "cfi_personality_id", dot_cfi_personality_id, 0 },
734*fae548d3Szrj { "cfi_lsda", dot_cfi_lsda, 0 },
735*fae548d3Szrj { "cfi_val_encoded_addr", dot_cfi_val_encoded_addr, 0 },
736*fae548d3Szrj { "cfi_inline_lsda", dot_cfi_inline_lsda, 0 },
737*fae548d3Szrj { "cfi_label", dot_cfi_label, 0 },
738*fae548d3Szrj { "cfi_val_offset", dot_cfi, DW_CFA_val_offset },
739*fae548d3Szrj { NULL, NULL, 0 }
740*fae548d3Szrj };
741*fae548d3Szrj
742*fae548d3Szrj static void
cfi_parse_separator(void)743*fae548d3Szrj cfi_parse_separator (void)
744*fae548d3Szrj {
745*fae548d3Szrj SKIP_WHITESPACE ();
746*fae548d3Szrj if (*input_line_pointer == ',')
747*fae548d3Szrj input_line_pointer++;
748*fae548d3Szrj else
749*fae548d3Szrj as_bad (_("missing separator"));
750*fae548d3Szrj }
751*fae548d3Szrj
752*fae548d3Szrj #ifndef tc_parse_to_dw2regnum
753*fae548d3Szrj static void
tc_parse_to_dw2regnum(expressionS * exp)754*fae548d3Szrj tc_parse_to_dw2regnum (expressionS *exp)
755*fae548d3Szrj {
756*fae548d3Szrj # ifdef tc_regname_to_dw2regnum
757*fae548d3Szrj SKIP_WHITESPACE ();
758*fae548d3Szrj if (is_name_beginner (*input_line_pointer)
759*fae548d3Szrj || (*input_line_pointer == '%'
760*fae548d3Szrj && is_name_beginner (*++input_line_pointer)))
761*fae548d3Szrj {
762*fae548d3Szrj char *name, c;
763*fae548d3Szrj
764*fae548d3Szrj c = get_symbol_name (& name);
765*fae548d3Szrj
766*fae548d3Szrj exp->X_op = O_constant;
767*fae548d3Szrj exp->X_add_number = tc_regname_to_dw2regnum (name);
768*fae548d3Szrj
769*fae548d3Szrj restore_line_pointer (c);
770*fae548d3Szrj }
771*fae548d3Szrj else
772*fae548d3Szrj # endif
773*fae548d3Szrj expression_and_evaluate (exp);
774*fae548d3Szrj }
775*fae548d3Szrj #endif
776*fae548d3Szrj
777*fae548d3Szrj static unsigned
cfi_parse_reg(void)778*fae548d3Szrj cfi_parse_reg (void)
779*fae548d3Szrj {
780*fae548d3Szrj int regno;
781*fae548d3Szrj expressionS exp;
782*fae548d3Szrj
783*fae548d3Szrj tc_parse_to_dw2regnum (&exp);
784*fae548d3Szrj switch (exp.X_op)
785*fae548d3Szrj {
786*fae548d3Szrj case O_register:
787*fae548d3Szrj case O_constant:
788*fae548d3Szrj regno = exp.X_add_number;
789*fae548d3Szrj break;
790*fae548d3Szrj
791*fae548d3Szrj default:
792*fae548d3Szrj regno = -1;
793*fae548d3Szrj break;
794*fae548d3Szrj }
795*fae548d3Szrj
796*fae548d3Szrj if (regno < 0)
797*fae548d3Szrj {
798*fae548d3Szrj as_bad (_("bad register expression"));
799*fae548d3Szrj regno = 0;
800*fae548d3Szrj }
801*fae548d3Szrj
802*fae548d3Szrj return regno;
803*fae548d3Szrj }
804*fae548d3Szrj
805*fae548d3Szrj static offsetT
cfi_parse_const(void)806*fae548d3Szrj cfi_parse_const (void)
807*fae548d3Szrj {
808*fae548d3Szrj return get_absolute_expression ();
809*fae548d3Szrj }
810*fae548d3Szrj
811*fae548d3Szrj static void
dot_cfi(int arg)812*fae548d3Szrj dot_cfi (int arg)
813*fae548d3Szrj {
814*fae548d3Szrj offsetT offset;
815*fae548d3Szrj unsigned reg1, reg2;
816*fae548d3Szrj
817*fae548d3Szrj if (frchain_now->frch_cfi_data == NULL)
818*fae548d3Szrj {
819*fae548d3Szrj as_bad (_("CFI instruction used without previous .cfi_startproc"));
820*fae548d3Szrj ignore_rest_of_line ();
821*fae548d3Szrj return;
822*fae548d3Szrj }
823*fae548d3Szrj
824*fae548d3Szrj /* If the last address was not at the current PC, advance to current. */
825*fae548d3Szrj if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
826*fae548d3Szrj || (S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
827*fae548d3Szrj != frag_now_fix ()))
828*fae548d3Szrj cfi_add_advance_loc (symbol_temp_new_now ());
829*fae548d3Szrj
830*fae548d3Szrj switch (arg)
831*fae548d3Szrj {
832*fae548d3Szrj case DW_CFA_offset:
833*fae548d3Szrj reg1 = cfi_parse_reg ();
834*fae548d3Szrj cfi_parse_separator ();
835*fae548d3Szrj offset = cfi_parse_const ();
836*fae548d3Szrj cfi_add_CFA_offset (reg1, offset);
837*fae548d3Szrj break;
838*fae548d3Szrj
839*fae548d3Szrj case DW_CFA_val_offset:
840*fae548d3Szrj reg1 = cfi_parse_reg ();
841*fae548d3Szrj cfi_parse_separator ();
842*fae548d3Szrj offset = cfi_parse_const ();
843*fae548d3Szrj cfi_add_CFA_val_offset (reg1, offset);
844*fae548d3Szrj break;
845*fae548d3Szrj
846*fae548d3Szrj case CFI_rel_offset:
847*fae548d3Szrj reg1 = cfi_parse_reg ();
848*fae548d3Szrj cfi_parse_separator ();
849*fae548d3Szrj offset = cfi_parse_const ();
850*fae548d3Szrj cfi_add_CFA_offset (reg1,
851*fae548d3Szrj offset - frchain_now->frch_cfi_data->cur_cfa_offset);
852*fae548d3Szrj break;
853*fae548d3Szrj
854*fae548d3Szrj case DW_CFA_def_cfa:
855*fae548d3Szrj reg1 = cfi_parse_reg ();
856*fae548d3Szrj cfi_parse_separator ();
857*fae548d3Szrj offset = cfi_parse_const ();
858*fae548d3Szrj cfi_add_CFA_def_cfa (reg1, offset);
859*fae548d3Szrj break;
860*fae548d3Szrj
861*fae548d3Szrj case DW_CFA_register:
862*fae548d3Szrj reg1 = cfi_parse_reg ();
863*fae548d3Szrj cfi_parse_separator ();
864*fae548d3Szrj reg2 = cfi_parse_reg ();
865*fae548d3Szrj cfi_add_CFA_register (reg1, reg2);
866*fae548d3Szrj break;
867*fae548d3Szrj
868*fae548d3Szrj case DW_CFA_def_cfa_register:
869*fae548d3Szrj reg1 = cfi_parse_reg ();
870*fae548d3Szrj cfi_add_CFA_def_cfa_register (reg1);
871*fae548d3Szrj break;
872*fae548d3Szrj
873*fae548d3Szrj case DW_CFA_def_cfa_offset:
874*fae548d3Szrj offset = cfi_parse_const ();
875*fae548d3Szrj cfi_add_CFA_def_cfa_offset (offset);
876*fae548d3Szrj break;
877*fae548d3Szrj
878*fae548d3Szrj case CFI_adjust_cfa_offset:
879*fae548d3Szrj offset = cfi_parse_const ();
880*fae548d3Szrj cfi_add_CFA_def_cfa_offset (frchain_now->frch_cfi_data->cur_cfa_offset
881*fae548d3Szrj + offset);
882*fae548d3Szrj break;
883*fae548d3Szrj
884*fae548d3Szrj case DW_CFA_restore:
885*fae548d3Szrj for (;;)
886*fae548d3Szrj {
887*fae548d3Szrj reg1 = cfi_parse_reg ();
888*fae548d3Szrj cfi_add_CFA_restore (reg1);
889*fae548d3Szrj SKIP_WHITESPACE ();
890*fae548d3Szrj if (*input_line_pointer != ',')
891*fae548d3Szrj break;
892*fae548d3Szrj ++input_line_pointer;
893*fae548d3Szrj }
894*fae548d3Szrj break;
895*fae548d3Szrj
896*fae548d3Szrj case DW_CFA_undefined:
897*fae548d3Szrj for (;;)
898*fae548d3Szrj {
899*fae548d3Szrj reg1 = cfi_parse_reg ();
900*fae548d3Szrj cfi_add_CFA_undefined (reg1);
901*fae548d3Szrj SKIP_WHITESPACE ();
902*fae548d3Szrj if (*input_line_pointer != ',')
903*fae548d3Szrj break;
904*fae548d3Szrj ++input_line_pointer;
905*fae548d3Szrj }
906*fae548d3Szrj break;
907*fae548d3Szrj
908*fae548d3Szrj case DW_CFA_same_value:
909*fae548d3Szrj reg1 = cfi_parse_reg ();
910*fae548d3Szrj cfi_add_CFA_same_value (reg1);
911*fae548d3Szrj break;
912*fae548d3Szrj
913*fae548d3Szrj case CFI_return_column:
914*fae548d3Szrj reg1 = cfi_parse_reg ();
915*fae548d3Szrj cfi_set_return_column (reg1);
916*fae548d3Szrj break;
917*fae548d3Szrj
918*fae548d3Szrj case DW_CFA_remember_state:
919*fae548d3Szrj cfi_add_CFA_remember_state ();
920*fae548d3Szrj break;
921*fae548d3Szrj
922*fae548d3Szrj case DW_CFA_restore_state:
923*fae548d3Szrj cfi_add_CFA_restore_state ();
924*fae548d3Szrj break;
925*fae548d3Szrj
926*fae548d3Szrj case DW_CFA_GNU_window_save:
927*fae548d3Szrj cfi_add_CFA_insn (DW_CFA_GNU_window_save);
928*fae548d3Szrj break;
929*fae548d3Szrj
930*fae548d3Szrj case CFI_signal_frame:
931*fae548d3Szrj frchain_now->frch_cfi_data->cur_fde_data->signal_frame = 1;
932*fae548d3Szrj break;
933*fae548d3Szrj
934*fae548d3Szrj default:
935*fae548d3Szrj abort ();
936*fae548d3Szrj }
937*fae548d3Szrj
938*fae548d3Szrj demand_empty_rest_of_line ();
939*fae548d3Szrj }
940*fae548d3Szrj
941*fae548d3Szrj static void
dot_cfi_escape(int ignored ATTRIBUTE_UNUSED)942*fae548d3Szrj dot_cfi_escape (int ignored ATTRIBUTE_UNUSED)
943*fae548d3Szrj {
944*fae548d3Szrj struct cfi_escape_data *head, **tail, *e;
945*fae548d3Szrj struct cfi_insn_data *insn;
946*fae548d3Szrj
947*fae548d3Szrj if (frchain_now->frch_cfi_data == NULL)
948*fae548d3Szrj {
949*fae548d3Szrj as_bad (_("CFI instruction used without previous .cfi_startproc"));
950*fae548d3Szrj ignore_rest_of_line ();
951*fae548d3Szrj return;
952*fae548d3Szrj }
953*fae548d3Szrj
954*fae548d3Szrj /* If the last address was not at the current PC, advance to current. */
955*fae548d3Szrj if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
956*fae548d3Szrj || (S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
957*fae548d3Szrj != frag_now_fix ()))
958*fae548d3Szrj cfi_add_advance_loc (symbol_temp_new_now ());
959*fae548d3Szrj
960*fae548d3Szrj tail = &head;
961*fae548d3Szrj do
962*fae548d3Szrj {
963*fae548d3Szrj e = XNEW (struct cfi_escape_data);
964*fae548d3Szrj do_parse_cons_expression (&e->exp, 1);
965*fae548d3Szrj *tail = e;
966*fae548d3Szrj tail = &e->next;
967*fae548d3Szrj }
968*fae548d3Szrj while (*input_line_pointer++ == ',');
969*fae548d3Szrj *tail = NULL;
970*fae548d3Szrj
971*fae548d3Szrj insn = alloc_cfi_insn_data ();
972*fae548d3Szrj insn->insn = CFI_escape;
973*fae548d3Szrj insn->u.esc = head;
974*fae548d3Szrj
975*fae548d3Szrj --input_line_pointer;
976*fae548d3Szrj demand_empty_rest_of_line ();
977*fae548d3Szrj }
978*fae548d3Szrj
979*fae548d3Szrj static void
dot_cfi_personality(int ignored ATTRIBUTE_UNUSED)980*fae548d3Szrj dot_cfi_personality (int ignored ATTRIBUTE_UNUSED)
981*fae548d3Szrj {
982*fae548d3Szrj struct fde_entry *fde;
983*fae548d3Szrj offsetT encoding;
984*fae548d3Szrj
985*fae548d3Szrj if (frchain_now->frch_cfi_data == NULL)
986*fae548d3Szrj {
987*fae548d3Szrj as_bad (_("CFI instruction used without previous .cfi_startproc"));
988*fae548d3Szrj ignore_rest_of_line ();
989*fae548d3Szrj return;
990*fae548d3Szrj }
991*fae548d3Szrj
992*fae548d3Szrj fde = frchain_now->frch_cfi_data->cur_fde_data;
993*fae548d3Szrj encoding = cfi_parse_const ();
994*fae548d3Szrj if (encoding == DW_EH_PE_omit)
995*fae548d3Szrj {
996*fae548d3Szrj demand_empty_rest_of_line ();
997*fae548d3Szrj fde->per_encoding = encoding;
998*fae548d3Szrj return;
999*fae548d3Szrj }
1000*fae548d3Szrj
1001*fae548d3Szrj if ((encoding & 0xff) != encoding
1002*fae548d3Szrj || ((((encoding & 0x70) != 0
1003*fae548d3Szrj #if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
1004*fae548d3Szrj && (encoding & 0x70) != DW_EH_PE_pcrel
1005*fae548d3Szrj #endif
1006*fae548d3Szrj )
1007*fae548d3Szrj /* leb128 can be handled, but does something actually need it? */
1008*fae548d3Szrj || (encoding & 7) == DW_EH_PE_uleb128
1009*fae548d3Szrj || (encoding & 7) > DW_EH_PE_udata8)
1010*fae548d3Szrj && tc_cfi_reloc_for_encoding (encoding) == BFD_RELOC_NONE))
1011*fae548d3Szrj {
1012*fae548d3Szrj as_bad (_("invalid or unsupported encoding in .cfi_personality"));
1013*fae548d3Szrj ignore_rest_of_line ();
1014*fae548d3Szrj return;
1015*fae548d3Szrj }
1016*fae548d3Szrj
1017*fae548d3Szrj if (*input_line_pointer++ != ',')
1018*fae548d3Szrj {
1019*fae548d3Szrj as_bad (_(".cfi_personality requires encoding and symbol arguments"));
1020*fae548d3Szrj ignore_rest_of_line ();
1021*fae548d3Szrj return;
1022*fae548d3Szrj }
1023*fae548d3Szrj
1024*fae548d3Szrj expression_and_evaluate (&fde->personality);
1025*fae548d3Szrj switch (fde->personality.X_op)
1026*fae548d3Szrj {
1027*fae548d3Szrj case O_symbol:
1028*fae548d3Szrj break;
1029*fae548d3Szrj case O_constant:
1030*fae548d3Szrj if ((encoding & 0x70) == DW_EH_PE_pcrel)
1031*fae548d3Szrj encoding = DW_EH_PE_omit;
1032*fae548d3Szrj break;
1033*fae548d3Szrj default:
1034*fae548d3Szrj encoding = DW_EH_PE_omit;
1035*fae548d3Szrj break;
1036*fae548d3Szrj }
1037*fae548d3Szrj
1038*fae548d3Szrj fde->per_encoding = encoding;
1039*fae548d3Szrj
1040*fae548d3Szrj if (encoding == DW_EH_PE_omit)
1041*fae548d3Szrj {
1042*fae548d3Szrj as_bad (_("wrong second argument to .cfi_personality"));
1043*fae548d3Szrj ignore_rest_of_line ();
1044*fae548d3Szrj return;
1045*fae548d3Szrj }
1046*fae548d3Szrj
1047*fae548d3Szrj demand_empty_rest_of_line ();
1048*fae548d3Szrj }
1049*fae548d3Szrj
1050*fae548d3Szrj static void
dot_cfi_lsda(int ignored ATTRIBUTE_UNUSED)1051*fae548d3Szrj dot_cfi_lsda (int ignored ATTRIBUTE_UNUSED)
1052*fae548d3Szrj {
1053*fae548d3Szrj struct fde_entry *fde;
1054*fae548d3Szrj offsetT encoding;
1055*fae548d3Szrj
1056*fae548d3Szrj if (frchain_now->frch_cfi_data == NULL)
1057*fae548d3Szrj {
1058*fae548d3Szrj as_bad (_("CFI instruction used without previous .cfi_startproc"));
1059*fae548d3Szrj ignore_rest_of_line ();
1060*fae548d3Szrj return;
1061*fae548d3Szrj }
1062*fae548d3Szrj
1063*fae548d3Szrj fde = frchain_now->frch_cfi_data->cur_fde_data;
1064*fae548d3Szrj encoding = cfi_parse_const ();
1065*fae548d3Szrj if (encoding == DW_EH_PE_omit)
1066*fae548d3Szrj {
1067*fae548d3Szrj demand_empty_rest_of_line ();
1068*fae548d3Szrj fde->lsda_encoding = encoding;
1069*fae548d3Szrj return;
1070*fae548d3Szrj }
1071*fae548d3Szrj
1072*fae548d3Szrj if ((encoding & 0xff) != encoding
1073*fae548d3Szrj || ((((encoding & 0x70) != 0
1074*fae548d3Szrj #if CFI_DIFF_LSDA_OK || defined tc_cfi_emit_pcrel_expr
1075*fae548d3Szrj && (encoding & 0x70) != DW_EH_PE_pcrel
1076*fae548d3Szrj #endif
1077*fae548d3Szrj )
1078*fae548d3Szrj /* leb128 can be handled, but does something actually need it? */
1079*fae548d3Szrj || (encoding & 7) == DW_EH_PE_uleb128
1080*fae548d3Szrj || (encoding & 7) > DW_EH_PE_udata8)
1081*fae548d3Szrj && tc_cfi_reloc_for_encoding (encoding) == BFD_RELOC_NONE))
1082*fae548d3Szrj {
1083*fae548d3Szrj as_bad (_("invalid or unsupported encoding in .cfi_lsda"));
1084*fae548d3Szrj ignore_rest_of_line ();
1085*fae548d3Szrj return;
1086*fae548d3Szrj }
1087*fae548d3Szrj
1088*fae548d3Szrj if (*input_line_pointer++ != ',')
1089*fae548d3Szrj {
1090*fae548d3Szrj as_bad (_(".cfi_lsda requires encoding and symbol arguments"));
1091*fae548d3Szrj ignore_rest_of_line ();
1092*fae548d3Szrj return;
1093*fae548d3Szrj }
1094*fae548d3Szrj
1095*fae548d3Szrj fde->lsda_encoding = encoding;
1096*fae548d3Szrj
1097*fae548d3Szrj expression_and_evaluate (&fde->lsda);
1098*fae548d3Szrj switch (fde->lsda.X_op)
1099*fae548d3Szrj {
1100*fae548d3Szrj case O_symbol:
1101*fae548d3Szrj break;
1102*fae548d3Szrj case O_constant:
1103*fae548d3Szrj if ((encoding & 0x70) == DW_EH_PE_pcrel)
1104*fae548d3Szrj encoding = DW_EH_PE_omit;
1105*fae548d3Szrj break;
1106*fae548d3Szrj default:
1107*fae548d3Szrj encoding = DW_EH_PE_omit;
1108*fae548d3Szrj break;
1109*fae548d3Szrj }
1110*fae548d3Szrj
1111*fae548d3Szrj fde->lsda_encoding = encoding;
1112*fae548d3Szrj
1113*fae548d3Szrj if (encoding == DW_EH_PE_omit)
1114*fae548d3Szrj {
1115*fae548d3Szrj as_bad (_("wrong second argument to .cfi_lsda"));
1116*fae548d3Szrj ignore_rest_of_line ();
1117*fae548d3Szrj return;
1118*fae548d3Szrj }
1119*fae548d3Szrj
1120*fae548d3Szrj demand_empty_rest_of_line ();
1121*fae548d3Szrj }
1122*fae548d3Szrj
1123*fae548d3Szrj static void
dot_cfi_val_encoded_addr(int ignored ATTRIBUTE_UNUSED)1124*fae548d3Szrj dot_cfi_val_encoded_addr (int ignored ATTRIBUTE_UNUSED)
1125*fae548d3Szrj {
1126*fae548d3Szrj struct cfi_insn_data *insn_ptr;
1127*fae548d3Szrj offsetT encoding;
1128*fae548d3Szrj
1129*fae548d3Szrj if (frchain_now->frch_cfi_data == NULL)
1130*fae548d3Szrj {
1131*fae548d3Szrj as_bad (_("CFI instruction used without previous .cfi_startproc"));
1132*fae548d3Szrj ignore_rest_of_line ();
1133*fae548d3Szrj return;
1134*fae548d3Szrj }
1135*fae548d3Szrj
1136*fae548d3Szrj /* If the last address was not at the current PC, advance to current. */
1137*fae548d3Szrj if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
1138*fae548d3Szrj || (S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
1139*fae548d3Szrj != frag_now_fix ()))
1140*fae548d3Szrj cfi_add_advance_loc (symbol_temp_new_now ());
1141*fae548d3Szrj
1142*fae548d3Szrj insn_ptr = alloc_cfi_insn_data ();
1143*fae548d3Szrj insn_ptr->insn = CFI_val_encoded_addr;
1144*fae548d3Szrj
1145*fae548d3Szrj insn_ptr->u.ea.reg = cfi_parse_reg ();
1146*fae548d3Szrj
1147*fae548d3Szrj cfi_parse_separator ();
1148*fae548d3Szrj encoding = cfi_parse_const ();
1149*fae548d3Szrj if ((encoding & 0xff) != encoding
1150*fae548d3Szrj || ((encoding & 0x70) != 0
1151*fae548d3Szrj #if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
1152*fae548d3Szrj && (encoding & 0x70) != DW_EH_PE_pcrel
1153*fae548d3Szrj #endif
1154*fae548d3Szrj )
1155*fae548d3Szrj /* leb128 can be handled, but does something actually need it? */
1156*fae548d3Szrj || (encoding & 7) == DW_EH_PE_uleb128
1157*fae548d3Szrj || (encoding & 7) > DW_EH_PE_udata8)
1158*fae548d3Szrj {
1159*fae548d3Szrj as_bad (_("invalid or unsupported encoding in .cfi_lsda"));
1160*fae548d3Szrj encoding = DW_EH_PE_omit;
1161*fae548d3Szrj }
1162*fae548d3Szrj
1163*fae548d3Szrj cfi_parse_separator ();
1164*fae548d3Szrj expression_and_evaluate (&insn_ptr->u.ea.exp);
1165*fae548d3Szrj switch (insn_ptr->u.ea.exp.X_op)
1166*fae548d3Szrj {
1167*fae548d3Szrj case O_symbol:
1168*fae548d3Szrj break;
1169*fae548d3Szrj case O_constant:
1170*fae548d3Szrj if ((encoding & 0x70) != DW_EH_PE_pcrel)
1171*fae548d3Szrj break;
1172*fae548d3Szrj /* Fall through. */
1173*fae548d3Szrj default:
1174*fae548d3Szrj encoding = DW_EH_PE_omit;
1175*fae548d3Szrj break;
1176*fae548d3Szrj }
1177*fae548d3Szrj
1178*fae548d3Szrj insn_ptr->u.ea.encoding = encoding;
1179*fae548d3Szrj if (encoding == DW_EH_PE_omit)
1180*fae548d3Szrj {
1181*fae548d3Szrj as_bad (_("wrong third argument to .cfi_val_encoded_addr"));
1182*fae548d3Szrj ignore_rest_of_line ();
1183*fae548d3Szrj return;
1184*fae548d3Szrj }
1185*fae548d3Szrj
1186*fae548d3Szrj demand_empty_rest_of_line ();
1187*fae548d3Szrj }
1188*fae548d3Szrj
1189*fae548d3Szrj static void
dot_cfi_label(int ignored ATTRIBUTE_UNUSED)1190*fae548d3Szrj dot_cfi_label (int ignored ATTRIBUTE_UNUSED)
1191*fae548d3Szrj {
1192*fae548d3Szrj char *name;
1193*fae548d3Szrj
1194*fae548d3Szrj if (frchain_now->frch_cfi_data == NULL)
1195*fae548d3Szrj {
1196*fae548d3Szrj as_bad (_("CFI instruction used without previous .cfi_startproc"));
1197*fae548d3Szrj ignore_rest_of_line ();
1198*fae548d3Szrj return;
1199*fae548d3Szrj }
1200*fae548d3Szrj
1201*fae548d3Szrj name = read_symbol_name ();
1202*fae548d3Szrj if (name == NULL)
1203*fae548d3Szrj return;
1204*fae548d3Szrj
1205*fae548d3Szrj /* If the last address was not at the current PC, advance to current. */
1206*fae548d3Szrj if (symbol_get_frag (frchain_now->frch_cfi_data->last_address) != frag_now
1207*fae548d3Szrj || (S_GET_VALUE (frchain_now->frch_cfi_data->last_address)
1208*fae548d3Szrj != frag_now_fix ()))
1209*fae548d3Szrj cfi_add_advance_loc (symbol_temp_new_now ());
1210*fae548d3Szrj
1211*fae548d3Szrj cfi_add_label (name);
1212*fae548d3Szrj free (name);
1213*fae548d3Szrj
1214*fae548d3Szrj demand_empty_rest_of_line ();
1215*fae548d3Szrj }
1216*fae548d3Szrj
1217*fae548d3Szrj static void
dot_cfi_sections(int ignored ATTRIBUTE_UNUSED)1218*fae548d3Szrj dot_cfi_sections (int ignored ATTRIBUTE_UNUSED)
1219*fae548d3Szrj {
1220*fae548d3Szrj int sections = 0;
1221*fae548d3Szrj
1222*fae548d3Szrj SKIP_WHITESPACE ();
1223*fae548d3Szrj if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"')
1224*fae548d3Szrj while (1)
1225*fae548d3Szrj {
1226*fae548d3Szrj char * saved_ilp;
1227*fae548d3Szrj char *name, c;
1228*fae548d3Szrj
1229*fae548d3Szrj saved_ilp = input_line_pointer;
1230*fae548d3Szrj c = get_symbol_name (& name);
1231*fae548d3Szrj
1232*fae548d3Szrj if (strncmp (name, ".eh_frame", sizeof ".eh_frame") == 0
1233*fae548d3Szrj && name[9] != '_')
1234*fae548d3Szrj sections |= CFI_EMIT_eh_frame;
1235*fae548d3Szrj else if (strncmp (name, ".debug_frame", sizeof ".debug_frame") == 0)
1236*fae548d3Szrj sections |= CFI_EMIT_debug_frame;
1237*fae548d3Szrj #if SUPPORT_COMPACT_EH
1238*fae548d3Szrj else if (strncmp (name, ".eh_frame_entry",
1239*fae548d3Szrj sizeof ".eh_frame_entry") == 0)
1240*fae548d3Szrj {
1241*fae548d3Szrj compact_eh = TRUE;
1242*fae548d3Szrj sections |= CFI_EMIT_eh_frame_compact;
1243*fae548d3Szrj }
1244*fae548d3Szrj #endif
1245*fae548d3Szrj #ifdef tc_cfi_section_name
1246*fae548d3Szrj else if (strcmp (name, tc_cfi_section_name) == 0)
1247*fae548d3Szrj sections |= CFI_EMIT_target;
1248*fae548d3Szrj #endif
1249*fae548d3Szrj else
1250*fae548d3Szrj {
1251*fae548d3Szrj *input_line_pointer = c;
1252*fae548d3Szrj input_line_pointer = saved_ilp;
1253*fae548d3Szrj break;
1254*fae548d3Szrj }
1255*fae548d3Szrj
1256*fae548d3Szrj *input_line_pointer = c;
1257*fae548d3Szrj SKIP_WHITESPACE_AFTER_NAME ();
1258*fae548d3Szrj if (*input_line_pointer == ',')
1259*fae548d3Szrj {
1260*fae548d3Szrj name = input_line_pointer++;
1261*fae548d3Szrj SKIP_WHITESPACE ();
1262*fae548d3Szrj if (!is_name_beginner (*input_line_pointer)
1263*fae548d3Szrj && *input_line_pointer != '"')
1264*fae548d3Szrj {
1265*fae548d3Szrj input_line_pointer = name;
1266*fae548d3Szrj break;
1267*fae548d3Szrj }
1268*fae548d3Szrj }
1269*fae548d3Szrj else if (is_name_beginner (*input_line_pointer)
1270*fae548d3Szrj || *input_line_pointer == '"')
1271*fae548d3Szrj break;
1272*fae548d3Szrj }
1273*fae548d3Szrj
1274*fae548d3Szrj demand_empty_rest_of_line ();
1275*fae548d3Szrj if (cfi_sections_set
1276*fae548d3Szrj && (sections & (CFI_EMIT_eh_frame | CFI_EMIT_eh_frame_compact))
1277*fae548d3Szrj && ((cfi_sections & (CFI_EMIT_eh_frame | CFI_EMIT_eh_frame_compact))
1278*fae548d3Szrj != (sections & (CFI_EMIT_eh_frame | CFI_EMIT_eh_frame_compact))))
1279*fae548d3Szrj as_bad (_("inconsistent uses of .cfi_sections"));
1280*fae548d3Szrj cfi_sections = sections;
1281*fae548d3Szrj }
1282*fae548d3Szrj
1283*fae548d3Szrj static void
dot_cfi_startproc(int ignored ATTRIBUTE_UNUSED)1284*fae548d3Szrj dot_cfi_startproc (int ignored ATTRIBUTE_UNUSED)
1285*fae548d3Szrj {
1286*fae548d3Szrj int simple = 0;
1287*fae548d3Szrj
1288*fae548d3Szrj if (frchain_now->frch_cfi_data != NULL)
1289*fae548d3Szrj {
1290*fae548d3Szrj as_bad (_("previous CFI entry not closed (missing .cfi_endproc)"));
1291*fae548d3Szrj ignore_rest_of_line ();
1292*fae548d3Szrj return;
1293*fae548d3Szrj }
1294*fae548d3Szrj
1295*fae548d3Szrj cfi_new_fde (symbol_temp_new_now ());
1296*fae548d3Szrj
1297*fae548d3Szrj SKIP_WHITESPACE ();
1298*fae548d3Szrj if (is_name_beginner (*input_line_pointer) || *input_line_pointer == '"')
1299*fae548d3Szrj {
1300*fae548d3Szrj char * saved_ilp = input_line_pointer;
1301*fae548d3Szrj char *name, c;
1302*fae548d3Szrj
1303*fae548d3Szrj c = get_symbol_name (& name);
1304*fae548d3Szrj
1305*fae548d3Szrj if (strcmp (name, "simple") == 0)
1306*fae548d3Szrj {
1307*fae548d3Szrj simple = 1;
1308*fae548d3Szrj restore_line_pointer (c);
1309*fae548d3Szrj }
1310*fae548d3Szrj else
1311*fae548d3Szrj input_line_pointer = saved_ilp;
1312*fae548d3Szrj }
1313*fae548d3Szrj demand_empty_rest_of_line ();
1314*fae548d3Szrj
1315*fae548d3Szrj cfi_sections_set = TRUE;
1316*fae548d3Szrj all_cfi_sections |= cfi_sections;
1317*fae548d3Szrj cfi_set_sections ();
1318*fae548d3Szrj frchain_now->frch_cfi_data->cur_cfa_offset = 0;
1319*fae548d3Szrj if (!simple)
1320*fae548d3Szrj tc_cfi_frame_initial_instructions ();
1321*fae548d3Szrj
1322*fae548d3Szrj if ((cfi_sections & CFI_EMIT_target) != 0)
1323*fae548d3Szrj tc_cfi_startproc ();
1324*fae548d3Szrj }
1325*fae548d3Szrj
1326*fae548d3Szrj static void
dot_cfi_endproc(int ignored ATTRIBUTE_UNUSED)1327*fae548d3Szrj dot_cfi_endproc (int ignored ATTRIBUTE_UNUSED)
1328*fae548d3Szrj {
1329*fae548d3Szrj if (frchain_now->frch_cfi_data == NULL)
1330*fae548d3Szrj {
1331*fae548d3Szrj as_bad (_(".cfi_endproc without corresponding .cfi_startproc"));
1332*fae548d3Szrj ignore_rest_of_line ();
1333*fae548d3Szrj return;
1334*fae548d3Szrj }
1335*fae548d3Szrj
1336*fae548d3Szrj last_fde = frchain_now->frch_cfi_data->cur_fde_data;
1337*fae548d3Szrj
1338*fae548d3Szrj cfi_end_fde (symbol_temp_new_now ());
1339*fae548d3Szrj
1340*fae548d3Szrj demand_empty_rest_of_line ();
1341*fae548d3Szrj
1342*fae548d3Szrj cfi_sections_set = TRUE;
1343*fae548d3Szrj if ((cfi_sections & CFI_EMIT_target) != 0)
1344*fae548d3Szrj tc_cfi_endproc (last_fde);
1345*fae548d3Szrj }
1346*fae548d3Szrj
1347*fae548d3Szrj static segT
get_cfi_seg(segT cseg,const char * base,flagword flags,int align)1348*fae548d3Szrj get_cfi_seg (segT cseg, const char *base, flagword flags, int align)
1349*fae548d3Szrj {
1350*fae548d3Szrj /* Exclude .debug_frame sections for Compact EH. */
1351*fae548d3Szrj if (SUPPORT_FRAME_LINKONCE || ((flags & SEC_DEBUGGING) == 0 && compact_eh))
1352*fae548d3Szrj {
1353*fae548d3Szrj struct dwcfi_seg_list *l;
1354*fae548d3Szrj
1355*fae548d3Szrj l = dwcfi_hash_find_or_make (cseg, base, flags);
1356*fae548d3Szrj
1357*fae548d3Szrj cseg = l->seg;
1358*fae548d3Szrj subseg_set (cseg, l->subseg);
1359*fae548d3Szrj }
1360*fae548d3Szrj else
1361*fae548d3Szrj {
1362*fae548d3Szrj cseg = subseg_new (base, 0);
1363*fae548d3Szrj bfd_set_section_flags (cseg, flags);
1364*fae548d3Szrj }
1365*fae548d3Szrj record_alignment (cseg, align);
1366*fae548d3Szrj return cseg;
1367*fae548d3Szrj }
1368*fae548d3Szrj
1369*fae548d3Szrj #if SUPPORT_COMPACT_EH
1370*fae548d3Szrj static void
dot_cfi_personality_id(int ignored ATTRIBUTE_UNUSED)1371*fae548d3Szrj dot_cfi_personality_id (int ignored ATTRIBUTE_UNUSED)
1372*fae548d3Szrj {
1373*fae548d3Szrj struct fde_entry *fde;
1374*fae548d3Szrj
1375*fae548d3Szrj if (frchain_now->frch_cfi_data == NULL)
1376*fae548d3Szrj {
1377*fae548d3Szrj as_bad (_("CFI instruction used without previous .cfi_startproc"));
1378*fae548d3Szrj ignore_rest_of_line ();
1379*fae548d3Szrj return;
1380*fae548d3Szrj }
1381*fae548d3Szrj
1382*fae548d3Szrj fde = frchain_now->frch_cfi_data->cur_fde_data;
1383*fae548d3Szrj fde->personality_id = cfi_parse_const ();
1384*fae548d3Szrj demand_empty_rest_of_line ();
1385*fae548d3Szrj
1386*fae548d3Szrj if (fde->personality_id == 0 || fde->personality_id > 3)
1387*fae548d3Szrj {
1388*fae548d3Szrj as_bad (_("wrong argument to .cfi_personality_id"));
1389*fae548d3Szrj return;
1390*fae548d3Szrj }
1391*fae548d3Szrj }
1392*fae548d3Szrj
1393*fae548d3Szrj static void
dot_cfi_fde_data(int ignored ATTRIBUTE_UNUSED)1394*fae548d3Szrj dot_cfi_fde_data (int ignored ATTRIBUTE_UNUSED)
1395*fae548d3Szrj {
1396*fae548d3Szrj if (frchain_now->frch_cfi_data == NULL)
1397*fae548d3Szrj {
1398*fae548d3Szrj as_bad (_(".cfi_fde_data without corresponding .cfi_startproc"));
1399*fae548d3Szrj ignore_rest_of_line ();
1400*fae548d3Szrj return;
1401*fae548d3Szrj }
1402*fae548d3Szrj
1403*fae548d3Szrj last_fde = frchain_now->frch_cfi_data->cur_fde_data;
1404*fae548d3Szrj
1405*fae548d3Szrj cfi_sections_set = TRUE;
1406*fae548d3Szrj if ((cfi_sections & CFI_EMIT_target) != 0
1407*fae548d3Szrj || (cfi_sections & CFI_EMIT_eh_frame_compact) != 0)
1408*fae548d3Szrj {
1409*fae548d3Szrj struct cfi_escape_data *head, **tail, *e;
1410*fae548d3Szrj int num_ops = 0;
1411*fae548d3Szrj
1412*fae548d3Szrj tail = &head;
1413*fae548d3Szrj if (!is_it_end_of_statement ())
1414*fae548d3Szrj {
1415*fae548d3Szrj num_ops = 0;
1416*fae548d3Szrj do
1417*fae548d3Szrj {
1418*fae548d3Szrj e = XNEW (struct cfi_escape_data);
1419*fae548d3Szrj do_parse_cons_expression (&e->exp, 1);
1420*fae548d3Szrj *tail = e;
1421*fae548d3Szrj tail = &e->next;
1422*fae548d3Szrj num_ops++;
1423*fae548d3Szrj }
1424*fae548d3Szrj while (*input_line_pointer++ == ',');
1425*fae548d3Szrj --input_line_pointer;
1426*fae548d3Szrj }
1427*fae548d3Szrj *tail = NULL;
1428*fae548d3Szrj
1429*fae548d3Szrj if (last_fde->lsda_encoding != DW_EH_PE_omit)
1430*fae548d3Szrj last_fde->eh_header_type = EH_COMPACT_HAS_LSDA;
1431*fae548d3Szrj else if (num_ops <= 3 && last_fde->per_encoding == DW_EH_PE_omit)
1432*fae548d3Szrj last_fde->eh_header_type = EH_COMPACT_INLINE;
1433*fae548d3Szrj else
1434*fae548d3Szrj last_fde->eh_header_type = EH_COMPACT_OUTLINE;
1435*fae548d3Szrj
1436*fae548d3Szrj if (last_fde->eh_header_type == EH_COMPACT_INLINE)
1437*fae548d3Szrj num_ops = 3;
1438*fae548d3Szrj
1439*fae548d3Szrj last_fde->eh_data_size = num_ops;
1440*fae548d3Szrj last_fde->eh_data = XNEWVEC (bfd_byte, num_ops);
1441*fae548d3Szrj num_ops = 0;
1442*fae548d3Szrj while (head)
1443*fae548d3Szrj {
1444*fae548d3Szrj e = head;
1445*fae548d3Szrj head = e->next;
1446*fae548d3Szrj last_fde->eh_data[num_ops++] = e->exp.X_add_number;
1447*fae548d3Szrj free (e);
1448*fae548d3Szrj }
1449*fae548d3Szrj if (last_fde->eh_header_type == EH_COMPACT_INLINE)
1450*fae548d3Szrj while (num_ops < 3)
1451*fae548d3Szrj last_fde->eh_data[num_ops++] = tc_compact_eh_opcode_stop;
1452*fae548d3Szrj }
1453*fae548d3Szrj
1454*fae548d3Szrj demand_empty_rest_of_line ();
1455*fae548d3Szrj }
1456*fae548d3Szrj
1457*fae548d3Szrj /* Function to emit the compact unwinding opcodes stored in the
1458*fae548d3Szrj fde's eh_data field. The end of the opcode data will be
1459*fae548d3Szrj padded to the value in align. */
1460*fae548d3Szrj
1461*fae548d3Szrj static void
output_compact_unwind_data(struct fde_entry * fde,int align)1462*fae548d3Szrj output_compact_unwind_data (struct fde_entry *fde, int align)
1463*fae548d3Szrj {
1464*fae548d3Szrj int data_size = fde->eh_data_size + 2;
1465*fae548d3Szrj int align_padding;
1466*fae548d3Szrj int amask;
1467*fae548d3Szrj char *p;
1468*fae548d3Szrj
1469*fae548d3Szrj fde->eh_loc = symbol_temp_new_now ();
1470*fae548d3Szrj
1471*fae548d3Szrj p = frag_more (1);
1472*fae548d3Szrj if (fde->personality_id != 0)
1473*fae548d3Szrj *p = fde->personality_id;
1474*fae548d3Szrj else if (fde->per_encoding != DW_EH_PE_omit)
1475*fae548d3Szrj {
1476*fae548d3Szrj *p = 0;
1477*fae548d3Szrj emit_expr_encoded (&fde->personality, fde->per_encoding, FALSE);
1478*fae548d3Szrj data_size += encoding_size (fde->per_encoding);
1479*fae548d3Szrj }
1480*fae548d3Szrj else
1481*fae548d3Szrj *p = 1;
1482*fae548d3Szrj
1483*fae548d3Szrj amask = (1 << align) - 1;
1484*fae548d3Szrj align_padding = ((data_size + amask) & ~amask) - data_size;
1485*fae548d3Szrj
1486*fae548d3Szrj p = frag_more (fde->eh_data_size + 1 + align_padding);
1487*fae548d3Szrj memcpy (p, fde->eh_data, fde->eh_data_size);
1488*fae548d3Szrj p += fde->eh_data_size;
1489*fae548d3Szrj
1490*fae548d3Szrj while (align_padding-- > 0)
1491*fae548d3Szrj *(p++) = tc_compact_eh_opcode_pad;
1492*fae548d3Szrj
1493*fae548d3Szrj *(p++) = tc_compact_eh_opcode_stop;
1494*fae548d3Szrj fde->eh_header_type = EH_COMPACT_OUTLINE_DONE;
1495*fae548d3Szrj }
1496*fae548d3Szrj
1497*fae548d3Szrj /* Handle the .cfi_inline_lsda directive. */
1498*fae548d3Szrj static void
dot_cfi_inline_lsda(int ignored ATTRIBUTE_UNUSED)1499*fae548d3Szrj dot_cfi_inline_lsda (int ignored ATTRIBUTE_UNUSED)
1500*fae548d3Szrj {
1501*fae548d3Szrj segT ccseg;
1502*fae548d3Szrj int align;
1503*fae548d3Szrj long max_alignment = 28;
1504*fae548d3Szrj
1505*fae548d3Szrj if (!last_fde)
1506*fae548d3Szrj {
1507*fae548d3Szrj as_bad (_("unexpected .cfi_inline_lsda"));
1508*fae548d3Szrj ignore_rest_of_line ();
1509*fae548d3Szrj return;
1510*fae548d3Szrj }
1511*fae548d3Szrj
1512*fae548d3Szrj if ((last_fde->sections & CFI_EMIT_eh_frame_compact) == 0)
1513*fae548d3Szrj {
1514*fae548d3Szrj as_bad (_(".cfi_inline_lsda not valid for this frame"));
1515*fae548d3Szrj ignore_rest_of_line ();
1516*fae548d3Szrj return;
1517*fae548d3Szrj }
1518*fae548d3Szrj
1519*fae548d3Szrj if (last_fde->eh_header_type != EH_COMPACT_UNKNOWN
1520*fae548d3Szrj && last_fde->eh_header_type != EH_COMPACT_HAS_LSDA)
1521*fae548d3Szrj {
1522*fae548d3Szrj as_bad (_(".cfi_inline_lsda seen for frame without .cfi_lsda"));
1523*fae548d3Szrj ignore_rest_of_line ();
1524*fae548d3Szrj return;
1525*fae548d3Szrj }
1526*fae548d3Szrj
1527*fae548d3Szrj #ifdef md_flush_pending_output
1528*fae548d3Szrj md_flush_pending_output ();
1529*fae548d3Szrj #endif
1530*fae548d3Szrj
1531*fae548d3Szrj align = get_absolute_expression ();
1532*fae548d3Szrj if (align > max_alignment)
1533*fae548d3Szrj {
1534*fae548d3Szrj align = max_alignment;
1535*fae548d3Szrj as_bad (_("Alignment too large: %d. assumed."), align);
1536*fae548d3Szrj }
1537*fae548d3Szrj else if (align < 0)
1538*fae548d3Szrj {
1539*fae548d3Szrj as_warn (_("Alignment negative: 0 assumed."));
1540*fae548d3Szrj align = 0;
1541*fae548d3Szrj }
1542*fae548d3Szrj
1543*fae548d3Szrj demand_empty_rest_of_line ();
1544*fae548d3Szrj ccseg = CUR_SEG (last_fde);
1545*fae548d3Szrj
1546*fae548d3Szrj /* Open .gnu_extab section. */
1547*fae548d3Szrj get_cfi_seg (ccseg, ".gnu_extab",
1548*fae548d3Szrj (SEC_ALLOC | SEC_LOAD | SEC_DATA
1549*fae548d3Szrj | DWARF2_EH_FRAME_READ_ONLY),
1550*fae548d3Szrj 1);
1551*fae548d3Szrj
1552*fae548d3Szrj frag_align (align, 0, 0);
1553*fae548d3Szrj record_alignment (now_seg, align);
1554*fae548d3Szrj if (last_fde->eh_header_type == EH_COMPACT_HAS_LSDA)
1555*fae548d3Szrj output_compact_unwind_data (last_fde, align);
1556*fae548d3Szrj
1557*fae548d3Szrj last_fde = NULL;
1558*fae548d3Szrj
1559*fae548d3Szrj return;
1560*fae548d3Szrj }
1561*fae548d3Szrj #else /* !SUPPORT_COMPACT_EH */
1562*fae548d3Szrj static void
dot_cfi_inline_lsda(int ignored ATTRIBUTE_UNUSED)1563*fae548d3Szrj dot_cfi_inline_lsda (int ignored ATTRIBUTE_UNUSED)
1564*fae548d3Szrj {
1565*fae548d3Szrj as_bad (_(".cfi_inline_lsda is not supported for this target"));
1566*fae548d3Szrj ignore_rest_of_line ();
1567*fae548d3Szrj }
1568*fae548d3Szrj
1569*fae548d3Szrj static void
dot_cfi_fde_data(int ignored ATTRIBUTE_UNUSED)1570*fae548d3Szrj dot_cfi_fde_data (int ignored ATTRIBUTE_UNUSED)
1571*fae548d3Szrj {
1572*fae548d3Szrj as_bad (_(".cfi_fde_data is not supported for this target"));
1573*fae548d3Szrj ignore_rest_of_line ();
1574*fae548d3Szrj }
1575*fae548d3Szrj
1576*fae548d3Szrj static void
dot_cfi_personality_id(int ignored ATTRIBUTE_UNUSED)1577*fae548d3Szrj dot_cfi_personality_id (int ignored ATTRIBUTE_UNUSED)
1578*fae548d3Szrj {
1579*fae548d3Szrj as_bad (_(".cfi_personality_id is not supported for this target"));
1580*fae548d3Szrj ignore_rest_of_line ();
1581*fae548d3Szrj }
1582*fae548d3Szrj #endif
1583*fae548d3Szrj
1584*fae548d3Szrj static void
output_cfi_insn(struct cfi_insn_data * insn)1585*fae548d3Szrj output_cfi_insn (struct cfi_insn_data *insn)
1586*fae548d3Szrj {
1587*fae548d3Szrj offsetT offset;
1588*fae548d3Szrj unsigned int regno;
1589*fae548d3Szrj
1590*fae548d3Szrj switch (insn->insn)
1591*fae548d3Szrj {
1592*fae548d3Szrj case DW_CFA_advance_loc:
1593*fae548d3Szrj {
1594*fae548d3Szrj symbolS *from = insn->u.ll.lab1;
1595*fae548d3Szrj symbolS *to = insn->u.ll.lab2;
1596*fae548d3Szrj
1597*fae548d3Szrj if (symbol_get_frag (to) == symbol_get_frag (from))
1598*fae548d3Szrj {
1599*fae548d3Szrj addressT delta = S_GET_VALUE (to) - S_GET_VALUE (from);
1600*fae548d3Szrj addressT scaled = delta / DWARF2_LINE_MIN_INSN_LENGTH;
1601*fae548d3Szrj
1602*fae548d3Szrj if (scaled == 0)
1603*fae548d3Szrj ;
1604*fae548d3Szrj else if (scaled <= 0x3F)
1605*fae548d3Szrj out_one (DW_CFA_advance_loc + scaled);
1606*fae548d3Szrj else if (scaled <= 0xFF)
1607*fae548d3Szrj {
1608*fae548d3Szrj out_one (DW_CFA_advance_loc1);
1609*fae548d3Szrj out_one (scaled);
1610*fae548d3Szrj }
1611*fae548d3Szrj else if (scaled <= 0xFFFF)
1612*fae548d3Szrj {
1613*fae548d3Szrj out_one (DW_CFA_advance_loc2);
1614*fae548d3Szrj out_two (scaled);
1615*fae548d3Szrj }
1616*fae548d3Szrj else
1617*fae548d3Szrj {
1618*fae548d3Szrj out_one (DW_CFA_advance_loc4);
1619*fae548d3Szrj out_four (scaled);
1620*fae548d3Szrj }
1621*fae548d3Szrj }
1622*fae548d3Szrj else
1623*fae548d3Szrj {
1624*fae548d3Szrj expressionS exp;
1625*fae548d3Szrj
1626*fae548d3Szrj exp.X_op = O_subtract;
1627*fae548d3Szrj exp.X_add_symbol = to;
1628*fae548d3Szrj exp.X_op_symbol = from;
1629*fae548d3Szrj exp.X_add_number = 0;
1630*fae548d3Szrj
1631*fae548d3Szrj /* The code in ehopt.c expects that one byte of the encoding
1632*fae548d3Szrj is already allocated to the frag. This comes from the way
1633*fae548d3Szrj that it scans the .eh_frame section looking first for the
1634*fae548d3Szrj .byte DW_CFA_advance_loc4. Call frag_grow with the sum of
1635*fae548d3Szrj room needed by frag_more and frag_var to preallocate space
1636*fae548d3Szrj ensuring that the DW_CFA_advance_loc4 is in the fixed part
1637*fae548d3Szrj of the rs_cfa frag, so that the relax machinery can remove
1638*fae548d3Szrj the advance_loc should it advance by zero. */
1639*fae548d3Szrj frag_grow (5);
1640*fae548d3Szrj *frag_more (1) = DW_CFA_advance_loc4;
1641*fae548d3Szrj
1642*fae548d3Szrj frag_var (rs_cfa, 4, 0, DWARF2_LINE_MIN_INSN_LENGTH << 3,
1643*fae548d3Szrj make_expr_symbol (&exp), frag_now_fix () - 1,
1644*fae548d3Szrj (char *) frag_now);
1645*fae548d3Szrj }
1646*fae548d3Szrj }
1647*fae548d3Szrj break;
1648*fae548d3Szrj
1649*fae548d3Szrj case DW_CFA_def_cfa:
1650*fae548d3Szrj offset = insn->u.ri.offset;
1651*fae548d3Szrj if (offset < 0)
1652*fae548d3Szrj {
1653*fae548d3Szrj out_one (DW_CFA_def_cfa_sf);
1654*fae548d3Szrj out_uleb128 (insn->u.ri.reg);
1655*fae548d3Szrj out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT);
1656*fae548d3Szrj }
1657*fae548d3Szrj else
1658*fae548d3Szrj {
1659*fae548d3Szrj out_one (DW_CFA_def_cfa);
1660*fae548d3Szrj out_uleb128 (insn->u.ri.reg);
1661*fae548d3Szrj out_uleb128 (offset);
1662*fae548d3Szrj }
1663*fae548d3Szrj break;
1664*fae548d3Szrj
1665*fae548d3Szrj case DW_CFA_def_cfa_register:
1666*fae548d3Szrj case DW_CFA_undefined:
1667*fae548d3Szrj case DW_CFA_same_value:
1668*fae548d3Szrj out_one (insn->insn);
1669*fae548d3Szrj out_uleb128 (insn->u.r);
1670*fae548d3Szrj break;
1671*fae548d3Szrj
1672*fae548d3Szrj case DW_CFA_def_cfa_offset:
1673*fae548d3Szrj offset = insn->u.i;
1674*fae548d3Szrj if (offset < 0)
1675*fae548d3Szrj {
1676*fae548d3Szrj out_one (DW_CFA_def_cfa_offset_sf);
1677*fae548d3Szrj out_sleb128 (offset / DWARF2_CIE_DATA_ALIGNMENT);
1678*fae548d3Szrj }
1679*fae548d3Szrj else
1680*fae548d3Szrj {
1681*fae548d3Szrj out_one (DW_CFA_def_cfa_offset);
1682*fae548d3Szrj out_uleb128 (offset);
1683*fae548d3Szrj }
1684*fae548d3Szrj break;
1685*fae548d3Szrj
1686*fae548d3Szrj case DW_CFA_restore:
1687*fae548d3Szrj regno = insn->u.r;
1688*fae548d3Szrj if (regno <= 0x3F)
1689*fae548d3Szrj {
1690*fae548d3Szrj out_one (DW_CFA_restore + regno);
1691*fae548d3Szrj }
1692*fae548d3Szrj else
1693*fae548d3Szrj {
1694*fae548d3Szrj out_one (DW_CFA_restore_extended);
1695*fae548d3Szrj out_uleb128 (regno);
1696*fae548d3Szrj }
1697*fae548d3Szrj break;
1698*fae548d3Szrj
1699*fae548d3Szrj case DW_CFA_offset:
1700*fae548d3Szrj regno = insn->u.ri.reg;
1701*fae548d3Szrj offset = insn->u.ri.offset / DWARF2_CIE_DATA_ALIGNMENT;
1702*fae548d3Szrj if (offset < 0)
1703*fae548d3Szrj {
1704*fae548d3Szrj out_one (DW_CFA_offset_extended_sf);
1705*fae548d3Szrj out_uleb128 (regno);
1706*fae548d3Szrj out_sleb128 (offset);
1707*fae548d3Szrj }
1708*fae548d3Szrj else if (regno <= 0x3F)
1709*fae548d3Szrj {
1710*fae548d3Szrj out_one (DW_CFA_offset + regno);
1711*fae548d3Szrj out_uleb128 (offset);
1712*fae548d3Szrj }
1713*fae548d3Szrj else
1714*fae548d3Szrj {
1715*fae548d3Szrj out_one (DW_CFA_offset_extended);
1716*fae548d3Szrj out_uleb128 (regno);
1717*fae548d3Szrj out_uleb128 (offset);
1718*fae548d3Szrj }
1719*fae548d3Szrj break;
1720*fae548d3Szrj
1721*fae548d3Szrj case DW_CFA_val_offset:
1722*fae548d3Szrj regno = insn->u.ri.reg;
1723*fae548d3Szrj offset = insn->u.ri.offset / DWARF2_CIE_DATA_ALIGNMENT;
1724*fae548d3Szrj if (offset < 0)
1725*fae548d3Szrj {
1726*fae548d3Szrj out_one (DW_CFA_val_offset_sf);
1727*fae548d3Szrj out_uleb128 (regno);
1728*fae548d3Szrj out_sleb128 (offset);
1729*fae548d3Szrj }
1730*fae548d3Szrj else
1731*fae548d3Szrj {
1732*fae548d3Szrj out_one (DW_CFA_val_offset);
1733*fae548d3Szrj out_uleb128 (regno);
1734*fae548d3Szrj out_uleb128 (offset);
1735*fae548d3Szrj }
1736*fae548d3Szrj break;
1737*fae548d3Szrj
1738*fae548d3Szrj case DW_CFA_register:
1739*fae548d3Szrj out_one (DW_CFA_register);
1740*fae548d3Szrj out_uleb128 (insn->u.rr.reg1);
1741*fae548d3Szrj out_uleb128 (insn->u.rr.reg2);
1742*fae548d3Szrj break;
1743*fae548d3Szrj
1744*fae548d3Szrj case DW_CFA_remember_state:
1745*fae548d3Szrj case DW_CFA_restore_state:
1746*fae548d3Szrj out_one (insn->insn);
1747*fae548d3Szrj break;
1748*fae548d3Szrj
1749*fae548d3Szrj case DW_CFA_GNU_window_save:
1750*fae548d3Szrj out_one (DW_CFA_GNU_window_save);
1751*fae548d3Szrj break;
1752*fae548d3Szrj
1753*fae548d3Szrj case CFI_escape:
1754*fae548d3Szrj {
1755*fae548d3Szrj struct cfi_escape_data *e;
1756*fae548d3Szrj for (e = insn->u.esc; e ; e = e->next)
1757*fae548d3Szrj emit_expr (&e->exp, 1);
1758*fae548d3Szrj break;
1759*fae548d3Szrj }
1760*fae548d3Szrj
1761*fae548d3Szrj case CFI_val_encoded_addr:
1762*fae548d3Szrj {
1763*fae548d3Szrj unsigned encoding = insn->u.ea.encoding;
1764*fae548d3Szrj offsetT enc_size;
1765*fae548d3Szrj
1766*fae548d3Szrj if (encoding == DW_EH_PE_omit)
1767*fae548d3Szrj break;
1768*fae548d3Szrj out_one (DW_CFA_val_expression);
1769*fae548d3Szrj out_uleb128 (insn->u.ea.reg);
1770*fae548d3Szrj
1771*fae548d3Szrj switch (encoding & 0x7)
1772*fae548d3Szrj {
1773*fae548d3Szrj case DW_EH_PE_absptr:
1774*fae548d3Szrj enc_size = DWARF2_ADDR_SIZE (stdoutput);
1775*fae548d3Szrj break;
1776*fae548d3Szrj case DW_EH_PE_udata2:
1777*fae548d3Szrj enc_size = 2;
1778*fae548d3Szrj break;
1779*fae548d3Szrj case DW_EH_PE_udata4:
1780*fae548d3Szrj enc_size = 4;
1781*fae548d3Szrj break;
1782*fae548d3Szrj case DW_EH_PE_udata8:
1783*fae548d3Szrj enc_size = 8;
1784*fae548d3Szrj break;
1785*fae548d3Szrj default:
1786*fae548d3Szrj abort ();
1787*fae548d3Szrj }
1788*fae548d3Szrj
1789*fae548d3Szrj /* If the user has requested absolute encoding,
1790*fae548d3Szrj then use the smaller DW_OP_addr encoding. */
1791*fae548d3Szrj if (insn->u.ea.encoding == DW_EH_PE_absptr)
1792*fae548d3Szrj {
1793*fae548d3Szrj out_uleb128 (1 + enc_size);
1794*fae548d3Szrj out_one (DW_OP_addr);
1795*fae548d3Szrj }
1796*fae548d3Szrj else
1797*fae548d3Szrj {
1798*fae548d3Szrj out_uleb128 (1 + 1 + enc_size);
1799*fae548d3Szrj out_one (DW_OP_GNU_encoded_addr);
1800*fae548d3Szrj out_one (encoding);
1801*fae548d3Szrj
1802*fae548d3Szrj if ((encoding & 0x70) == DW_EH_PE_pcrel)
1803*fae548d3Szrj {
1804*fae548d3Szrj #if CFI_DIFF_EXPR_OK
1805*fae548d3Szrj insn->u.ea.exp.X_op = O_subtract;
1806*fae548d3Szrj insn->u.ea.exp.X_op_symbol = symbol_temp_new_now ();
1807*fae548d3Szrj #elif defined (tc_cfi_emit_pcrel_expr)
1808*fae548d3Szrj tc_cfi_emit_pcrel_expr (&insn->u.ea.exp, enc_size);
1809*fae548d3Szrj break;
1810*fae548d3Szrj #else
1811*fae548d3Szrj abort ();
1812*fae548d3Szrj #endif
1813*fae548d3Szrj }
1814*fae548d3Szrj }
1815*fae548d3Szrj emit_expr (&insn->u.ea.exp, enc_size);
1816*fae548d3Szrj }
1817*fae548d3Szrj break;
1818*fae548d3Szrj
1819*fae548d3Szrj case CFI_label:
1820*fae548d3Szrj colon (insn->u.sym_name);
1821*fae548d3Szrj break;
1822*fae548d3Szrj
1823*fae548d3Szrj default:
1824*fae548d3Szrj abort ();
1825*fae548d3Szrj }
1826*fae548d3Szrj }
1827*fae548d3Szrj
1828*fae548d3Szrj static void
output_cie(struct cie_entry * cie,bfd_boolean eh_frame,int align)1829*fae548d3Szrj output_cie (struct cie_entry *cie, bfd_boolean eh_frame, int align)
1830*fae548d3Szrj {
1831*fae548d3Szrj symbolS *after_size_address, *end_address;
1832*fae548d3Szrj expressionS exp;
1833*fae548d3Szrj struct cfi_insn_data *i;
1834*fae548d3Szrj offsetT augmentation_size;
1835*fae548d3Szrj int enc;
1836*fae548d3Szrj enum dwarf2_format fmt = DWARF2_FORMAT (now_seg);
1837*fae548d3Szrj
1838*fae548d3Szrj cie->start_address = symbol_temp_new_now ();
1839*fae548d3Szrj after_size_address = symbol_temp_make ();
1840*fae548d3Szrj end_address = symbol_temp_make ();
1841*fae548d3Szrj
1842*fae548d3Szrj exp.X_op = O_subtract;
1843*fae548d3Szrj exp.X_add_symbol = end_address;
1844*fae548d3Szrj exp.X_op_symbol = after_size_address;
1845*fae548d3Szrj exp.X_add_number = 0;
1846*fae548d3Szrj
1847*fae548d3Szrj if (eh_frame || fmt == dwarf2_format_32bit)
1848*fae548d3Szrj emit_expr (&exp, 4); /* Length. */
1849*fae548d3Szrj else
1850*fae548d3Szrj {
1851*fae548d3Szrj if (fmt == dwarf2_format_64bit)
1852*fae548d3Szrj out_four (-1);
1853*fae548d3Szrj emit_expr (&exp, 8); /* Length. */
1854*fae548d3Szrj }
1855*fae548d3Szrj symbol_set_value_now (after_size_address);
1856*fae548d3Szrj if (eh_frame)
1857*fae548d3Szrj out_four (0); /* CIE id. */
1858*fae548d3Szrj else
1859*fae548d3Szrj {
1860*fae548d3Szrj out_four (-1); /* CIE id. */
1861*fae548d3Szrj if (fmt != dwarf2_format_32bit)
1862*fae548d3Szrj out_four (-1);
1863*fae548d3Szrj }
1864*fae548d3Szrj out_one (flag_dwarf_cie_version); /* Version. */
1865*fae548d3Szrj if (eh_frame)
1866*fae548d3Szrj {
1867*fae548d3Szrj out_one ('z'); /* Augmentation. */
1868*fae548d3Szrj if (cie->per_encoding != DW_EH_PE_omit)
1869*fae548d3Szrj out_one ('P');
1870*fae548d3Szrj if (cie->lsda_encoding != DW_EH_PE_omit)
1871*fae548d3Szrj out_one ('L');
1872*fae548d3Szrj out_one ('R');
1873*fae548d3Szrj #ifdef tc_output_cie_extra
1874*fae548d3Szrj tc_output_cie_extra (cie);
1875*fae548d3Szrj #endif
1876*fae548d3Szrj }
1877*fae548d3Szrj if (cie->signal_frame)
1878*fae548d3Szrj out_one ('S');
1879*fae548d3Szrj out_one (0);
1880*fae548d3Szrj if (flag_dwarf_cie_version >= 4)
1881*fae548d3Szrj {
1882*fae548d3Szrj /* For now we are assuming a flat address space with 4 or 8 byte
1883*fae548d3Szrj addresses. */
1884*fae548d3Szrj int address_size = dwarf2_format_32bit ? 4 : 8;
1885*fae548d3Szrj out_one (address_size); /* Address size. */
1886*fae548d3Szrj out_one (0); /* Segment size. */
1887*fae548d3Szrj }
1888*fae548d3Szrj out_uleb128 (DWARF2_LINE_MIN_INSN_LENGTH); /* Code alignment. */
1889*fae548d3Szrj out_sleb128 (DWARF2_CIE_DATA_ALIGNMENT); /* Data alignment. */
1890*fae548d3Szrj if (flag_dwarf_cie_version == 1) /* Return column. */
1891*fae548d3Szrj {
1892*fae548d3Szrj if ((cie->return_column & 0xff) != cie->return_column)
1893*fae548d3Szrj as_bad (_("return column number %d overflows in CIE version 1"),
1894*fae548d3Szrj cie->return_column);
1895*fae548d3Szrj out_one (cie->return_column);
1896*fae548d3Szrj }
1897*fae548d3Szrj else
1898*fae548d3Szrj out_uleb128 (cie->return_column);
1899*fae548d3Szrj if (eh_frame)
1900*fae548d3Szrj {
1901*fae548d3Szrj augmentation_size = 1 + (cie->lsda_encoding != DW_EH_PE_omit);
1902*fae548d3Szrj if (cie->per_encoding != DW_EH_PE_omit)
1903*fae548d3Szrj augmentation_size += 1 + encoding_size (cie->per_encoding);
1904*fae548d3Szrj out_uleb128 (augmentation_size); /* Augmentation size. */
1905*fae548d3Szrj
1906*fae548d3Szrj emit_expr_encoded (&cie->personality, cie->per_encoding, TRUE);
1907*fae548d3Szrj
1908*fae548d3Szrj if (cie->lsda_encoding != DW_EH_PE_omit)
1909*fae548d3Szrj out_one (cie->lsda_encoding);
1910*fae548d3Szrj }
1911*fae548d3Szrj
1912*fae548d3Szrj switch (DWARF2_FDE_RELOC_SIZE)
1913*fae548d3Szrj {
1914*fae548d3Szrj case 2:
1915*fae548d3Szrj enc = DW_EH_PE_sdata2;
1916*fae548d3Szrj break;
1917*fae548d3Szrj case 4:
1918*fae548d3Szrj enc = DW_EH_PE_sdata4;
1919*fae548d3Szrj break;
1920*fae548d3Szrj case 8:
1921*fae548d3Szrj enc = DW_EH_PE_sdata8;
1922*fae548d3Szrj break;
1923*fae548d3Szrj default:
1924*fae548d3Szrj abort ();
1925*fae548d3Szrj }
1926*fae548d3Szrj #if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
1927*fae548d3Szrj enc |= DW_EH_PE_pcrel;
1928*fae548d3Szrj #endif
1929*fae548d3Szrj #ifdef DWARF2_FDE_RELOC_ENCODING
1930*fae548d3Szrj /* Allow target to override encoding. */
1931*fae548d3Szrj enc = DWARF2_FDE_RELOC_ENCODING (enc);
1932*fae548d3Szrj #endif
1933*fae548d3Szrj cie->fde_encoding = enc;
1934*fae548d3Szrj if (eh_frame)
1935*fae548d3Szrj out_one (enc);
1936*fae548d3Szrj
1937*fae548d3Szrj if (cie->first)
1938*fae548d3Szrj {
1939*fae548d3Szrj for (i = cie->first; i != cie->last; i = i->next)
1940*fae548d3Szrj {
1941*fae548d3Szrj if (CUR_SEG (i) != CUR_SEG (cie))
1942*fae548d3Szrj continue;
1943*fae548d3Szrj output_cfi_insn (i);
1944*fae548d3Szrj }
1945*fae548d3Szrj }
1946*fae548d3Szrj
1947*fae548d3Szrj frag_align (align, DW_CFA_nop, 0);
1948*fae548d3Szrj symbol_set_value_now (end_address);
1949*fae548d3Szrj }
1950*fae548d3Szrj
1951*fae548d3Szrj static void
output_fde(struct fde_entry * fde,struct cie_entry * cie,bfd_boolean eh_frame,struct cfi_insn_data * first,int align)1952*fae548d3Szrj output_fde (struct fde_entry *fde, struct cie_entry *cie,
1953*fae548d3Szrj bfd_boolean eh_frame, struct cfi_insn_data *first,
1954*fae548d3Szrj int align)
1955*fae548d3Szrj {
1956*fae548d3Szrj symbolS *after_size_address, *end_address;
1957*fae548d3Szrj expressionS exp;
1958*fae548d3Szrj offsetT augmentation_size;
1959*fae548d3Szrj enum dwarf2_format fmt = DWARF2_FORMAT (now_seg);
1960*fae548d3Szrj unsigned int offset_size;
1961*fae548d3Szrj unsigned int addr_size;
1962*fae548d3Szrj
1963*fae548d3Szrj after_size_address = symbol_temp_make ();
1964*fae548d3Szrj end_address = symbol_temp_make ();
1965*fae548d3Szrj
1966*fae548d3Szrj exp.X_op = O_subtract;
1967*fae548d3Szrj exp.X_add_symbol = end_address;
1968*fae548d3Szrj exp.X_op_symbol = after_size_address;
1969*fae548d3Szrj exp.X_add_number = 0;
1970*fae548d3Szrj if (eh_frame || fmt == dwarf2_format_32bit)
1971*fae548d3Szrj offset_size = 4;
1972*fae548d3Szrj else
1973*fae548d3Szrj {
1974*fae548d3Szrj if (fmt == dwarf2_format_64bit)
1975*fae548d3Szrj out_four (-1);
1976*fae548d3Szrj offset_size = 8;
1977*fae548d3Szrj }
1978*fae548d3Szrj emit_expr (&exp, offset_size); /* Length. */
1979*fae548d3Szrj symbol_set_value_now (after_size_address);
1980*fae548d3Szrj
1981*fae548d3Szrj if (eh_frame)
1982*fae548d3Szrj {
1983*fae548d3Szrj exp.X_op = O_subtract;
1984*fae548d3Szrj exp.X_add_symbol = after_size_address;
1985*fae548d3Szrj exp.X_op_symbol = cie->start_address;
1986*fae548d3Szrj exp.X_add_number = 0;
1987*fae548d3Szrj emit_expr (&exp, offset_size); /* CIE offset. */
1988*fae548d3Szrj }
1989*fae548d3Szrj else
1990*fae548d3Szrj {
1991*fae548d3Szrj TC_DWARF2_EMIT_OFFSET (cie->start_address, offset_size);
1992*fae548d3Szrj }
1993*fae548d3Szrj
1994*fae548d3Szrj exp.X_op = O_symbol;
1995*fae548d3Szrj if (eh_frame)
1996*fae548d3Szrj {
1997*fae548d3Szrj bfd_reloc_code_real_type code
1998*fae548d3Szrj = tc_cfi_reloc_for_encoding (cie->fde_encoding);
1999*fae548d3Szrj addr_size = DWARF2_FDE_RELOC_SIZE;
2000*fae548d3Szrj if (code != BFD_RELOC_NONE)
2001*fae548d3Szrj {
2002*fae548d3Szrj reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, code);
2003*fae548d3Szrj char *p = frag_more (addr_size);
2004*fae548d3Szrj gas_assert (addr_size == (unsigned) howto->bitsize / 8);
2005*fae548d3Szrj md_number_to_chars (p, 0, addr_size);
2006*fae548d3Szrj fix_new (frag_now, p - frag_now->fr_literal, addr_size,
2007*fae548d3Szrj fde->start_address, 0, howto->pc_relative, code);
2008*fae548d3Szrj }
2009*fae548d3Szrj else
2010*fae548d3Szrj {
2011*fae548d3Szrj exp.X_op = O_subtract;
2012*fae548d3Szrj exp.X_add_number = 0;
2013*fae548d3Szrj #if CFI_DIFF_EXPR_OK
2014*fae548d3Szrj exp.X_add_symbol = fde->start_address;
2015*fae548d3Szrj exp.X_op_symbol = symbol_temp_new_now ();
2016*fae548d3Szrj emit_expr (&exp, addr_size); /* Code offset. */
2017*fae548d3Szrj #else
2018*fae548d3Szrj exp.X_op = O_symbol;
2019*fae548d3Szrj exp.X_add_symbol = fde->start_address;
2020*fae548d3Szrj
2021*fae548d3Szrj #if defined(tc_cfi_emit_pcrel_expr)
2022*fae548d3Szrj tc_cfi_emit_pcrel_expr (&exp, addr_size); /* Code offset. */
2023*fae548d3Szrj #else
2024*fae548d3Szrj emit_expr (&exp, addr_size); /* Code offset. */
2025*fae548d3Szrj #endif
2026*fae548d3Szrj #endif
2027*fae548d3Szrj }
2028*fae548d3Szrj }
2029*fae548d3Szrj else
2030*fae548d3Szrj {
2031*fae548d3Szrj exp.X_add_number = 0;
2032*fae548d3Szrj exp.X_add_symbol = fde->start_address;
2033*fae548d3Szrj addr_size = DWARF2_ADDR_SIZE (stdoutput);
2034*fae548d3Szrj emit_expr (&exp, addr_size);
2035*fae548d3Szrj }
2036*fae548d3Szrj
2037*fae548d3Szrj exp.X_op = O_subtract;
2038*fae548d3Szrj exp.X_add_symbol = fde->end_address;
2039*fae548d3Szrj exp.X_op_symbol = fde->start_address; /* Code length. */
2040*fae548d3Szrj exp.X_add_number = 0;
2041*fae548d3Szrj emit_expr (&exp, addr_size);
2042*fae548d3Szrj
2043*fae548d3Szrj augmentation_size = encoding_size (fde->lsda_encoding);
2044*fae548d3Szrj if (eh_frame)
2045*fae548d3Szrj out_uleb128 (augmentation_size); /* Augmentation size. */
2046*fae548d3Szrj
2047*fae548d3Szrj emit_expr_encoded (&fde->lsda, cie->lsda_encoding, FALSE);
2048*fae548d3Szrj
2049*fae548d3Szrj for (; first; first = first->next)
2050*fae548d3Szrj if (CUR_SEG (first) == CUR_SEG (fde))
2051*fae548d3Szrj output_cfi_insn (first);
2052*fae548d3Szrj
2053*fae548d3Szrj frag_align (align, DW_CFA_nop, 0);
2054*fae548d3Szrj symbol_set_value_now (end_address);
2055*fae548d3Szrj }
2056*fae548d3Szrj
2057*fae548d3Szrj static struct cie_entry *
select_cie_for_fde(struct fde_entry * fde,bfd_boolean eh_frame,struct cfi_insn_data ** pfirst,int align)2058*fae548d3Szrj select_cie_for_fde (struct fde_entry *fde, bfd_boolean eh_frame,
2059*fae548d3Szrj struct cfi_insn_data **pfirst, int align)
2060*fae548d3Szrj {
2061*fae548d3Szrj struct cfi_insn_data *i, *j;
2062*fae548d3Szrj struct cie_entry *cie;
2063*fae548d3Szrj
2064*fae548d3Szrj for (cie = cie_root; cie; cie = cie->next)
2065*fae548d3Szrj {
2066*fae548d3Szrj if (CUR_SEG (cie) != CUR_SEG (fde))
2067*fae548d3Szrj continue;
2068*fae548d3Szrj #ifdef tc_cie_fde_equivalent_extra
2069*fae548d3Szrj if (!tc_cie_fde_equivalent_extra (cie, fde))
2070*fae548d3Szrj continue;
2071*fae548d3Szrj #endif
2072*fae548d3Szrj if (cie->return_column != fde->return_column
2073*fae548d3Szrj || cie->signal_frame != fde->signal_frame
2074*fae548d3Szrj || cie->per_encoding != fde->per_encoding
2075*fae548d3Szrj || cie->lsda_encoding != fde->lsda_encoding)
2076*fae548d3Szrj continue;
2077*fae548d3Szrj if (cie->per_encoding != DW_EH_PE_omit)
2078*fae548d3Szrj {
2079*fae548d3Szrj if (cie->personality.X_op != fde->personality.X_op
2080*fae548d3Szrj || (cie->personality.X_add_number
2081*fae548d3Szrj != fde->personality.X_add_number))
2082*fae548d3Szrj continue;
2083*fae548d3Szrj switch (cie->personality.X_op)
2084*fae548d3Szrj {
2085*fae548d3Szrj case O_constant:
2086*fae548d3Szrj if (cie->personality.X_unsigned != fde->personality.X_unsigned)
2087*fae548d3Szrj continue;
2088*fae548d3Szrj break;
2089*fae548d3Szrj case O_symbol:
2090*fae548d3Szrj if (cie->personality.X_add_symbol
2091*fae548d3Szrj != fde->personality.X_add_symbol)
2092*fae548d3Szrj continue;
2093*fae548d3Szrj break;
2094*fae548d3Szrj default:
2095*fae548d3Szrj abort ();
2096*fae548d3Szrj }
2097*fae548d3Szrj }
2098*fae548d3Szrj for (i = cie->first, j = fde->data;
2099*fae548d3Szrj i != cie->last && j != NULL;
2100*fae548d3Szrj i = i->next, j = j->next)
2101*fae548d3Szrj {
2102*fae548d3Szrj if (i->insn != j->insn)
2103*fae548d3Szrj goto fail;
2104*fae548d3Szrj switch (i->insn)
2105*fae548d3Szrj {
2106*fae548d3Szrj case DW_CFA_advance_loc:
2107*fae548d3Szrj case DW_CFA_remember_state:
2108*fae548d3Szrj /* We reached the first advance/remember in the FDE,
2109*fae548d3Szrj but did not reach the end of the CIE list. */
2110*fae548d3Szrj goto fail;
2111*fae548d3Szrj
2112*fae548d3Szrj case DW_CFA_offset:
2113*fae548d3Szrj case DW_CFA_def_cfa:
2114*fae548d3Szrj if (i->u.ri.reg != j->u.ri.reg)
2115*fae548d3Szrj goto fail;
2116*fae548d3Szrj if (i->u.ri.offset != j->u.ri.offset)
2117*fae548d3Szrj goto fail;
2118*fae548d3Szrj break;
2119*fae548d3Szrj
2120*fae548d3Szrj case DW_CFA_register:
2121*fae548d3Szrj if (i->u.rr.reg1 != j->u.rr.reg1)
2122*fae548d3Szrj goto fail;
2123*fae548d3Szrj if (i->u.rr.reg2 != j->u.rr.reg2)
2124*fae548d3Szrj goto fail;
2125*fae548d3Szrj break;
2126*fae548d3Szrj
2127*fae548d3Szrj case DW_CFA_def_cfa_register:
2128*fae548d3Szrj case DW_CFA_restore:
2129*fae548d3Szrj case DW_CFA_undefined:
2130*fae548d3Szrj case DW_CFA_same_value:
2131*fae548d3Szrj if (i->u.r != j->u.r)
2132*fae548d3Szrj goto fail;
2133*fae548d3Szrj break;
2134*fae548d3Szrj
2135*fae548d3Szrj case DW_CFA_def_cfa_offset:
2136*fae548d3Szrj if (i->u.i != j->u.i)
2137*fae548d3Szrj goto fail;
2138*fae548d3Szrj break;
2139*fae548d3Szrj
2140*fae548d3Szrj case CFI_escape:
2141*fae548d3Szrj case CFI_val_encoded_addr:
2142*fae548d3Szrj case CFI_label:
2143*fae548d3Szrj /* Don't bother matching these for now. */
2144*fae548d3Szrj goto fail;
2145*fae548d3Szrj
2146*fae548d3Szrj default:
2147*fae548d3Szrj abort ();
2148*fae548d3Szrj }
2149*fae548d3Szrj }
2150*fae548d3Szrj
2151*fae548d3Szrj /* Success if we reached the end of the CIE list, and we've either
2152*fae548d3Szrj run out of FDE entries or we've encountered an advance,
2153*fae548d3Szrj remember, or escape. */
2154*fae548d3Szrj if (i == cie->last
2155*fae548d3Szrj && (!j
2156*fae548d3Szrj || j->insn == DW_CFA_advance_loc
2157*fae548d3Szrj || j->insn == DW_CFA_remember_state
2158*fae548d3Szrj || j->insn == CFI_escape
2159*fae548d3Szrj || j->insn == CFI_val_encoded_addr
2160*fae548d3Szrj || j->insn == CFI_label))
2161*fae548d3Szrj {
2162*fae548d3Szrj *pfirst = j;
2163*fae548d3Szrj return cie;
2164*fae548d3Szrj }
2165*fae548d3Szrj
2166*fae548d3Szrj fail:;
2167*fae548d3Szrj }
2168*fae548d3Szrj
2169*fae548d3Szrj cie = XNEW (struct cie_entry);
2170*fae548d3Szrj cie->next = cie_root;
2171*fae548d3Szrj cie_root = cie;
2172*fae548d3Szrj SET_CUR_SEG (cie, CUR_SEG (fde));
2173*fae548d3Szrj cie->return_column = fde->return_column;
2174*fae548d3Szrj cie->signal_frame = fde->signal_frame;
2175*fae548d3Szrj cie->per_encoding = fde->per_encoding;
2176*fae548d3Szrj cie->lsda_encoding = fde->lsda_encoding;
2177*fae548d3Szrj cie->personality = fde->personality;
2178*fae548d3Szrj cie->first = fde->data;
2179*fae548d3Szrj #ifdef tc_cie_entry_init_extra
2180*fae548d3Szrj tc_cie_entry_init_extra (cie, fde)
2181*fae548d3Szrj #endif
2182*fae548d3Szrj
2183*fae548d3Szrj for (i = cie->first; i ; i = i->next)
2184*fae548d3Szrj if (i->insn == DW_CFA_advance_loc
2185*fae548d3Szrj || i->insn == DW_CFA_remember_state
2186*fae548d3Szrj || i->insn == CFI_escape
2187*fae548d3Szrj || i->insn == CFI_val_encoded_addr
2188*fae548d3Szrj || i->insn == CFI_label)
2189*fae548d3Szrj break;
2190*fae548d3Szrj
2191*fae548d3Szrj cie->last = i;
2192*fae548d3Szrj *pfirst = i;
2193*fae548d3Szrj
2194*fae548d3Szrj output_cie (cie, eh_frame, align);
2195*fae548d3Szrj
2196*fae548d3Szrj return cie;
2197*fae548d3Szrj }
2198*fae548d3Szrj
2199*fae548d3Szrj #ifdef md_reg_eh_frame_to_debug_frame
2200*fae548d3Szrj static void
cfi_change_reg_numbers(struct cfi_insn_data * insn,segT ccseg)2201*fae548d3Szrj cfi_change_reg_numbers (struct cfi_insn_data *insn, segT ccseg)
2202*fae548d3Szrj {
2203*fae548d3Szrj for (; insn; insn = insn->next)
2204*fae548d3Szrj {
2205*fae548d3Szrj if (CUR_SEG (insn) != ccseg)
2206*fae548d3Szrj continue;
2207*fae548d3Szrj switch (insn->insn)
2208*fae548d3Szrj {
2209*fae548d3Szrj case DW_CFA_advance_loc:
2210*fae548d3Szrj case DW_CFA_def_cfa_offset:
2211*fae548d3Szrj case DW_CFA_remember_state:
2212*fae548d3Szrj case DW_CFA_restore_state:
2213*fae548d3Szrj case DW_CFA_GNU_window_save:
2214*fae548d3Szrj case CFI_escape:
2215*fae548d3Szrj case CFI_label:
2216*fae548d3Szrj break;
2217*fae548d3Szrj
2218*fae548d3Szrj case DW_CFA_def_cfa:
2219*fae548d3Szrj case DW_CFA_offset:
2220*fae548d3Szrj insn->u.ri.reg = md_reg_eh_frame_to_debug_frame (insn->u.ri.reg);
2221*fae548d3Szrj break;
2222*fae548d3Szrj
2223*fae548d3Szrj case DW_CFA_def_cfa_register:
2224*fae548d3Szrj case DW_CFA_undefined:
2225*fae548d3Szrj case DW_CFA_same_value:
2226*fae548d3Szrj case DW_CFA_restore:
2227*fae548d3Szrj insn->u.r = md_reg_eh_frame_to_debug_frame (insn->u.r);
2228*fae548d3Szrj break;
2229*fae548d3Szrj
2230*fae548d3Szrj case DW_CFA_register:
2231*fae548d3Szrj insn->u.rr.reg1 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg1);
2232*fae548d3Szrj insn->u.rr.reg2 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg2);
2233*fae548d3Szrj break;
2234*fae548d3Szrj
2235*fae548d3Szrj case CFI_val_encoded_addr:
2236*fae548d3Szrj insn->u.ea.reg = md_reg_eh_frame_to_debug_frame (insn->u.ea.reg);
2237*fae548d3Szrj break;
2238*fae548d3Szrj
2239*fae548d3Szrj default:
2240*fae548d3Szrj abort ();
2241*fae548d3Szrj }
2242*fae548d3Szrj }
2243*fae548d3Szrj }
2244*fae548d3Szrj #else
2245*fae548d3Szrj #define cfi_change_reg_numbers(insn, cseg) do { } while (0)
2246*fae548d3Szrj #endif
2247*fae548d3Szrj
2248*fae548d3Szrj #if SUPPORT_COMPACT_EH
2249*fae548d3Szrj static void
cfi_emit_eh_header(symbolS * sym,bfd_vma addend)2250*fae548d3Szrj cfi_emit_eh_header (symbolS *sym, bfd_vma addend)
2251*fae548d3Szrj {
2252*fae548d3Szrj expressionS exp;
2253*fae548d3Szrj
2254*fae548d3Szrj exp.X_add_number = addend;
2255*fae548d3Szrj exp.X_add_symbol = sym;
2256*fae548d3Szrj emit_expr_encoded (&exp, DW_EH_PE_sdata4 | DW_EH_PE_pcrel, FALSE);
2257*fae548d3Szrj }
2258*fae548d3Szrj
2259*fae548d3Szrj static void
output_eh_header(struct fde_entry * fde)2260*fae548d3Szrj output_eh_header (struct fde_entry *fde)
2261*fae548d3Szrj {
2262*fae548d3Szrj char *p;
2263*fae548d3Szrj bfd_vma addend;
2264*fae548d3Szrj
2265*fae548d3Szrj if (fde->eh_header_type == EH_COMPACT_INLINE)
2266*fae548d3Szrj addend = 0;
2267*fae548d3Szrj else
2268*fae548d3Szrj addend = 1;
2269*fae548d3Szrj
2270*fae548d3Szrj cfi_emit_eh_header (fde->start_address, addend);
2271*fae548d3Szrj
2272*fae548d3Szrj if (fde->eh_header_type == EH_COMPACT_INLINE)
2273*fae548d3Szrj {
2274*fae548d3Szrj p = frag_more (4);
2275*fae548d3Szrj /* Inline entries always use PR1. */
2276*fae548d3Szrj *(p++) = 1;
2277*fae548d3Szrj memcpy(p, fde->eh_data, 3);
2278*fae548d3Szrj }
2279*fae548d3Szrj else
2280*fae548d3Szrj {
2281*fae548d3Szrj if (fde->eh_header_type == EH_COMPACT_LEGACY)
2282*fae548d3Szrj addend = 1;
2283*fae548d3Szrj else if (fde->eh_header_type == EH_COMPACT_OUTLINE
2284*fae548d3Szrj || fde->eh_header_type == EH_COMPACT_OUTLINE_DONE)
2285*fae548d3Szrj addend = 0;
2286*fae548d3Szrj else
2287*fae548d3Szrj abort ();
2288*fae548d3Szrj cfi_emit_eh_header (fde->eh_loc, addend);
2289*fae548d3Szrj }
2290*fae548d3Szrj }
2291*fae548d3Szrj #endif
2292*fae548d3Szrj
2293*fae548d3Szrj void
cfi_finish(void)2294*fae548d3Szrj cfi_finish (void)
2295*fae548d3Szrj {
2296*fae548d3Szrj struct cie_entry *cie, *cie_next;
2297*fae548d3Szrj segT cfi_seg, ccseg;
2298*fae548d3Szrj struct fde_entry *fde;
2299*fae548d3Szrj struct cfi_insn_data *first;
2300*fae548d3Szrj int save_flag_traditional_format, seek_next_seg;
2301*fae548d3Szrj
2302*fae548d3Szrj if (all_fde_data == 0)
2303*fae548d3Szrj return;
2304*fae548d3Szrj
2305*fae548d3Szrj cfi_sections_set = TRUE;
2306*fae548d3Szrj if ((all_cfi_sections & CFI_EMIT_eh_frame) != 0
2307*fae548d3Szrj || (all_cfi_sections & CFI_EMIT_eh_frame_compact) != 0)
2308*fae548d3Szrj {
2309*fae548d3Szrj /* Make sure check_eh_frame doesn't do anything with our output. */
2310*fae548d3Szrj save_flag_traditional_format = flag_traditional_format;
2311*fae548d3Szrj flag_traditional_format = 1;
2312*fae548d3Szrj
2313*fae548d3Szrj if (!EH_FRAME_LINKONCE)
2314*fae548d3Szrj {
2315*fae548d3Szrj /* Open .eh_frame section. */
2316*fae548d3Szrj cfi_seg = get_cfi_seg (NULL, ".eh_frame",
2317*fae548d3Szrj (SEC_ALLOC | SEC_LOAD | SEC_DATA
2318*fae548d3Szrj | DWARF2_EH_FRAME_READ_ONLY),
2319*fae548d3Szrj EH_FRAME_ALIGNMENT);
2320*fae548d3Szrj #ifdef md_fix_up_eh_frame
2321*fae548d3Szrj md_fix_up_eh_frame (cfi_seg);
2322*fae548d3Szrj #else
2323*fae548d3Szrj (void) cfi_seg;
2324*fae548d3Szrj #endif
2325*fae548d3Szrj }
2326*fae548d3Szrj
2327*fae548d3Szrj do
2328*fae548d3Szrj {
2329*fae548d3Szrj ccseg = NULL;
2330*fae548d3Szrj seek_next_seg = 0;
2331*fae548d3Szrj
2332*fae548d3Szrj for (cie = cie_root; cie; cie = cie_next)
2333*fae548d3Szrj {
2334*fae548d3Szrj cie_next = cie->next;
2335*fae548d3Szrj free ((void *) cie);
2336*fae548d3Szrj }
2337*fae548d3Szrj cie_root = NULL;
2338*fae548d3Szrj
2339*fae548d3Szrj for (fde = all_fde_data; fde ; fde = fde->next)
2340*fae548d3Szrj {
2341*fae548d3Szrj if ((fde->sections & CFI_EMIT_eh_frame) == 0
2342*fae548d3Szrj && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2343*fae548d3Szrj continue;
2344*fae548d3Szrj
2345*fae548d3Szrj #if SUPPORT_COMPACT_EH
2346*fae548d3Szrj /* Emit a LEGACY format header if we have processed all
2347*fae548d3Szrj of the .cfi directives without encountering either inline or
2348*fae548d3Szrj out-of-line compact unwinding opcodes. */
2349*fae548d3Szrj if (fde->eh_header_type == EH_COMPACT_HAS_LSDA
2350*fae548d3Szrj || fde->eh_header_type == EH_COMPACT_UNKNOWN)
2351*fae548d3Szrj fde->eh_header_type = EH_COMPACT_LEGACY;
2352*fae548d3Szrj
2353*fae548d3Szrj if (fde->eh_header_type != EH_COMPACT_LEGACY)
2354*fae548d3Szrj continue;
2355*fae548d3Szrj #endif
2356*fae548d3Szrj if (EH_FRAME_LINKONCE)
2357*fae548d3Szrj {
2358*fae548d3Szrj if (HANDLED (fde))
2359*fae548d3Szrj continue;
2360*fae548d3Szrj if (seek_next_seg && CUR_SEG (fde) != ccseg)
2361*fae548d3Szrj {
2362*fae548d3Szrj seek_next_seg = 2;
2363*fae548d3Szrj continue;
2364*fae548d3Szrj }
2365*fae548d3Szrj if (!seek_next_seg)
2366*fae548d3Szrj {
2367*fae548d3Szrj ccseg = CUR_SEG (fde);
2368*fae548d3Szrj /* Open .eh_frame section. */
2369*fae548d3Szrj cfi_seg = get_cfi_seg (ccseg, ".eh_frame",
2370*fae548d3Szrj (SEC_ALLOC | SEC_LOAD | SEC_DATA
2371*fae548d3Szrj | DWARF2_EH_FRAME_READ_ONLY),
2372*fae548d3Szrj EH_FRAME_ALIGNMENT);
2373*fae548d3Szrj #ifdef md_fix_up_eh_frame
2374*fae548d3Szrj md_fix_up_eh_frame (cfi_seg);
2375*fae548d3Szrj #else
2376*fae548d3Szrj (void) cfi_seg;
2377*fae548d3Szrj #endif
2378*fae548d3Szrj seek_next_seg = 1;
2379*fae548d3Szrj }
2380*fae548d3Szrj SET_HANDLED (fde, 1);
2381*fae548d3Szrj }
2382*fae548d3Szrj
2383*fae548d3Szrj if (fde->end_address == NULL)
2384*fae548d3Szrj {
2385*fae548d3Szrj as_bad (_("open CFI at the end of file; "
2386*fae548d3Szrj "missing .cfi_endproc directive"));
2387*fae548d3Szrj fde->end_address = fde->start_address;
2388*fae548d3Szrj }
2389*fae548d3Szrj
2390*fae548d3Szrj cie = select_cie_for_fde (fde, TRUE, &first, 2);
2391*fae548d3Szrj fde->eh_loc = symbol_temp_new_now ();
2392*fae548d3Szrj output_fde (fde, cie, TRUE, first,
2393*fae548d3Szrj fde->next == NULL ? EH_FRAME_ALIGNMENT : 2);
2394*fae548d3Szrj }
2395*fae548d3Szrj }
2396*fae548d3Szrj while (EH_FRAME_LINKONCE && seek_next_seg == 2);
2397*fae548d3Szrj
2398*fae548d3Szrj if (EH_FRAME_LINKONCE)
2399*fae548d3Szrj for (fde = all_fde_data; fde ; fde = fde->next)
2400*fae548d3Szrj SET_HANDLED (fde, 0);
2401*fae548d3Szrj
2402*fae548d3Szrj #if SUPPORT_COMPACT_EH
2403*fae548d3Szrj if (compact_eh)
2404*fae548d3Szrj {
2405*fae548d3Szrj /* Create remaining out of line table entries. */
2406*fae548d3Szrj do
2407*fae548d3Szrj {
2408*fae548d3Szrj ccseg = NULL;
2409*fae548d3Szrj seek_next_seg = 0;
2410*fae548d3Szrj
2411*fae548d3Szrj for (fde = all_fde_data; fde ; fde = fde->next)
2412*fae548d3Szrj {
2413*fae548d3Szrj if ((fde->sections & CFI_EMIT_eh_frame) == 0
2414*fae548d3Szrj && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2415*fae548d3Szrj continue;
2416*fae548d3Szrj
2417*fae548d3Szrj if (fde->eh_header_type != EH_COMPACT_OUTLINE)
2418*fae548d3Szrj continue;
2419*fae548d3Szrj if (HANDLED (fde))
2420*fae548d3Szrj continue;
2421*fae548d3Szrj if (seek_next_seg && CUR_SEG (fde) != ccseg)
2422*fae548d3Szrj {
2423*fae548d3Szrj seek_next_seg = 2;
2424*fae548d3Szrj continue;
2425*fae548d3Szrj }
2426*fae548d3Szrj if (!seek_next_seg)
2427*fae548d3Szrj {
2428*fae548d3Szrj ccseg = CUR_SEG (fde);
2429*fae548d3Szrj /* Open .gnu_extab section. */
2430*fae548d3Szrj get_cfi_seg (ccseg, ".gnu_extab",
2431*fae548d3Szrj (SEC_ALLOC | SEC_LOAD | SEC_DATA
2432*fae548d3Szrj | DWARF2_EH_FRAME_READ_ONLY),
2433*fae548d3Szrj 1);
2434*fae548d3Szrj seek_next_seg = 1;
2435*fae548d3Szrj }
2436*fae548d3Szrj SET_HANDLED (fde, 1);
2437*fae548d3Szrj
2438*fae548d3Szrj frag_align (1, 0, 0);
2439*fae548d3Szrj record_alignment (now_seg, 1);
2440*fae548d3Szrj output_compact_unwind_data (fde, 1);
2441*fae548d3Szrj }
2442*fae548d3Szrj }
2443*fae548d3Szrj while (EH_FRAME_LINKONCE && seek_next_seg == 2);
2444*fae548d3Szrj
2445*fae548d3Szrj for (fde = all_fde_data; fde ; fde = fde->next)
2446*fae548d3Szrj SET_HANDLED (fde, 0);
2447*fae548d3Szrj
2448*fae548d3Szrj /* Create index table fragments. */
2449*fae548d3Szrj do
2450*fae548d3Szrj {
2451*fae548d3Szrj ccseg = NULL;
2452*fae548d3Szrj seek_next_seg = 0;
2453*fae548d3Szrj
2454*fae548d3Szrj for (fde = all_fde_data; fde ; fde = fde->next)
2455*fae548d3Szrj {
2456*fae548d3Szrj if ((fde->sections & CFI_EMIT_eh_frame) == 0
2457*fae548d3Szrj && (fde->sections & CFI_EMIT_eh_frame_compact) == 0)
2458*fae548d3Szrj continue;
2459*fae548d3Szrj
2460*fae548d3Szrj if (HANDLED (fde))
2461*fae548d3Szrj continue;
2462*fae548d3Szrj if (seek_next_seg && CUR_SEG (fde) != ccseg)
2463*fae548d3Szrj {
2464*fae548d3Szrj seek_next_seg = 2;
2465*fae548d3Szrj continue;
2466*fae548d3Szrj }
2467*fae548d3Szrj if (!seek_next_seg)
2468*fae548d3Szrj {
2469*fae548d3Szrj ccseg = CUR_SEG (fde);
2470*fae548d3Szrj /* Open .eh_frame_entry section. */
2471*fae548d3Szrj cfi_seg = get_cfi_seg (ccseg, ".eh_frame_entry",
2472*fae548d3Szrj (SEC_ALLOC | SEC_LOAD | SEC_DATA
2473*fae548d3Szrj | DWARF2_EH_FRAME_READ_ONLY),
2474*fae548d3Szrj 2);
2475*fae548d3Szrj seek_next_seg = 1;
2476*fae548d3Szrj }
2477*fae548d3Szrj SET_HANDLED (fde, 1);
2478*fae548d3Szrj
2479*fae548d3Szrj output_eh_header (fde);
2480*fae548d3Szrj }
2481*fae548d3Szrj }
2482*fae548d3Szrj while (seek_next_seg == 2);
2483*fae548d3Szrj
2484*fae548d3Szrj for (fde = all_fde_data; fde ; fde = fde->next)
2485*fae548d3Szrj SET_HANDLED (fde, 0);
2486*fae548d3Szrj }
2487*fae548d3Szrj #endif /* SUPPORT_COMPACT_EH */
2488*fae548d3Szrj
2489*fae548d3Szrj flag_traditional_format = save_flag_traditional_format;
2490*fae548d3Szrj }
2491*fae548d3Szrj
2492*fae548d3Szrj cfi_sections_set = TRUE;
2493*fae548d3Szrj if ((all_cfi_sections & CFI_EMIT_debug_frame) != 0)
2494*fae548d3Szrj {
2495*fae548d3Szrj int alignment = ffs (DWARF2_ADDR_SIZE (stdoutput)) - 1;
2496*fae548d3Szrj
2497*fae548d3Szrj if (!SUPPORT_FRAME_LINKONCE)
2498*fae548d3Szrj get_cfi_seg (NULL, ".debug_frame",
2499*fae548d3Szrj SEC_READONLY | SEC_DEBUGGING,
2500*fae548d3Szrj alignment);
2501*fae548d3Szrj
2502*fae548d3Szrj do
2503*fae548d3Szrj {
2504*fae548d3Szrj ccseg = NULL;
2505*fae548d3Szrj seek_next_seg = 0;
2506*fae548d3Szrj
2507*fae548d3Szrj for (cie = cie_root; cie; cie = cie_next)
2508*fae548d3Szrj {
2509*fae548d3Szrj cie_next = cie->next;
2510*fae548d3Szrj free ((void *) cie);
2511*fae548d3Szrj }
2512*fae548d3Szrj cie_root = NULL;
2513*fae548d3Szrj
2514*fae548d3Szrj for (fde = all_fde_data; fde ; fde = fde->next)
2515*fae548d3Szrj {
2516*fae548d3Szrj if ((fde->sections & CFI_EMIT_debug_frame) == 0)
2517*fae548d3Szrj continue;
2518*fae548d3Szrj
2519*fae548d3Szrj if (SUPPORT_FRAME_LINKONCE)
2520*fae548d3Szrj {
2521*fae548d3Szrj if (HANDLED (fde))
2522*fae548d3Szrj continue;
2523*fae548d3Szrj if (seek_next_seg && CUR_SEG (fde) != ccseg)
2524*fae548d3Szrj {
2525*fae548d3Szrj seek_next_seg = 2;
2526*fae548d3Szrj continue;
2527*fae548d3Szrj }
2528*fae548d3Szrj if (!seek_next_seg)
2529*fae548d3Szrj {
2530*fae548d3Szrj ccseg = CUR_SEG (fde);
2531*fae548d3Szrj /* Open .debug_frame section. */
2532*fae548d3Szrj get_cfi_seg (ccseg, ".debug_frame",
2533*fae548d3Szrj SEC_READONLY | SEC_DEBUGGING,
2534*fae548d3Szrj alignment);
2535*fae548d3Szrj seek_next_seg = 1;
2536*fae548d3Szrj }
2537*fae548d3Szrj SET_HANDLED (fde, 1);
2538*fae548d3Szrj }
2539*fae548d3Szrj if (fde->end_address == NULL)
2540*fae548d3Szrj {
2541*fae548d3Szrj as_bad (_("open CFI at the end of file; "
2542*fae548d3Szrj "missing .cfi_endproc directive"));
2543*fae548d3Szrj fde->end_address = fde->start_address;
2544*fae548d3Szrj }
2545*fae548d3Szrj
2546*fae548d3Szrj fde->per_encoding = DW_EH_PE_omit;
2547*fae548d3Szrj fde->lsda_encoding = DW_EH_PE_omit;
2548*fae548d3Szrj cfi_change_reg_numbers (fde->data, ccseg);
2549*fae548d3Szrj cie = select_cie_for_fde (fde, FALSE, &first, alignment);
2550*fae548d3Szrj output_fde (fde, cie, FALSE, first, alignment);
2551*fae548d3Szrj }
2552*fae548d3Szrj }
2553*fae548d3Szrj while (SUPPORT_FRAME_LINKONCE && seek_next_seg == 2);
2554*fae548d3Szrj
2555*fae548d3Szrj if (SUPPORT_FRAME_LINKONCE)
2556*fae548d3Szrj for (fde = all_fde_data; fde ; fde = fde->next)
2557*fae548d3Szrj SET_HANDLED (fde, 0);
2558*fae548d3Szrj }
2559*fae548d3Szrj }
2560*fae548d3Szrj
2561*fae548d3Szrj #else /* TARGET_USE_CFIPOP */
2562*fae548d3Szrj
2563*fae548d3Szrj /* Emit an intelligible error message for missing support. */
2564*fae548d3Szrj
2565*fae548d3Szrj static void
dot_cfi_dummy(int ignored ATTRIBUTE_UNUSED)2566*fae548d3Szrj dot_cfi_dummy (int ignored ATTRIBUTE_UNUSED)
2567*fae548d3Szrj {
2568*fae548d3Szrj as_bad (_("CFI is not supported for this target"));
2569*fae548d3Szrj ignore_rest_of_line ();
2570*fae548d3Szrj }
2571*fae548d3Szrj
2572*fae548d3Szrj const pseudo_typeS cfi_pseudo_table[] =
2573*fae548d3Szrj {
2574*fae548d3Szrj { "cfi_sections", dot_cfi_dummy, 0 },
2575*fae548d3Szrj { "cfi_startproc", dot_cfi_dummy, 0 },
2576*fae548d3Szrj { "cfi_endproc", dot_cfi_dummy, 0 },
2577*fae548d3Szrj { "cfi_fde_data", dot_cfi_dummy, 0 },
2578*fae548d3Szrj { "cfi_def_cfa", dot_cfi_dummy, 0 },
2579*fae548d3Szrj { "cfi_def_cfa_register", dot_cfi_dummy, 0 },
2580*fae548d3Szrj { "cfi_def_cfa_offset", dot_cfi_dummy, 0 },
2581*fae548d3Szrj { "cfi_adjust_cfa_offset", dot_cfi_dummy, 0 },
2582*fae548d3Szrj { "cfi_offset", dot_cfi_dummy, 0 },
2583*fae548d3Szrj { "cfi_rel_offset", dot_cfi_dummy, 0 },
2584*fae548d3Szrj { "cfi_register", dot_cfi_dummy, 0 },
2585*fae548d3Szrj { "cfi_return_column", dot_cfi_dummy, 0 },
2586*fae548d3Szrj { "cfi_restore", dot_cfi_dummy, 0 },
2587*fae548d3Szrj { "cfi_undefined", dot_cfi_dummy, 0 },
2588*fae548d3Szrj { "cfi_same_value", dot_cfi_dummy, 0 },
2589*fae548d3Szrj { "cfi_remember_state", dot_cfi_dummy, 0 },
2590*fae548d3Szrj { "cfi_restore_state", dot_cfi_dummy, 0 },
2591*fae548d3Szrj { "cfi_window_save", dot_cfi_dummy, 0 },
2592*fae548d3Szrj { "cfi_escape", dot_cfi_dummy, 0 },
2593*fae548d3Szrj { "cfi_signal_frame", dot_cfi_dummy, 0 },
2594*fae548d3Szrj { "cfi_personality", dot_cfi_dummy, 0 },
2595*fae548d3Szrj { "cfi_personality_id", dot_cfi_dummy, 0 },
2596*fae548d3Szrj { "cfi_lsda", dot_cfi_dummy, 0 },
2597*fae548d3Szrj { "cfi_val_encoded_addr", dot_cfi_dummy, 0 },
2598*fae548d3Szrj { "cfi_label", dot_cfi_dummy, 0 },
2599*fae548d3Szrj { "cfi_inline_lsda", dot_cfi_dummy, 0 },
2600*fae548d3Szrj { "cfi_val_offset", dot_cfi_dummy, 0 },
2601*fae548d3Szrj { NULL, NULL, 0 }
2602*fae548d3Szrj };
2603*fae548d3Szrj
2604*fae548d3Szrj void
cfi_finish(void)2605*fae548d3Szrj cfi_finish (void)
2606*fae548d3Szrj {
2607*fae548d3Szrj }
2608*fae548d3Szrj #endif /* TARGET_USE_CFIPOP */
2609