This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 1/3] libgcc: Remove local _Unwind_Word and _Unwind_Sword uses


Hi,

the outcome of the "abi_word_mode" discussion last year was to get rid of
the type attribute mode(word) entirely.  The only user of that attribute is
gcc itself.  It is used in the libgcc unwinding code to define the _Unwind_Word
and _Unwind_Sword data types.  So getting rid of mode(word) means getting rid of
these two types.

The attached patch and the following two address local uses of these two data
types.  All local uses seem to be related to leb128 numbers read from the
dwarf 2 information.  The patch defines the _uleb128_t and _sleb128_t data
types to be used instead of _Unwind_Word and _Unwind_Sword.  Although a leb128
number is potentially unlimited in size these two types are defined as normal
integer types.
The intention is to have efficient types for handling all leb128 numbers in the 
unwinder code.  _Unwind_Sword is either defined as long or as long long depending on 
whether a void * fits into a long or not.

Maybe it is important to keep in mind that the new _{u|s}leb128_t types are not able 
to store the contents of a register anymore.  Consider e.g. the spu target with a 4 
byte long a 4 byte void * but 16 byte registers!  But actually it is not necessary 
to make these types as wide as a register.  Only dwarf indices and offsets are read 
using read_{u|s}leb128 but no register contents.


Following this I'll post patches for libstdc++ and libjava which have to be applied
together with this one.

The SIZEOF builtin macros patch must be applied before:
http://gcc.gnu.org/ml/gcc-patches/2007-01/msg00978.html


(Note: A copy of the libgcc unwinding code is also included in glibc what unfortunately
makes glibc a second mode(word) user.  We probably have to deal with these files as well.)


I've bootstrapped all 3 on i686, s390 and s390x.  No testsuite regressions.

OK for mainline.

Bye,

-Andreas-


2007-01-22  Andreas Krebbel  <krebbel1@de.ibm.com>

	* unwind-dw2-fde.c (get_cie_encoding): Replaced _Unwind_Word with 
	_uleb128_t and _Unwind_SWord with _sleb128_t.
	* unwind-dw2.c (extract_cie_info, execute_stack_op, execute_cfa_program,
	uw_frame_state_for, uw_update_context_1): Likewise.
	* unwind-c.c (parse_lsda_header, PERSONALITY_FUNCTION): Likewise.
	* unwind-pe.h (read_uleb128, read_sleb128,
	read_encoded_value_with_base): Likewise.
	* unwind-generic.h: Define _sleb128_t and _uleb128_t types.



