Ping.

Dave

On 2026-07-28 3:49 p.m., John David Anglin wrote:
> Most of this change is hppa specific but we to revise the common code
> to support ASM_OUTPUT_DWARF_TEXTREL and crtstuff.c to handle the
> initialization of tbase for text segment relative offsets.
> 
> Tested with no regressions on hppa64-hp-hpux11.11.
> 
> Okay for trunk?
> 
> Dave
> ---
> 
> hppa64-hpux: Rework EH encoding to avoid dynamic relocations
> 
> The EH encoding is revised to use text segment relative offsets
> for code labels and pc-relative offsets for data offsets.
> 
> 2026-07-28  John David Anglin  <[email protected]>
> 
> gcc/ChangeLog:
> 
>       * config/pa/pa-protos.h (pa_asm_output_dwarf_segrel): Declare.
>       * config/pa/pa.cc (pa_asm_output_dwarf_segrel): New.
>       * config/pa/pa64-hpux.h (ASM_PREFERRED_EH_DATA_FORMAT): Define.
>       (ASM_OUTPUT_DWARF_TEXTREL): Define.
>       * doc/tm.texi.in (ASM_OUTPUT_DWARF_TEXTREL): Document.
>       * doc/tm.texi: Regenerate.
>       * dwarf2asm.cc (dw2_asm_output_encoded_addr_rtx): Handle
>       ASM_OUTPUT_DWARF_TEXTREL.
> 
> libgcc/ChangeLog:
> 
>       * config/pa/pa64-hpux-lib.h (CRT_GET_RFIB_TEXT): Define.
>       * crtstuff.c (crtstuff.c): Handle CRT_GET_RFIB_TEXT.
> 
> diff --git a/gcc/config/pa/pa-protos.h b/gcc/config/pa/pa-protos.h
> index 7fbf5750800..d7bb4663bcd 100644
> --- a/gcc/config/pa/pa-protos.h
> +++ b/gcc/config/pa/pa-protos.h
> @@ -109,5 +109,7 @@ extern HOST_WIDE_INT pa_initial_elimination_offset (int, 
> int);
>  extern int pa_function_arg_size (machine_mode, const_tree);
>  extern void pa_output_function_label (FILE *);
>  extern void hppa_profile_hook (int);
> +extern void pa_asm_output_dwarf_segrel (FILE *file, int size,
> +                                     const char *label);
>  
>  extern const int pa_magic_milli[];
> diff --git a/gcc/config/pa/pa.cc b/gcc/config/pa/pa.cc
> index 0afa4c6b7c3..a6360ab96a7 100644
> --- a/gcc/config/pa/pa.cc
> +++ b/gcc/config/pa/pa.cc
> @@ -11339,4 +11339,14 @@ pa_frame_pointer_required (void)
>    return false;
>  }
>  
> +/* Output a segment relative offset.  */
> +
> +void
> +pa_asm_output_dwarf_segrel (FILE *file, int size, const char *label)
> +{
> +  fputs (integer_asm_op (size, FALSE), file);
> +  assemble_name (file, label);
> +  fputs("-$segrel$", file);
> +}
> +
>  #include "gt-pa.h"
> diff --git a/gcc/config/pa/pa64-hpux.h b/gcc/config/pa/pa64-hpux.h
> index 4673a639f44..3b90c5f0a4a 100644
> --- a/gcc/config/pa/pa64-hpux.h
> +++ b/gcc/config/pa/pa64-hpux.h
> @@ -376,3 +376,33 @@ do {                                                     
>         \
>     __cxa_finalize introduced by crtbegin.o.  So, we provide an archive
>     library of empty stub functions to resolve these symbols.  */
>  #define TARGET_ATTRIBUTE_WEAK
> +
> +/* This macro chooses the encoding of pointers embedded in the exception
> +   handling sections.  If at all possible, this should be defined such
> +   that the exception handling section will not require dynamic relocations,
> +   and so may be read-only.
> +
> +   The HP-UX dynamic linker can't handle unaligned DIR64 relocations.
> +
> +   The .eh_frame section resides in the data segment.  We use segment
> +   relative encoding for code labels which reside in the text segment as
> +   pc-relative offsets don't work.  Text segments are limited in size to
> +   2G so we can use 4-byte offsets.  We use 8-byte pc-relative encoding
> +   for data labels.  We use indirect pc-relative encoding for function
> +   pointers.  This eliminates the need for dynamic relocations.
> +
> +   We use the DW_EH_PE_aligned encoding with the HP assembler but this
> +   is never tested.  The GNU assembler is required to support many standard
> +   C++ features.  */
> +
> +#undef ASM_PREFERRED_EH_DATA_FORMAT
> +#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL)                    \
> +  (TARGET_GAS                                                                
> \
> +   ? ((CODE) == 1                                                    \
> +      ? (DW_EH_PE_textrel | DW_EH_PE_sdata4)                         \
> +      : (((GLOBAL) || (CODE) == 2 ? DW_EH_PE_indirect : 0)           \
> +      | DW_EH_PE_pcrel | DW_EH_PE_sdata8))                           \
> +   : DW_EH_PE_aligned)
> +
> +#define ASM_OUTPUT_DWARF_TEXTREL(FILE,SIZE,LABEL) \
> +  pa_asm_output_dwarf_segrel ((FILE), (SIZE), (LABEL));
> diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
> index 85e17525683..404bda98234 100644
> --- a/gcc/doc/tm.texi
> +++ b/gcc/doc/tm.texi
> @@ -10532,6 +10532,11 @@ A C statement to issue assembly directives that 
> create a reference to the
>  given @var{label} relative to the dbase, using an integer of the given 
> @var{size}.
>  @end defmac
>  
> +@defmac ASM_OUTPUT_DWARF_TEXTREL (@var{stream}, @var{size}, @var{label})
> +A C statement to issue assembly directives that create a reference to the
> +given @var{label} relative to the tbase, using an integer of the given 
> @var{size}.
> +@end defmac
> +
>  @defmac ASM_OUTPUT_DWARF_TABLE_REF (@var{label})
>  A C statement to issue assembly directives that create a reference to
>  the DWARF table identifier @var{label} from the current section.  This
> diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
> index 1a9edd0635d..564de156702 100644
> --- a/gcc/doc/tm.texi.in
> +++ b/gcc/doc/tm.texi.in
> @@ -6924,6 +6924,11 @@ A C statement to issue assembly directives that create 
> a reference to the
>  given @var{label} relative to the dbase, using an integer of the given 
> @var{size}.
>  @end defmac
>  
> +@defmac ASM_OUTPUT_DWARF_TEXTREL (@var{stream}, @var{size}, @var{label})
> +A C statement to issue assembly directives that create a reference to the
> +given @var{label} relative to the tbase, using an integer of the given 
> @var{size}.
> +@end defmac
> +
>  @defmac ASM_OUTPUT_DWARF_TABLE_REF (@var{label})
>  A C statement to issue assembly directives that create a reference to
>  the DWARF table identifier @var{label} from the current section.  This
> diff --git a/gcc/dwarf2asm.cc b/gcc/dwarf2asm.cc
> index 54d008a02be..4ec68230fea 100644
> --- a/gcc/dwarf2asm.cc
> +++ b/gcc/dwarf2asm.cc
> @@ -1153,6 +1153,13 @@ dw2_asm_output_encoded_addr_rtx (int encoding, rtx 
> addr, bool is_public,
>  #endif
>         break;
>  
> +#ifdef ASM_OUTPUT_DWARF_TEXTREL
> +     case DW_EH_PE_textrel:
> +       gcc_assert (GET_CODE (addr) == SYMBOL_REF);
> +       ASM_OUTPUT_DWARF_TEXTREL (asm_out_file, size, XSTR (addr, 0));
> +       break;
> +#endif
> +
>       default:
>         /* Other encodings should have been handled by
>            ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX.  */
> diff --git a/libgcc/config/pa/pa64-hpux-lib.h 
> b/libgcc/config/pa/pa64-hpux-lib.h
> index d7055e02bdc..73310493b03 100644
> --- a/libgcc/config/pa/pa64-hpux-lib.h
> +++ b/libgcc/config/pa/pa64-hpux-lib.h
> @@ -23,6 +23,21 @@ a copy of the GCC Runtime Library Exception along with 
> this program;
>  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
>  <http://www.gnu.org/licenses/>.  */
>  
> +/* Get text base.  Maximum size of the text segment is 2G, so we can
> +   use a SEGREL32 relocation to determine segment offset.  */
> +#define CRT_GET_RFIB_TEXT(BASE) \
> +{                                                                    \
> +  unsigned long tmp;                                                 \
> +                                                                     \
> +  __asm__ ("bl,n L$RFIB1,%0\n\t"                                     \
> +        ".word L$RFIB1-$segrel$\n"                                   \
> +        "L$RFIB1:\n\t"                                               \
> +        "depdi 0,63,2,%0\n\t"                                        \
> +        "ldw -4(%0),%1\n\t"                                          \
> +        "sub %0,%1,%0\n"                                             \
> +        : "=&r"(BASE), "=r"(tmp));                                   \
> +}
> +
>  /* We use DTOR_LIST_BEGIN to carry a bunch of hacks to allow us to use
>     the init and fini array sections with both the HP and GNU linkers.
>     The linkers setup the required dynamic entries in the dynamic segment
> diff --git a/libgcc/crtstuff.c b/libgcc/crtstuff.c
> index 44820cb27c1..39e7f49e9e0 100644
> --- a/libgcc/crtstuff.c
> +++ b/libgcc/crtstuff.c
> @@ -475,10 +475,18 @@ frame_dummy (void)
>  {
>  #ifdef USE_EH_FRAME_REGISTRY
>    static struct object object;
> -#ifdef CRT_GET_RFIB_DATA
> +#if defined (CRT_GET_RFIB_DATA) || defined (CRT_GET_RFIB_TEXT)
>    void *tbase, *dbase;
> +#ifdef CRT_GET_RFIB_TEXT
> +  CRT_GET_RFIB_TEXT (tbase);
> +#else
>    tbase = 0;
> +#endif
> +#ifdef CRT_GET_RFIB_DATA
>    CRT_GET_RFIB_DATA (dbase);
> +#else
> +  dbase = 0;
> +#endif
>    if (__register_frame_info_bases)
>      __register_frame_info_bases (__EH_FRAME_BEGIN__, &object, tbase, dbase);
>  #else


-- 
John David Anglin  [email protected]

Reply via email to