public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/morello)] Fix up some cheri warnings in libgcc
@ 2022-03-14 10:35 Matthew Malcomson
  0 siblings, 0 replies; only message in thread
From: Matthew Malcomson @ 2022-03-14 10:35 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:9b82fa20f04768be50824a2e4ce8762a1a3db7ef

commit 9b82fa20f04768be50824a2e4ce8762a1a3db7ef
Author: Matthew Malcomson <matthew.malcomson@arm.com>
Date:   Mon Mar 7 18:04:39 2022 +0000

    Fix up some cheri warnings in libgcc
    
    In emutls.c we introduce a new type to represent an address, to ensure
    we have the same distinction between pointer and address here as
    everywhere else.  This allows us to remove a provenance warning on a
    binary operation between two capabilities.
    
    One point of note is that we use __attribute__((mode(address))) rather
    than ptraddr_t.  This is because ptraddr_t is not necessarily defined
    for all targets, while __attribute__((mode(address))) is.  We care about
    this more inside libgcc than in other software since this software is
    supposed to be as portable as GCC is.
    
    In the GCC C-language personality function we avoid some provenance warnings
    by using _Unwind_Address in some binary operations, and we cast an
    _Unwind_Ptr to a void * before passing it to
    __builtin_code_address_from_pointer.
    
    In unwind-dw2 and unwind-dw2-fde we just need to make the difference
    between an address and a pointer clear for the compiler.  We record
    addresses in many structures since they are smaller and we only need the
    address.  Our functions for reading in encoded values need to be able to
    return capabilities because we can have capabilities stored (indirectly)
    in the debug information.  Hence we now need to cast from the "read"
    value type to the "for use" value type.
    
    Avoid unaligned warnings in `read_encoded_value_with_base`.  We know
    the union we define is not aligned for capabilities, but we handle it
    manually ourselves (there is never a capability directly in the debug
    information, but there can be `void *`'s for other backends).
    
    Mark the __EH_FRAME_BEGIN__ symbol as being used in the inline assembly
    that the purecap implementation of get_eh_frame_begin is implemented
    with.  This avoids a warning, and avoids the possibility of the variable
    being optimised away.
    
    Add the EH_FRAME_SECTION_CONST macro (which expands to `const`
    or the empty string depending on configuration settings) to the
    declaration of `get_eh_frame_begin` so the function does not discard the
    `const` attribute.
    
    We adjust our `asm` directive so that it indicates we are
    using the __EH_FRAME_BEGIN__ symbol as this avoids an unused variable
    warning.

Diff:
---
 libgcc/crtstuff.c       | 12 ++++++------
 libgcc/emutls.c         |  3 ++-
 libgcc/unwind-c.c       |  4 ++--
 libgcc/unwind-dw2-fde.c |  9 +++++----
 libgcc/unwind-dw2.c     |  2 +-
 libgcc/unwind-dw2.h     |  9 ++++++---
 libgcc/unwind-pe.h      |  7 +++++++
 7 files changed, 29 insertions(+), 17 deletions(-)

diff --git a/libgcc/crtstuff.c b/libgcc/crtstuff.c
index 225af9db8a0..74470f1c923 100644
--- a/libgcc/crtstuff.c
+++ b/libgcc/crtstuff.c
@@ -263,7 +263,7 @@ STATIC func_ptr __DTOR_LIST__[1]
 STATIC EH_FRAME_SECTION_CONST char __EH_FRAME_BEGIN__[]
      __attribute__((section(__LIBGCC_EH_FRAME_SECTION_NAME__), aligned(4)))
      = { };
-# ifdef __CHERI_PURE_CAPABILITY__ && defined (__aarch64__)
+# if defined (__CHERI_PURE_CAPABILITY__) && defined (__aarch64__)
 /* MORELLO  __EH_FRAME_BEGIN__ marks the start of the .eh_frame section.
    The __register_frame_info* functions below pass this to the unwinder so that
    it knows where to access the dwarf unwinding information from.
@@ -273,19 +273,19 @@ STATIC EH_FRAME_SECTION_CONST char __EH_FRAME_BEGIN__[]
    N.b. this is pretty useful in development since PCC gives us executable
    permissions, which means we can use the landing-pad offset info rather than
    having to implement both at the same time.  */
-static inline void *
+static inline EH_FRAME_SECTION_CONST void *
 get_eh_frame_begin (void)
 {
   void *ret;
-  asm ("adrp  %0, __EH_FRAME_BEGIN__\n\t"
-       "add %0, %0, :lo12:__EH_FRAME_BEGIN__"
-       : "=r" (ret) : );
+  asm ("adrp  %0, %1\n\t"
+       "add %0, %0, :lo12:%1"
+       : "=r" (ret) : "S" (__EH_FRAME_BEGIN__));
   return ret;
 }
 # elif defined (__CHERI_PURE_CAPABILITY__)
 # error libgcc crtstuff not updated for non-Morello capability target.
 # else
-static inline void *
+static inline EH_FRAME_SECTION_CONST void *
 get_eh_frame_begin (void)
 {
   return __EH_FRAME_BEGIN__;
diff --git a/libgcc/emutls.c b/libgcc/emutls.c
index 5f23e626b94..9bc514cf3d7 100644
--- a/libgcc/emutls.c
+++ b/libgcc/emutls.c
@@ -32,6 +32,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 
 typedef unsigned int word __attribute__((mode(word)));
 typedef __UINTPTR_TYPE__ pointer;
+typedef unsigned address_t __attribute__((mode(address)));
 
 struct __emutls_object
 {
@@ -111,7 +112,7 @@ emutls_alloc (struct __emutls_object *obj)
       if (ptr == NULL)
 	abort ();
       ret = (void *) (((pointer) (ptr + sizeof (void *) + obj->align - 1))
-		      & ~(pointer)(obj->align - 1));
+		      & ~(address_t)(obj->align - 1));
       ((void **) ret)[-1] = ptr;
     }
 
diff --git a/libgcc/unwind-c.c b/libgcc/unwind-c.c
index 24a464fa670..be553ae970b 100644
--- a/libgcc/unwind-c.c
+++ b/libgcc/unwind-c.c
@@ -169,7 +169,7 @@ PERSONALITY_FUNCTION (int version,
 #ifdef __USING_SJLJ_EXCEPTIONS__
   ip = (_Unwind_Address) ip_ptr;
 #else
-  ip = __builtin_code_address_from_pointer (ip_ptr);
+  ip = __builtin_code_address_from_pointer ((void*)ip_ptr);
 #endif
 
   if (! ip_before_insn)
@@ -226,7 +226,7 @@ PERSONALITY_FUNCTION (int version,
       /* The table is sorted, so if we've passed the ip, stop.  */
       if (ip < info.Start + cs_start)
 	p = info.action_table;
-      else if (ip < info.Start + cs_start + cs_len)
+      else if (ip < info.Start + (_Unwind_Address)cs_start + (_Unwind_Address)cs_len)
 	{
 	  if (cs_lp)
 	    {
diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c
index 609507db638..26be05d4aca 100644
--- a/libgcc/unwind-dw2-fde.c
+++ b/libgcc/unwind-dw2-fde.c
@@ -668,6 +668,7 @@ classify_object_over_fdes (struct object *ob, const fde *this_fde)
 
       read_encoded_value_with_base (encoding, base, this_fde->pc_begin,
 				    &pc_begin);
+      _Unwind_Address pc_begin_addr = (_Unwind_Address)pc_begin;
 
       /* Take care to ignore link-once functions that were removed.
 	 In these cases, the function address will be NULL, but if
@@ -679,12 +680,12 @@ classify_object_over_fdes (struct object *ob, const fde *this_fde)
       else
 	mask = -1;
 
-      if ((pc_begin & mask) == 0)
+      if ((pc_begin_addr & mask) == 0)
 	continue;
 
       count += 1;
-      if (pc_begin < ob->pc_begin)
-	ob->pc_begin = pc_begin;
+      if (pc_begin_addr < (_Unwind_Address)ob->pc_begin)
+	ob->pc_begin = (void *) pc_begin;
     }
 
   return count;
@@ -911,7 +912,7 @@ binary_search_unencoded_fdes (struct object *ob, _Unwind_Address pc)
       memcpy (&pc_begin, (const void * const *) f->pc_begin, sizeof (void *));
       memcpy (&pc_range, (const uaddr *) f->pc_begin + 1, sizeof (uaddr));
 
-      if (pc < pc_begin)
+      if ((_Unwind_Address)pc < pc_begin)
 	hi = i;
       else if (pc >= pc_begin + pc_range)
 	lo = i + 1;
diff --git a/libgcc/unwind-dw2.c b/libgcc/unwind-dw2.c
index 2b964a0e495..096476e041c 100644
--- a/libgcc/unwind-dw2.c
+++ b/libgcc/unwind-dw2.c
@@ -1316,7 +1316,7 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
 #endif
     }
 
-  fs->pc = context->bases.func;
+  fs->pc = (_Unwind_Address)context->bases.func;
 
   cie = get_cie (fde);
   insn = extract_cie_info (cie, context, fs);
diff --git a/libgcc/unwind-dw2.h b/libgcc/unwind-dw2.h
index 1c4977d97e2..615fe590feb 100644
--- a/libgcc/unwind-dw2.h
+++ b/libgcc/unwind-dw2.h
@@ -64,9 +64,12 @@ typedef struct
   } regs;
 
   /* The PC described by the current frame state.
-     This is read from the CFA data or FDE pc range.  Hence on capability
-     architectures it is an address rather than a pointer.  For non-capability
-     architectures _Unwind_Address is the same as a pointer.  */
+     This is read from the CFA data or FDE pc range.  On capability
+     architectures it can be a pointer, but will never be an executable pointer
+     (since reading from the DWARF information can only have the permissions of
+     the capability we use for a base, and we never use an executable
+     capability for such a base).  For non-capability architectures
+     _Unwind_Address is the same as a pointer.  */
   _Unwind_Address pc;
 
   /* The information we care about from the CIE/FDE.  */
diff --git a/libgcc/unwind-pe.h b/libgcc/unwind-pe.h
index 1b0496527b8..f96a0d95c73 100644
--- a/libgcc/unwind-pe.h
+++ b/libgcc/unwind-pe.h
@@ -184,6 +184,12 @@ static const unsigned char *
 read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
 			      const unsigned char *p, _Unwind_Ptr *val)
 {
+  /* This structure can not hold capabilities since it is not aligned.
+     That is just fine, since (in the ABI's supported currently) capabilities
+     are never directly embedded in DWARF information so that the eh_frame
+     section can be read-only.  */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wif-not-aligned"
   union unaligned
     {
       void *ptr;
@@ -194,6 +200,7 @@ read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
       signed s4 __attribute__ ((mode (SI)));
       signed s8 __attribute__ ((mode (DI)));
     } __attribute__((__packed__));
+#pragma GCC diagnostic pop
 
   const union unaligned *u = (const union unaligned *) p;
   _Unwind_Internal_Ptr result;


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-03-14 10:35 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-14 10:35 [gcc(refs/vendors/ARM/heads/morello)] Fix up some cheri warnings in libgcc Matthew Malcomson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).