RE: PATCH: Fix read_leb128 in readelf for 64bit host

Dave Korn
2004-12-28T13:15:21Z

> -----Original Message-----
> From: binutils-owner On Behalf Of H. J. Lu
> Sent: 27 December 2004 19:02

> On Sat, Dec 25, 2004 at 04:42:29PM -0800, H. J. Lu wrote:
> > read_leb128 in readelf assumes long == int == 32bit. It doesn't work
> > with 64bit host. Does this patch look right?
> >
> >
>
> I am going to check in this patch. Gdb 6.3 has the same problem. I
> am enclosing a patch here.

> --- binutils/readelf.c.leb 2004-12-10 14:20:22.000000000 -0800
> +++ binutils/readelf.c 2004-12-27 10:49:33.689234088 -0800
> @@ -6933,7 +6933,7 @@ read_leb128 (unsigned char *data, int *l
> {
> unsigned long int result = 0;
> unsigned int num_read = 0;
> - int shift = 0;
> + unsigned int shift = 0;
> unsigned char byte;
>
> do
> @@ -6941,7 +6941,7 @@ read_leb128 (unsigned char *data, int *l
> byte = *data++;
> num_read++;
>
> - result |= (byte & 0x7f) << shift;
> + result |= ((unsigned long int) (byte & 0x7f)) << shift;
>
> shift += 7;
>
> @@ -6951,8 +6951,8 @@ read_leb128 (unsigned char *data, int *l
> if (length_return != NULL)
> *length_return = num_read;
>
> - if (sign && (shift < 32) && (byte & 0x40))
> - result |= -1 << shift;
> + if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40))
> + result |= -1L << shift;
>
> return result;
> }
>

IIRC the C spec says shift amounts >=32 are undefined behaviour, even in the
presence of larger integer types. Is shift ever going to be >= 32 for 64 bit
hosts in these functions? (I suspect it will). If so, the shift must be
decomposed into two smaller shifts, no?

cheers,
DaveK
--
Can't think of a witty .sigline today....