diff mbox series

Fix PR87927, implement TARGET_ASM_{,UN}ALIGNED_P{S,D,T}I_OP

Message ID cb6e9f7d-7280-5089-5800-57fa3801d377@mittosystems.com
State New
Headers show
Series Fix PR87927, implement TARGET_ASM_{,UN}ALIGNED_P{S,D,T}I_OP | expand

Commit Message

Jozef Lawrynowicz Nov. 14, 2018, 11:05 a.m. UTC
Use of the patchable_function_entry attribute when the pointer mode is a
partial int mode can cause a segfault.
The handler for this attribute tries to write out the assembler directive
for an integer with bytesize POINTER_SIZE_UNITS, so if this is not 2, 4, 8 or
16 NULL is returned, resulting in a segfault.

This was observed on msp430-elf with the large memory model, where POINTER_SIZE
is 20, and so POINTER_SIZE_UNITS is 3.

Fixed by implementing TARGET_ASM_{,UN}ALIGNED_PSI_OP, and extending "struct
asm_int_op".

For completeness I added the hooks for PDImode (used by bfin) and PTImode (used
by rs6000). However, these aren't tied to any real types as they are used
for register modes, so I can't see this patch having any effect for these
targets. Since there's no way to represent these modes in memory, the compiler
will never need to write out an assembler directive for them.

Successfully bootstrapped and regtested current trunk for x86_64-pc-linux-gnu
and regtested msp430-elf with -mlarge.

Ok for trunk?

Comments

Jeff Law Nov. 16, 2018, 4:22 p.m. UTC | #1
On 11/14/18 4:05 AM, Jozef Lawrynowicz wrote:
> Use of the patchable_function_entry attribute when the pointer mode is a
> partial int mode can cause a segfault.
> The handler for this attribute tries to write out the assembler directive
> for an integer with bytesize POINTER_SIZE_UNITS, so if this is not 2, 4, 8 or
> 
> 16 NULL is returned, resulting in a segfault.
> 
> This was observed on msp430-elf with the large memory model, where POINTER_SIZE
> 
> is 20, and so POINTER_SIZE_UNITS is 3.
> 
> Fixed by implementing TARGET_ASM_{,UN}ALIGNED_PSI_OP, and extending "struct
> asm_int_op".
> 
> For completeness I added the hooks for PDImode (used by bfin) and PTImode (used
> 
> by rs6000). However, these aren't tied to any real types as they are used
> for register modes, so I can't see this patch having any effect for these
> targets. Since there's no way to represent these modes in memory, the compiler
> 
> will never need to write out an assembler directive for them.
> 
> Successfully bootstrapped and regtested current trunk for x86_64-pc-linux-gnu
> 
> and regtested msp430-elf with -mlarge.
> 
> Ok for trunk?
> 
> 
> 0001-Implement-TARGET_ASM_-UN-ALIGNED_P-S-D-T-I_OP.patch
> 
> From ffff48890bd01668f68bafbd94556c9754bf2406 Mon Sep 17 00:00:00 2001
> From: Jozef Lawrynowicz <jozef.l@mittosystems.com>
> Date: Thu, 8 Nov 2018 13:42:27 +0000
> Subject: [PATCH] Implement TARGET_ASM_{,UN}ALIGNED_P{S,D,T}I_OP
> 
> 2018-11-14  Jozef Lawrynowicz  <jozef.l@mittosystems.com>
> 
> 	PR target/87927
> 
> 	gcc/ChangeLog:
> 
> 	* target-def.h: Initialize TARGET_ASM_{,UN}ALIGNED_P{S,D,T}I_OP.
> 	Add them to the TARGET_ASM_{,UN}ALIGNED_INT_OP structs.
> 	* target.def: Enumerate TARGET_ASM_{,UN}ALIGNED_P{S,D,T}I_OP in
> 	the byte_op hook.
> 	* target.h: Add psi, pdi, pti to struct asm_int_op definition.
> 	* targhooks.c (default_print_patchable_function_entry): Assert
> 	asm_int_op does not return a NULL string.
> 	* varasm.c (integer_asm_op): Return the op for a partial int type
> 	when the requested size does not correspond to an integer type.
> 	* config/msp430/msp430.c: Initialize TARGET_ASM_{,UN}ALIGNED_PSI_OP.
OK
jeff
diff mbox series

