This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils 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]

Re: PATCH: don't sign-extend address in ihex files


Ian Lance Taylor <ian@airs.com> writes:

> Alan Modra <amodra@bigpond.net.au> writes:
> 
> > On Tue, May 13, 2003 at 03:03:09PM -0500, Jim Blandy wrote:
> > > Since the value of the hex_value
> > > macro (defined in libiberty.h) is signed
> > 
> > Except when char is unsigned, which is another argument in favour of
> > your patch.
> 
> Well, since ANSI C is value preserving rather than unsignedness
> preserving, you still need the cast to unsigned int.  Otherwise
> unsigned char promotes to signed int when used in an expression.
> 
> Still, arguably the _hex_value array should be unsigned char rather
> than simply char.

I did originally want to just make hex_value itself unsigned.

How would this patch be?  I've eyeballed all the uses of hex_value in
the binutils, and they seem okay.

libiberty/ChangeLog:
2003-05-14  Jim Blandy  <jimb@redhat.com>

	* hex.c (_hex_value): Make this unsigned.
	(hex_value): Update documentation for new return type.  hex_value
	now expands to an unsigned int expression, to avoid unexpected
	sign extension when we store it in a bfd_vma, which is larger than
	int on some platforms.
	* functions.texi: Regenerated.

include/ChangeLog:
2003-05-14  Jim Blandy  <jimb@redhat.com>

	* libiberty.h (hex_value): Make the value an unsigned int, to
	avoid unexpected sign-extension when cast to unsigned types larger
	than int --- like bfd_vma, on some platforms.
	(_hex_value): Update declaration.

Index: include/libiberty.h
===================================================================
RCS file: /cvs/src/src/include/libiberty.h,v
retrieving revision 1.23
diff -c -r1.23 libiberty.h
*** include/libiberty.h	27 Feb 2003 21:01:01 -0000	1.23
--- include/libiberty.h	14 May 2003 19:42:49 -0000
***************
*** 254,265 ****
  
  #define _hex_array_size 256
  #define _hex_bad	99
! extern const char _hex_value[_hex_array_size];
  extern void hex_init PARAMS ((void));
  #define hex_p(c)	(hex_value (c) != _hex_bad)
  /* If you change this, note well: Some code relies on side effects in
     the argument being performed exactly once.  */
! #define hex_value(c)	(_hex_value[(unsigned char) (c)])
  
  /* Definitions used by the pexecute routine.  */
  
--- 254,265 ----
  
  #define _hex_array_size 256
  #define _hex_bad	99
! extern const unsigned char _hex_value[_hex_array_size];
  extern void hex_init PARAMS ((void));
  #define hex_p(c)	(hex_value (c) != _hex_bad)
  /* If you change this, note well: Some code relies on side effects in
     the argument being performed exactly once.  */
! #define hex_value(c)	((unsigned int) _hex_value[(unsigned char) (c)])
  
  /* Definitions used by the pexecute routine.  */
  
Index: libiberty/functions.texi
===================================================================
RCS file: /cvs/src/src/libiberty/functions.texi,v
retrieving revision 1.12
diff -c -r1.12 functions.texi
*** libiberty/functions.texi	16 Apr 2003 23:09:21 -0000	1.12
--- libiberty/functions.texi	14 May 2003 19:42:54 -0000
***************
*** 337,348 ****
  @end deftypefn
  
  @c hex.c:42
! @deftypefn Extension int hex_value (int @var{c})
  
  Returns the numeric equivalent of the given character when interpreted
  as a hexidecimal digit.  The result is undefined if you pass an
  invalid hex digit.  Note that the value you pass will be cast to
  @code{unsigned char} within the macro.
  
  @end deftypefn
  
--- 337,354 ----
  @end deftypefn
  
  @c hex.c:42
! @deftypefn Extension unsigned int hex_value (int @var{c})
  
  Returns the numeric equivalent of the given character when interpreted
  as a hexidecimal digit.  The result is undefined if you pass an
  invalid hex digit.  Note that the value you pass will be cast to
  @code{unsigned char} within the macro.
+ 
+ The @code{hex_value} macro returns @code{unsigned int}, rather than
+ signed @code{int}, to make it easier to use in parsing addresses from
+ hex dump files: a signed @code{int} would be sign-extended when
+ converted to a wider unsigned type --- like @code{bfd_vma}, on some
+ systems.
  
  @end deftypefn
  
Index: libiberty/hex.c
===================================================================
RCS file: /cvs/src/src/libiberty/hex.c,v
retrieving revision 1.3
diff -c -r1.3 hex.c
*** libiberty/hex.c	28 Mar 2002 04:06:38 -0000	1.3
--- libiberty/hex.c	14 May 2003 19:42:54 -0000
***************
*** 39,51 ****
  
  @end deftypefn
  
! @deftypefn Extension int hex_value (int @var{c})
  
  Returns the numeric equivalent of the given character when interpreted
  as a hexidecimal digit.  The result is undefined if you pass an
  invalid hex digit.  Note that the value you pass will be cast to
  @code{unsigned char} within the macro.
  
  @end deftypefn
  
  @undocumented _hex_array_size
--- 39,57 ----
  
  @end deftypefn
  
! @deftypefn Extension unsigned int hex_value (int @var{c})
  
  Returns the numeric equivalent of the given character when interpreted
  as a hexidecimal digit.  The result is undefined if you pass an
  invalid hex digit.  Note that the value you pass will be cast to
  @code{unsigned char} within the macro.
  
+ The @code{hex_value} macro returns @code{unsigned int}, rather than
+ signed @code{int}, to make it easier to use in parsing addresses from
+ hex dump files: a signed @code{int} would be sign-extended when
+ converted to a wider unsigned type --- like @code{bfd_vma}, on some
+ systems.
+ 
  @end deftypefn
  
  @undocumented _hex_array_size
***************
*** 60,66 ****
    && 'A' == 0x41 && 'a' == 0x61 && '!' == 0x21 \
    && EOF == -1
  
! const char _hex_value[_hex_array_size] =
  {
    _hex_bad, _hex_bad, _hex_bad, _hex_bad,   /* NUL SOH STX ETX */
    _hex_bad, _hex_bad, _hex_bad, _hex_bad,   /* EOT ENQ ACK BEL */
--- 66,72 ----
    && 'A' == 0x41 && 'a' == 0x61 && '!' == 0x21 \
    && EOF == -1
  
! const unsigned char _hex_value[_hex_array_size] =
  {
    _hex_bad, _hex_bad, _hex_bad, _hex_bad,   /* NUL SOH STX ETX */
    _hex_bad, _hex_bad, _hex_bad, _hex_bad,   /* EOT ENQ ACK BEL */
***************
*** 139,145 ****
  
  #else
  
! char _hex_value[_hex_array_size];
  
  #endif /* not ASCII */
  
--- 145,151 ----
  
  #else
  
! unsigned char _hex_value[_hex_array_size];
  
  #endif /* not ASCII */
  


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