#include "config.h"
#include <stdio.h>
#include "dwarf_incl.h"
#include "dwarf_error.h"
#include "dwarf_util.h"
#define BYTESLEBMAX 10
#define BITSPERBYTE 8
int
_dwarf_decode_u_leb128_chk(Dwarf_Small * leb128,
Dwarf_Unsigned * leb128_length,
Dwarf_Unsigned *outval,
Dwarf_Byte_Ptr endptr)
{
Dwarf_Unsigned byte = 0;
Dwarf_Unsigned word_number = 0;
Dwarf_Unsigned number = 0;
unsigned shift = 0;
unsigned byte_length = 0;
if (leb128 >=endptr) {
return DW_DLV_ERROR;
}
if ((*leb128 & 0x80) == 0) {
if (leb128_length) {
*leb128_length = 1;
}
*outval = *leb128;
return DW_DLV_OK;
} else {
if ((leb128+1) >=endptr) {
return DW_DLV_ERROR;
}
if ((*(leb128 + 1) & 0x80) == 0) {
if (leb128_length) {
*leb128_length = 2;
}
word_number = *leb128 & 0x7f;
word_number |= (*(leb128 + 1) & 0x7f) << 7;
*outval = word_number;
return DW_DLV_OK;
}
}
number = 0;
shift = 0;
byte_length = 1;
byte = *leb128;
for (;;) {
if (shift >= (sizeof(number)*BITSPERBYTE)) {
return DW_DLV_ERROR;
}
number |= (byte & 0x7f) << shift;
if ((byte & 0x80) == 0) {
if (leb128_length) {
*leb128_length = byte_length;
}
*outval = number;
return DW_DLV_OK;
}
shift += 7;
byte_length++;
if (byte_length > BYTESLEBMAX) {
if( leb128_length) {
*leb128_length = BYTESLEBMAX;
}
break;
}
++leb128;
if ((leb128) >=endptr) {
return DW_DLV_ERROR;
}
byte = *leb128;
}
return DW_DLV_ERROR;
}
#define BITSINBYTE 8
int
_dwarf_decode_s_leb128_chk(Dwarf_Small * leb128, Dwarf_Unsigned * leb128_length,
Dwarf_Signed *outval,Dwarf_Byte_Ptr endptr)
{
Dwarf_Unsigned byte = 0;
Dwarf_Signed number = 0;
Dwarf_Bool sign = 0;
Dwarf_Unsigned shift = 0;
unsigned byte_length = 1;
if (!outval) {
return DW_DLV_ERROR;
}
if (leb128 >= endptr) {
return DW_DLV_ERROR;
}
byte = *leb128;
for (;;) {
sign = byte & 0x40;
if (shift >= (sizeof(number)*BITSPERBYTE)) {
return DW_DLV_ERROR;
}
number |= ((Dwarf_Unsigned) ((byte & 0x7f))) << shift;
shift += 7;
if ((byte & 0x80) == 0) {
break;
}
++leb128;
if (leb128 >= endptr) {
return DW_DLV_ERROR;
}
byte = *leb128;
byte_length++;
if (byte_length > BYTESLEBMAX) {
if (leb128_length) {
*leb128_length = BYTESLEBMAX;
}
return DW_DLV_ERROR;
}
}
if (sign) {
unsigned shiftlim = sizeof(Dwarf_Signed) * BITSINBYTE -1;
if (shift < shiftlim) {
number |= -(Dwarf_Signed)(((Dwarf_Unsigned)1) << shift);
} else if (shift == shiftlim) {
number |= (((Dwarf_Unsigned)1) << shift);
}
}
if (leb128_length) {
*leb128_length = byte_length;
}
*outval = number;
return DW_DLV_OK;
}