Index: gcc/unwind-dw2-fde.c
===================================================================
*** gcc/unwind-dw2-fde.c.orig	2007-01-19 15:30:41.000000000 +0100
--- gcc/unwind-dw2-fde.c	2007-01-19 15:30:57.000000000 +0100
*************** get_cie_encoding (const struct dwarf_cie
*** 266,273 ****
  {
    const unsigned char *aug, *p;
    _Unwind_Ptr dummy;
!   _Unwind_Word utmp;
!   _Unwind_Sword stmp;
  
    aug = cie->augmentation;
    if (aug[0] != 'z')
--- 266,273 ----
  {
    const unsigned char *aug, *p;
    _Unwind_Ptr dummy;
!   _uleb128_t utmp;
!   _sleb128_t stmp;
  
    aug = cie->augmentation;
    if (aug[0] != 'z')
Index: gcc/unwind-dw2.c
===================================================================
*** gcc/unwind-dw2.c.orig	2007-01-19 15:30:41.000000000 +0100
--- gcc/unwind-dw2.c	2007-01-19 15:30:57.000000000 +0100
*************** extract_cie_info (const struct dwarf_cie
*** 320,326 ****
    const unsigned char *aug = cie->augmentation;
    const unsigned char *p = aug + strlen ((const char *)aug) + 1;
    const unsigned char *ret = NULL;
!   _Unwind_Word utmp;
  
    /* g++ v2 "eh" has pointer immediately following augmentation string,
       so it must be handled first.  */
--- 320,327 ----
    const unsigned char *aug = cie->augmentation;
    const unsigned char *p = aug + strlen ((const char *)aug) + 1;
    const unsigned char *ret = NULL;
!   _uleb128_t utmp;
!   _sleb128_t stmp;
  
    /* g++ v2 "eh" has pointer immediately following augmentation string,
       so it must be handled first.  */
*************** extract_cie_info (const struct dwarf_cie
*** 333,344 ****
  
    /* Immediately following the augmentation are the code and
       data alignment and return address column.  */
!   p = read_uleb128 (p, &fs->code_align);
!   p = read_sleb128 (p, &fs->data_align);
    if (cie->version == 1)
      fs->retaddr_column = *p++;
    else
!     p = read_uleb128 (p, &fs->retaddr_column);
    fs->lsda_encoding = DW_EH_PE_omit;
  
    /* If the augmentation starts with 'z', then a uleb128 immediately
--- 334,350 ----
  
    /* Immediately following the augmentation are the code and
       data alignment and return address column.  */
!   p = read_uleb128 (p, &utmp);
!   fs->code_align = (_Unwind_Word)utmp;
!   p = read_sleb128 (p, &stmp);
!   fs->data_align = (_Unwind_Sword)stmp;
    if (cie->version == 1)
      fs->retaddr_column = *p++;
    else
!     {
!       p = read_uleb128 (p, &utmp);
!       fs->retaddr_column = (_Unwind_Word)utmp;
!     }
    fs->lsda_encoding = DW_EH_PE_omit;
  
    /* If the augmentation starts with 'z', then a uleb128 immediately
*************** execute_stack_op (const unsigned char *o
*** 413,420 ****
    while (op_ptr < op_end)
      {
        enum dwarf_location_atom op = *op_ptr++;
!       _Unwind_Word result, reg, utmp;
!       _Unwind_Sword offset, stmp;
  
        switch (op)
  	{
--- 419,427 ----
    while (op_ptr < op_end)
      {
        enum dwarf_location_atom op = *op_ptr++;
!       _Unwind_Word result;
!       _uleb128_t reg, utmp;
!       _sleb128_t offset, stmp;
  
        switch (op)
  	{
*************** execute_stack_op (const unsigned char *o
*** 491,501 ****
  	  op_ptr += 8;
  	  break;
  	case DW_OP_constu:
! 	  op_ptr = read_uleb128 (op_ptr, &result);
  	  break;
  	case DW_OP_consts:
  	  op_ptr = read_sleb128 (op_ptr, &stmp);
! 	  result = stmp;
  	  break;
  
  	case DW_OP_reg0:
--- 498,509 ----
  	  op_ptr += 8;
  	  break;
  	case DW_OP_constu:
! 	  op_ptr = read_uleb128 (op_ptr, &utmp);
! 	  result = (_Unwind_Word)utmp;
  	  break;
  	case DW_OP_consts:
  	  op_ptr = read_sleb128 (op_ptr, &stmp);
! 	  result = (_Unwind_Sword)stmp;
  	  break;
  
  	case DW_OP_reg0:
*************** execute_stack_op (const unsigned char *o
*** 575,581 ****
  	case DW_OP_bregx:
  	  op_ptr = read_uleb128 (op_ptr, &reg);
  	  op_ptr = read_sleb128 (op_ptr, &offset);
! 	  result = _Unwind_GetGR (context, reg) + offset;
  	  break;
  
  	case DW_OP_dup:
--- 583,589 ----
  	case DW_OP_bregx:
  	  op_ptr = read_uleb128 (op_ptr, &reg);
  	  op_ptr = read_sleb128 (op_ptr, &offset);
! 	  result = _Unwind_GetGR (context, reg) + (_Unwind_Word)offset;
  	  break;
  
  	case DW_OP_dup:
*************** execute_stack_op (const unsigned char *o
*** 669,675 ****
  	      break;
  	    case DW_OP_plus_uconst:
  	      op_ptr = read_uleb128 (op_ptr, &utmp);
! 	      result += utmp;
  	      break;
  
  	    default:
--- 677,683 ----
  	      break;
  	    case DW_OP_plus_uconst:
  	      op_ptr = read_uleb128 (op_ptr, &utmp);
! 	      result += (_Unwind_Word)utmp;
  	      break;
  
  	    default:
*************** execute_cfa_program (const unsigned char
*** 827,834 ****
    while (insn_ptr < insn_end && fs->pc < context->ra + context->signal_frame)
      {
        unsigned char insn = *insn_ptr++;
!       _Unwind_Word reg, utmp;
!       _Unwind_Sword offset, stmp;
  
        if ((insn & 0xc0) == DW_CFA_advance_loc)
  	fs->pc += (insn & 0x3f) * fs->code_align;
--- 835,842 ----
    while (insn_ptr < insn_end && fs->pc < context->ra + context->signal_frame)
      {
        unsigned char insn = *insn_ptr++;
!       _uleb128_t reg, utmp;
!       _sleb128_t offset, stmp;
  
        if ((insn & 0xc0) == DW_CFA_advance_loc)
  	fs->pc += (insn & 0x3f) * fs->code_align;
*************** execute_cfa_program (const unsigned char
*** 898,908 ****
  
  	case DW_CFA_register:
  	  {
! 	    _Unwind_Word reg2;
  	    insn_ptr = read_uleb128 (insn_ptr, &reg);
  	    insn_ptr = read_uleb128 (insn_ptr, &reg2);
  	    fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_REG;
! 	    fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.reg = reg2;
  	  }
  	  break;
  
--- 906,917 ----
  
  	case DW_CFA_register:
  	  {
! 	    _uleb128_t reg2;
  	    insn_ptr = read_uleb128 (insn_ptr, &reg);
  	    insn_ptr = read_uleb128 (insn_ptr, &reg2);
  	    fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_REG;
! 	    fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.reg =
! 	      (_Unwind_Word)reg2;
  	  }
  	  break;
  
*************** execute_cfa_program (const unsigned char
*** 932,945 ****
  	  break;
  
  	case DW_CFA_def_cfa:
- 	  insn_ptr = read_uleb128 (insn_ptr, &fs->regs.cfa_reg);
  	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
! 	  fs->regs.cfa_offset = utmp;
  	  fs->regs.cfa_how = CFA_REG_OFFSET;
  	  break;
  
  	case DW_CFA_def_cfa_register:
! 	  insn_ptr = read_uleb128 (insn_ptr, &fs->regs.cfa_reg);
  	  fs->regs.cfa_how = CFA_REG_OFFSET;
  	  break;
  
--- 941,956 ----
  	  break;
  
  	case DW_CFA_def_cfa:
  	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
! 	  fs->regs.cfa_reg = (_Unwind_Word)utmp;
! 	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
! 	  fs->regs.cfa_offset = (_Unwind_Word)utmp;
  	  fs->regs.cfa_how = CFA_REG_OFFSET;
  	  break;
  
  	case DW_CFA_def_cfa_register:
! 	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
! 	  fs->regs.cfa_reg = (_Unwind_Word)utmp;
  	  fs->regs.cfa_how = CFA_REG_OFFSET;
  	  break;
  
*************** execute_cfa_program (const unsigned char
*** 975,988 ****
  	  break;
  
  	case DW_CFA_def_cfa_sf:
! 	  insn_ptr = read_uleb128 (insn_ptr, &fs->regs.cfa_reg);
! 	  insn_ptr = read_sleb128 (insn_ptr, &fs->regs.cfa_offset);
  	  fs->regs.cfa_how = CFA_REG_OFFSET;
  	  fs->regs.cfa_offset *= fs->data_align;
  	  break;
  
  	case DW_CFA_def_cfa_offset_sf:
! 	  insn_ptr = read_sleb128 (insn_ptr, &fs->regs.cfa_offset);
  	  fs->regs.cfa_offset *= fs->data_align;
  	  /* cfa_how deliberately not set.  */
  	  break;
--- 986,1002 ----
  	  break;
  
  	case DW_CFA_def_cfa_sf:
! 	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
! 	  fs->regs.cfa_reg = (_Unwind_Word)utmp;
! 	  insn_ptr = read_sleb128 (insn_ptr, &stmp);
! 	  fs->regs.cfa_offset = (_Unwind_Sword)stmp;
  	  fs->regs.cfa_how = CFA_REG_OFFSET;
  	  fs->regs.cfa_offset *= fs->data_align;
  	  break;
  
  	case DW_CFA_def_cfa_offset_sf:
! 	  insn_ptr = read_sleb128 (insn_ptr, &stmp);
! 	  fs->regs.cfa_offset = (_Unwind_Sword)stmp;
  	  fs->regs.cfa_offset *= fs->data_align;
  	  /* cfa_how deliberately not set.  */
  	  break;
*************** execute_cfa_program (const unsigned char
*** 1024,1030 ****
  	  break;
  
  	case DW_CFA_GNU_args_size:
! 	  insn_ptr = read_uleb128 (insn_ptr, &context->args_size);
  	  break;
  
  	case DW_CFA_GNU_negative_offset_extended:
--- 1038,1045 ----
  	  break;
  
  	case DW_CFA_GNU_args_size:
! 	  insn_ptr = read_uleb128 (insn_ptr, &utmp);
! 	  context->args_size = (_Unwind_Word)utmp;
  	  break;
  
  	case DW_CFA_GNU_negative_offset_extended:
*************** uw_frame_state_for (struct _Unwind_Conte
*** 1095,1101 ****
    insn = NULL;
    if (fs->saw_z)
      {
!       _Unwind_Word i;
        aug = read_uleb128 (aug, &i);
        insn = aug + i;
      }
--- 1110,1116 ----
    insn = NULL;
    if (fs->saw_z)
      {
!       _uleb128_t i;
        aug = read_uleb128 (aug, &i);
        insn = aug + i;
      }
*************** uw_update_context_1 (struct _Unwind_Cont
*** 1237,1243 ****
      case CFA_EXP:
        {
  	const unsigned char *exp = fs->regs.cfa_exp;
! 	_Unwind_Word len;
  
  	exp = read_uleb128 (exp, &len);
  	cfa = (void *) (_Unwind_Ptr)
--- 1252,1258 ----
      case CFA_EXP:
        {
  	const unsigned char *exp = fs->regs.cfa_exp;
! 	_uleb128_t len;
  
  	exp = read_uleb128 (exp, &len);
  	cfa = (void *) (_Unwind_Ptr)
*************** uw_update_context_1 (struct _Unwind_Cont
*** 1276,1282 ****
        case REG_SAVED_EXP:
  	{
  	  const unsigned char *exp = fs->regs.reg[i].loc.exp;
! 	  _Unwind_Word len;
  	  _Unwind_Ptr val;
  
  	  exp = read_uleb128 (exp, &len);
--- 1291,1297 ----
        case REG_SAVED_EXP:
  	{
  	  const unsigned char *exp = fs->regs.reg[i].loc.exp;
! 	  _uleb128_t len;
  	  _Unwind_Ptr val;
  
  	  exp = read_uleb128 (exp, &len);
*************** uw_update_context_1 (struct _Unwind_Cont
*** 1295,1301 ****
        case REG_SAVED_VAL_EXP:
  	{
  	  const unsigned char *exp = fs->regs.reg[i].loc.exp;
! 	  _Unwind_Word len;
  	  _Unwind_Ptr val;
  
  	  exp = read_uleb128 (exp, &len);
--- 1310,1316 ----
        case REG_SAVED_VAL_EXP:
  	{
  	  const unsigned char *exp = fs->regs.reg[i].loc.exp;
! 	  _uleb128_t len;
  	  _Unwind_Ptr val;
  
  	  exp = read_uleb128 (exp, &len);
Index: gcc/unwind-c.c
===================================================================
*** gcc/unwind-c.c.orig	2007-01-19 15:30:41.000000000 +0100
--- gcc/unwind-c.c	2007-01-19 15:30:57.000000000 +0100
*************** static const unsigned char *
*** 50,56 ****
  parse_lsda_header (struct _Unwind_Context *context, const unsigned char *p,
  		   lsda_header_info *info)
  {
!   _Unwind_Word tmp;
    unsigned char lpstart_encoding;
  
    info->Start = (context ? _Unwind_GetRegionStart (context) : 0);
--- 50,56 ----
  parse_lsda_header (struct _Unwind_Context *context, const unsigned char *p,
  		   lsda_header_info *info)
  {
!   _uleb128_t tmp;
    unsigned char lpstart_encoding;
  
    info->Start = (context ? _Unwind_GetRegionStart (context) : 0);
*************** PERSONALITY_FUNCTION (int version,
*** 175,181 ****
      return _URC_CONTINUE_UNWIND;
    else
      {
!       _Unwind_Word cs_lp, cs_action;
        do
  	{
  	  p = read_uleb128 (p, &cs_lp);
--- 175,181 ----
      return _URC_CONTINUE_UNWIND;
    else
      {
!       _uleb128_t cs_lp, cs_action;
        do
  	{
  	  p = read_uleb128 (p, &cs_lp);
*************** PERSONALITY_FUNCTION (int version,
*** 185,191 ****
  
        /* Can never have null landing pad for sjlj -- that would have
  	 been indicated by a -1 call site index.  */
!       landing_pad = cs_lp + 1;
        if (cs_action)
  	action_record = info.action_table + cs_action - 1;
        goto found_something;
--- 185,191 ----
  
        /* Can never have null landing pad for sjlj -- that would have
  	 been indicated by a -1 call site index.  */
!       landing_pad = (_Unwind_Ptr)cs_lp + 1;
        if (cs_action)
  	action_record = info.action_table + cs_action - 1;
        goto found_something;
*************** PERSONALITY_FUNCTION (int version,
*** 195,201 ****
    while (p < info.action_table)
      {
        _Unwind_Ptr cs_start, cs_len, cs_lp;
!       _Unwind_Word cs_action;
  
        /* Note that all call-site encodings are "absolute" displacements.  */
        p = read_encoded_value (0, info.call_site_encoding, p, &cs_start);
--- 195,201 ----
    while (p < info.action_table)
      {
        _Unwind_Ptr cs_start, cs_len, cs_lp;
!       _uleb128_t cs_action;
  
        /* Note that all call-site encodings are "absolute" displacements.  */
        p = read_encoded_value (0, info.call_site_encoding, p, &cs_start);
Index: gcc/unwind-pe.h
===================================================================
*** gcc/unwind-pe.h.orig	2007-01-19 15:30:41.000000000 +0100
--- gcc/unwind-pe.h	2007-01-19 15:30:57.000000000 +0100
*************** base_of_encoded_value (unsigned char enc
*** 130,146 ****
     pointers should not be leb128 encoded on that target.  */
  
  static const unsigned char *
! read_uleb128 (const unsigned char *p, _Unwind_Word *val)
  {
    unsigned int shift = 0;
    unsigned char byte;
!   _Unwind_Word result;
  
    result = 0;
    do
      {
        byte = *p++;
!       result |= ((_Unwind_Word)byte & 0x7f) << shift;
        shift += 7;
      }
    while (byte & 0x80);
--- 130,146 ----
     pointers should not be leb128 encoded on that target.  */
  
  static const unsigned char *
! read_uleb128 (const unsigned char *p, _uleb128_t *val)
  {
    unsigned int shift = 0;
    unsigned char byte;
!   _uleb128_t result;
  
    result = 0;
    do
      {
        byte = *p++;
!       result |= ((_uleb128_t)byte & 0x7f) << shift;
        shift += 7;
      }
    while (byte & 0x80);
*************** read_uleb128 (const unsigned char *p, _U
*** 152,177 ****
  /* Similar, but read a signed leb128 value.  */
  
  static const unsigned char *
! read_sleb128 (const unsigned char *p, _Unwind_Sword *val)
  {
    unsigned int shift = 0;
    unsigned char byte;
!   _Unwind_Word result;
  
    result = 0;
    do
      {
        byte = *p++;
!       result |= ((_Unwind_Word)byte & 0x7f) << shift;
        shift += 7;
      }
    while (byte & 0x80);
  
    /* Sign-extend a negative value.  */
    if (shift < 8 * sizeof(result) && (byte & 0x40) != 0)
!     result |= -(((_Unwind_Word)1L) << shift);
  
!   *val = (_Unwind_Sword) result;
    return p;
  }
  
--- 152,177 ----
  /* Similar, but read a signed leb128 value.  */
  
  static const unsigned char *
! read_sleb128 (const unsigned char *p, _sleb128_t *val)
  {
    unsigned int shift = 0;
    unsigned char byte;
!   _uleb128_t result;
  
    result = 0;
    do
      {
        byte = *p++;
!       result |= ((_uleb128_t)byte & 0x7f) << shift;
        shift += 7;
      }
    while (byte & 0x80);
  
    /* Sign-extend a negative value.  */
    if (shift < 8 * sizeof(result) && (byte & 0x40) != 0)
!     result |= -(((_uleb128_t)1L) << shift);
  
!   *val = (_sleb128_t) result;
    return p;
  }
  
*************** read_encoded_value_with_base (unsigned c
*** 215,221 ****
  
  	case DW_EH_PE_uleb128:
  	  {
! 	    _Unwind_Word tmp;
  	    p = read_uleb128 (p, &tmp);
  	    result = (_Unwind_Internal_Ptr) tmp;
  	  }
--- 215,221 ----
  
  	case DW_EH_PE_uleb128:
  	  {
! 	    _uleb128_t tmp;
  	    p = read_uleb128 (p, &tmp);
  	    result = (_Unwind_Internal_Ptr) tmp;
  	  }
*************** read_encoded_value_with_base (unsigned c
*** 223,229 ****
  
  	case DW_EH_PE_sleb128:
  	  {
! 	    _Unwind_Sword tmp;
  	    p = read_sleb128 (p, &tmp);
  	    result = (_Unwind_Internal_Ptr) tmp;
  	  }
--- 223,229 ----
  
  	case DW_EH_PE_sleb128:
  	  {
! 	    _sleb128_t tmp;
  	    p = read_sleb128 (p, &tmp);
  	    result = (_Unwind_Internal_Ptr) tmp;
  	  }
Index: gcc/unwind-generic.h
===================================================================
*** gcc/unwind-generic.h.orig	2007-01-19 15:30:41.000000000 +0100
--- gcc/unwind-generic.h	2007-01-19 15:30:57.000000000 +0100
*************** extern _Unwind_Ptr _Unwind_GetTextRelBas
*** 230,235 ****
--- 230,264 ----
     contains it.  */
  extern void * _Unwind_FindEnclosingFunction (void *pc);
  
+ #ifndef __SIZEOF_LONG__
+   #error "__SIZEOF_LONG__ macro not defined"
+ #endif
+ 
+ #ifndef __SIZEOF_VOID_P__
+   #error "__SIZEOF_VOID_P__ macro not defined"
+ #endif
+ 
+ 
+ /* leb128 type numbers have a potentially unlimited size.
+    The target of the following definitions of _sleb128_t and _uleb128_t
+    is to have efficient data types large enough to hold the leb128 type
+    numbers used in the unwind code.
+    Mostly these types will simply be defined to long and unsigned long
+    except when a unsigned long data type on the target machine is not
+    capable of storing a pointer.  */
+ 
+ #if __SIZEOF_LONG__ < __SIZEOF_VOID_P__
+ #ifdef HAVE_LONG_LONG
+   typedef long long _sleb128_t;
+   typedef unsigned long long _uleb128_t;
+ #else
+   #error "long long data type is needed to define _sleb128_t"
+ #endif
+ #else
+   typedef long _sleb128_t;
+   typedef unsigned long _uleb128_t;
+ #endif
+ 
  #ifdef __cplusplus
  }
  #endif


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]