This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH, CFI] Fix EH for coldfire-uclinux
- From: Maxim Kuvyrkov <maxim at codesourcery dot com>
- To: binutils <binutils at sourceware dot org>
- Cc: Daniel Jacobowitz <dan at codesourcery dot com>, Jason Merrill <jason at redhat dot com>
- Date: Wed, 04 Nov 2009 00:35:50 +0300
- Subject: [PATCH, CFI] Fix EH for coldfire-uclinux
Hi,
The following patch fixes a problem in EH on coldfire-uclinux. Due to
peculiarities of ColdFire uClinux it is not possible to use PC-relative
encoding for CFI. This problem was uncovered by recent switch of GCC to
emit .cfi* directives by default.
To generate bFLT binaries for coldfire-uclinux elf2flt utility is used.
Elf2flt does not honor PT_LOAD's from the executable. So, despite
appearances of the ELF file, .text and .eh_frame sections will not end
up in the same segment in bFLT file. Therefore PC-relative encoding
cannot be used for CFI on coldfire-uclinux. Hence this patch defines
CFI_DIFF_EXPR_OK to 0 for coldfire-uclinux.
However, there is one exception to the above -- encoding of LSDA. LSDA
encoding is explicitly specified by the compiler and can be relied on.
So the patch also adds CFI_DIFF_LSDA_OK macro to convince GAS to accept
PC-relative encoding in this one case.
Tested on coldfire-uclinux and various other architectures where this
patch is a no-op.
OK to check in?
Thanks,
--
Maxim Kuvyrkov
CodeSourcery
maxim@codesourcery.com
(650) 331-3385 x724
2009-11-01 Daniel Jacobowitz <dan@codesourcery.com>
Maxim Kuvyrkov <maxim@codesourcery.com>
* config/tc-m68k.h (CF_DIFF_EXPR_OK): Define to 0 for uClinux.
(CFI_DIFF_LSDA_OK): Define.
* config/te-uclinux.h: New file.
* configure.tgt (m68k-uclinux): Define em.
* dw2gencfi.c (CFI_DIFF_LSDA_OK): New macro.
(dot_cfi_lsda, output_fde): Use instead of CFI_DIFF_EXPR_OK.
Index: gas/config/tc-m68k.h
===================================================================
--- gas/config/tc-m68k.h (revision 267216)
+++ gas/config/tc-m68k.h (working copy)
@@ -178,3 +178,13 @@ extern int tc_m68k_regname_to_dw2regnum
#define tc_cfi_frame_initial_instructions tc_m68k_frame_initial_instructions
extern void tc_m68k_frame_initial_instructions (void);
+
+#ifdef TE_UCLINUX
+/* elf2flt does not honor PT_LOAD's from the executable.
+ .text and .eh_frame sections will not end up in the same segment and so
+ we cannot use PC-relative encoding for CFI. */
+# define CFI_DIFF_EXPR_OK 0
+
+/* However, follow compiler's guidance when it specifies encoding for LSDA. */
+# define CFI_DIFF_LSDA_OK 1
+#endif
Index: gas/config/te-uclinux.h
===================================================================
--- gas/config/te-uclinux.h (revision 0)
+++ gas/config/te-uclinux.h (revision 0)
@@ -0,0 +1,22 @@
+/* Copyright 2009 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 3,
+ or (at your option) any later version.
+
+ GAS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GAS; see the file COPYING. If not, write to the Free
+ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#define TE_UCLINUX
+
+#include "te-generic.h"
Index: gas/dw2gencfi.c
===================================================================
--- gas/dw2gencfi.c (revision 267216)
+++ gas/dw2gencfi.c (working copy)
@@ -36,6 +36,14 @@
# endif
#endif
+#ifndef CFI_DIFF_LSDA_OK
+# define CFI_DIFF_LSDA_OK CFI_DIFF_EXPR_OK
+#endif
+
+#if CFI_DIFF_EXPR_OK == 1 && CFI_DIFF_LSDA_OK == 0
+# error "CFI_DIFF_EXPR_OK should imply CFI_DIFF_LSDA_OK"
+#endif
+
/* We re-use DWARF2_LINE_MIN_INSN_LENGTH for the code alignment field
of the CIE. Default to 1 if not otherwise specified. */
#ifndef DWARF2_LINE_MIN_INSN_LENGTH
@@ -758,7 +766,7 @@ dot_cfi_lsda (int ignored ATTRIBUTE_UNUS
if ((encoding & 0xff) != encoding
|| ((encoding & 0x70) != 0
-#if CFI_DIFF_EXPR_OK || defined tc_cfi_emit_pcrel_expr
+#if CFI_DIFF_LSDA_OK || defined tc_cfi_emit_pcrel_expr
&& (encoding & 0x70) != DW_EH_PE_pcrel
#endif
)
@@ -1445,7 +1453,7 @@ output_fde (struct fde_entry *fde, struc
exp = fde->lsda;
if ((fde->lsda_encoding & 0x70) == DW_EH_PE_pcrel)
{
-#if CFI_DIFF_EXPR_OK
+#if CFI_DIFF_LSDA_OK
exp.X_op = O_subtract;
exp.X_op_symbol = symbol_temp_new_now ();
emit_expr (&exp, augmentation_size);
Index: gas/configure.tgt
===================================================================
--- gas/configure.tgt (revision 267216)
+++ gas/configure.tgt (working copy)
@@ -267,7 +267,7 @@ case ${generic_target} in
m68k-*-sysv4*) fmt=elf em=svr4 ;;
m68k-*-rtems*) fmt=elf ;;
m68k-*-linux-*) fmt=elf em=linux ;;
- m68k-*-uclinux*) fmt=elf ;;
+ m68k-*-uclinux*) fmt=elf em=uclinux ;;
m68k-*-gnu*) fmt=elf ;;
m68k-*-netbsdelf*) fmt=elf em=nbsd ;;
m68k-*-netbsd*) fmt=aout em=nbsd bfd_gas=yes ;;