Patch

From ffff48890bd01668f68bafbd94556c9754bf2406 Mon Sep 17 00:00:00 2001
From: Jozef Lawrynowicz <jozef.l@mittosystems.com>
Date: Thu, 8 Nov 2018 13:42:27 +0000
Subject: [PATCH] Implement TARGET_ASM_{,UN}ALIGNED_P{S,D,T}I_OP

2018-11-14  Jozef Lawrynowicz  <jozef.l@mittosystems.com>

	PR target/87927

	gcc/ChangeLog:

	* target-def.h: Initialize TARGET_ASM_{,UN}ALIGNED_P{S,D,T}I_OP.
	Add them to the TARGET_ASM_{,UN}ALIGNED_INT_OP structs.
	* target.def: Enumerate TARGET_ASM_{,UN}ALIGNED_P{S,D,T}I_OP in
	the byte_op hook.
	* target.h: Add psi, pdi, pti to struct asm_int_op definition.
	* targhooks.c (default_print_patchable_function_entry): Assert
	asm_int_op does not return a NULL string.
	* varasm.c (integer_asm_op): Return the op for a partial int type
	when the requested size does not correspond to an integer type.
	* config/msp430/msp430.c: Initialize TARGET_ASM_{,UN}ALIGNED_PSI_OP.

---
 gcc/config/msp430/msp430.c |  5 +++++
 gcc/target-def.h           | 15 +++++++++++++++
 gcc/target.def             |  6 ++++++
 gcc/target.h               |  3 +++
 gcc/targhooks.c            |  4 +++-
 gcc/varasm.c               | 14 ++++++++++++++
 6 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c
index 7d305b1bece..3a41cc011e7 100644
--- a/gcc/config/msp430/msp430.c
+++ b/gcc/config/msp430/msp430.c
@@ -3469,6 +3469,11 @@  msp430_print_operand_raw (FILE * file, rtx op)
     }
 }
 
+#undef  TARGET_ASM_ALIGNED_PSI_OP
+#define TARGET_ASM_ALIGNED_PSI_OP "\t.long\t"
+#undef  TARGET_ASM_UNALIGNED_PSI_OP
+#define TARGET_ASM_UNALIGNED_PSI_OP TARGET_ASM_ALIGNED_PSI_OP
+
 #undef  TARGET_PRINT_OPERAND_ADDRESS
 #define TARGET_PRINT_OPERAND_ADDRESS	msp430_print_operand_addr
 
diff --git a/gcc/target-def.h b/gcc/target-def.h
index 695198b9555..44c085fec40 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -47,6 +47,15 @@ 
 #define TARGET_ASM_UNALIGNED_TI_OP NULL
 #endif /* OBJECT_FORMAT_ELF */
 
+/* There is no standard way to handle P{S,D,T}Imode, targets must implement them
+   if required.  */
+#define TARGET_ASM_ALIGNED_PSI_OP NULL
+#define TARGET_ASM_UNALIGNED_PSI_OP NULL
+#define TARGET_ASM_ALIGNED_PDI_OP NULL
+#define TARGET_ASM_UNALIGNED_PDI_OP NULL
+#define TARGET_ASM_ALIGNED_PTI_OP NULL
+#define TARGET_ASM_UNALIGNED_PTI_OP NULL
+
 #if !defined(TARGET_ASM_CONSTRUCTOR) && !defined(USE_COLLECT2)
 # ifdef CTORS_SECTION_ASM_OP
 #  define TARGET_ASM_CONSTRUCTOR default_ctor_section_asm_out_constructor
@@ -89,14 +98,20 @@ 
 
 #define TARGET_ASM_ALIGNED_INT_OP				\
 		       {TARGET_ASM_ALIGNED_HI_OP,		\
+			TARGET_ASM_ALIGNED_PSI_OP,		\
 			TARGET_ASM_ALIGNED_SI_OP,		\
+			TARGET_ASM_ALIGNED_PDI_OP,		\
 			TARGET_ASM_ALIGNED_DI_OP,		\
+			TARGET_ASM_ALIGNED_PTI_OP,		\
 			TARGET_ASM_ALIGNED_TI_OP}
 
 #define TARGET_ASM_UNALIGNED_INT_OP				\
 		       {TARGET_ASM_UNALIGNED_HI_OP,		\
+			TARGET_ASM_UNALIGNED_PSI_OP,		\
 			TARGET_ASM_UNALIGNED_SI_OP,		\
+			TARGET_ASM_UNALIGNED_PDI_OP,		\
 			TARGET_ASM_UNALIGNED_DI_OP,		\
+			TARGET_ASM_UNALIGNED_PTI_OP,		\
 			TARGET_ASM_UNALIGNED_TI_OP}
 
 #if !defined (TARGET_FUNCTION_INCOMING_ARG)
