PATCH: don't sign-extend address in ihex files
Jim Blandy
jimb@redhat.com
Wed May 14 20:06:00 GMT 2003
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 */
More information about the Binutils
mailing list