X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Funwind-pe.h;h=121f8776721a5e8b9b0c1a5a938f83bb034b7f1c;hb=04c6c482d8fc5479d481e2f4ccb82b0bef4f96da;hp=9a98f4571ff41125260f8b65d2a2eeec6c05d123;hpb=8e7f75ad4cf9ecfa1b96d1459edfefd73fb006c5;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/unwind-pe.h b/gcc/unwind-pe.h index 9a98f4571ff..121f8776721 100644 --- a/gcc/unwind-pe.h +++ b/gcc/unwind-pe.h @@ -1,28 +1,35 @@ /* Exception handling and frame unwind runtime interface routines. - Copyright (C) 2001 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2004, 2008, 2009 Free Software Foundation, Inc. - This file is part of GNU CC. + This file is part of GCC. - GNU CC 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 2, or (at your option) + GCC 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. - GNU CC 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. + GCC 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 GNU CC; see the file COPYING. If not, write to - the Free Software Foundation, 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ /* @@@ Really this should be out of line, but this also causes link compatibility problems with the base ABI. This is slightly better than duplicating code, however. */ -/* If using C++, references to abort have to be qualified with std::. */ +#ifndef GCC_UNWIND_PE_H +#define GCC_UNWIND_PE_H + +/* If using C++, references to abort have to be qualified with std::. */ #if __cplusplus #define __gxx_abort std::abort #else @@ -52,11 +59,16 @@ #define DW_EH_PE_indirect 0x80 +#ifndef NO_SIZE_OF_ENCODED_VALUE + /* Given an encoding, return the number of bytes the format occupies. This is only defined for fixed-size encodings, and so does not include leb128. */ static unsigned int +size_of_encoded_value (unsigned char encoding) __attribute__ ((unused)); + +static unsigned int size_of_encoded_value (unsigned char encoding) { if (encoding == DW_EH_PE_omit) @@ -76,6 +88,8 @@ size_of_encoded_value (unsigned char encoding) __gxx_abort (); } +#endif + #ifndef NO_BASE_OF_ENCODED_VALUE /* Given an encoding and an _Unwind_Context, return the base to which @@ -108,6 +122,57 @@ base_of_encoded_value (unsigned char encoding, struct _Unwind_Context *context) #endif +/* Read an unsigned leb128 value from P, store the value in VAL, return + P incremented past the value. We assume that a word is large enough to + hold any value so encoded; if it is smaller than a pointer on some target, + 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); + + *val = result; + return p; +} + +/* 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; +} + /* Load an encoded value from memory at P. The value is returned in VAL; The function returns P incremented past the value. BASE is as given by base_of_encoded_value for this encoding in the appropriate context. */ @@ -127,57 +192,38 @@ read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base, signed s8 __attribute__ ((mode (DI))); } __attribute__((__packed__)); - union unaligned *u = (union unaligned *) p; - _Unwind_Ptr result; + const union unaligned *u = (const union unaligned *) p; + _Unwind_Internal_Ptr result; if (encoding == DW_EH_PE_aligned) { - _Unwind_Ptr a = (_Unwind_Ptr)p; + _Unwind_Internal_Ptr a = (_Unwind_Internal_Ptr) p; a = (a + sizeof (void *) - 1) & - sizeof(void *); - result = *(_Unwind_Ptr *) a; - p = (const unsigned char *)(a + sizeof (void *)); + result = *(_Unwind_Internal_Ptr *) a; + p = (const unsigned char *) (_Unwind_Internal_Ptr) (a + sizeof (void *)); } else { switch (encoding & 0x0f) { case DW_EH_PE_absptr: - result = (_Unwind_Ptr) u->ptr; + result = (_Unwind_Internal_Ptr) u->ptr; p += sizeof (void *); break; case DW_EH_PE_uleb128: { - unsigned int shift = 0; - unsigned char byte; - - result = 0; - do - { - byte = *p++; - result |= (_Unwind_Ptr)(byte & 0x7f) << shift; - shift += 7; - } - while (byte & 0x80); + _uleb128_t tmp; + p = read_uleb128 (p, &tmp); + result = (_Unwind_Internal_Ptr) tmp; } break; case DW_EH_PE_sleb128: { - unsigned int shift = 0; - unsigned char byte; - - result = 0; - do - { - byte = *p++; - result |= (_Unwind_Ptr)(byte & 0x7f) << shift; - shift += 7; - } - while (byte & 0x80); - - if (shift < 8 * sizeof(result) && (byte & 0x40) != 0) - result |= -(1L << shift); + _sleb128_t tmp; + p = read_sleb128 (p, &tmp); + result = (_Unwind_Internal_Ptr) tmp; } break; @@ -214,9 +260,9 @@ read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base, if (result != 0) { result += ((encoding & 0x70) == DW_EH_PE_pcrel - ? (_Unwind_Ptr)u : base); + ? (_Unwind_Internal_Ptr) u : base); if (encoding & DW_EH_PE_indirect) - result = *(_Unwind_Ptr *)result; + result = *(_Unwind_Internal_Ptr *) result; } } @@ -240,19 +286,4 @@ read_encoded_value (struct _Unwind_Context *context, unsigned char encoding, #endif -/* Read an unsigned leb128 value from P, store the value in VAL, return - P incremented past the value. */ - -static inline const unsigned char * -read_uleb128 (const unsigned char *p, _Unwind_Ptr *val) -{ - return read_encoded_value_with_base (DW_EH_PE_uleb128, 0, p, val); -} - -/* Similar, but read a signed leb128 value. */ - -static inline const unsigned char * -read_sleb128 (const unsigned char *p, _Unwind_Ptr *val) -{ - return read_encoded_value_with_base (DW_EH_PE_sleb128, 0, p, val); -} +#endif /* unwind-pe.h */