diff --git a/gcc/target.def b/gcc/target.def
index ad27d352ca4..77b8a5fe638 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -45,12 +45,18 @@  DEFHOOKPODX (close_paren, const char *, ")")
 DEFHOOKPOD
 (byte_op,
  "@deftypevrx {Target Hook} {const char *} TARGET_ASM_ALIGNED_HI_OP\n\
+@deftypevrx {Target Hook} {const char *} TARGET_ASM_ALIGNED_PSI_OP\n\
 @deftypevrx {Target Hook} {const char *} TARGET_ASM_ALIGNED_SI_OP\n\
+@deftypevrx {Target Hook} {const char *} TARGET_ASM_ALIGNED_PDI_OP\n\
 @deftypevrx {Target Hook} {const char *} TARGET_ASM_ALIGNED_DI_OP\n\
+@deftypevrx {Target Hook} {const char *} TARGET_ASM_ALIGNED_PTI_OP\n\
 @deftypevrx {Target Hook} {const char *} TARGET_ASM_ALIGNED_TI_OP\n\
 @deftypevrx {Target Hook} {const char *} TARGET_ASM_UNALIGNED_HI_OP\n\
+@deftypevrx {Target Hook} {const char *} TARGET_ASM_UNALIGNED_PSI_OP\n\
 @deftypevrx {Target Hook} {const char *} TARGET_ASM_UNALIGNED_SI_OP\n\
+@deftypevrx {Target Hook} {const char *} TARGET_ASM_UNALIGNED_PDI_OP\n\
 @deftypevrx {Target Hook} {const char *} TARGET_ASM_UNALIGNED_DI_OP\n\
+@deftypevrx {Target Hook} {const char *} TARGET_ASM_UNALIGNED_PTI_OP\n\
 @deftypevrx {Target Hook} {const char *} TARGET_ASM_UNALIGNED_TI_OP\n\
 These hooks specify assembly directives for creating certain kinds\n\
 of integer object.  The @code{TARGET_ASM_BYTE_OP} directive creates a\n\
diff --git a/gcc/target.h b/gcc/target.h
index 8968580e432..663926b0896 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -158,8 +158,11 @@  extern bool stmt_in_inner_loop_p (struct _stmt_vec_info *);
 struct asm_int_op
 {
   const char *hi;
+  const char *psi;
   const char *si;
+  const char *pdi;
   const char *di;
+  const char *pti;
   const char *ti;
 };
 
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 3d8b3b9d69b..b2c2d835294 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -1807,13 +1807,15 @@  default_print_patchable_function_entry (FILE *file,
       char buf[256];
       static int patch_area_number;
       section *previous_section = in_section;
+      const char *asm_op = integer_asm_op (POINTER_SIZE_UNITS, false);
 
+      gcc_assert (asm_op != NULL);
       patch_area_number++;
       ASM_GENERATE_INTERNAL_LABEL (buf, "LPFE", patch_area_number);
 
       switch_to_section (get_section ("__patchable_function_entries",
 				      0, NULL));
-      fputs (integer_asm_op (POINTER_SIZE_UNITS, false), file);
+      fputs (asm_op, file);
       assemble_name_raw (file, buf);
       fputc ('\n', file);
 
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 545e13fef6a..243d205c1f5 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -2733,10 +2733,24 @@  integer_asm_op (int size, int aligned_p)
       return targetm.asm_out.byte_op;
     case 2:
       return ops->hi;
+    case 3:
+      return ops->psi;
     case 4:
       return ops->si;
+    case 5:
+    case 6:
+    case 7:
+      return ops->pdi;
     case 8:
       return ops->di;
+    case 9:
+    case 10:
+    case 11:
+    case 12:
+    case 13:
+    case 14:
+    case 15:
+      return ops->pti;
     case 16:
       return ops->ti;
     default:
-- 
2.17.1