49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe/*
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved.
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe This program is free software; you can redistribute it and/or modify it
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe under the terms of version 2.1 of the GNU Lesser General Public License
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe as published by the Free Software Foundation.
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe This program is distributed in the hope that it would be useful, but
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe WITHOUT ANY WARRANTY; without even the implied warranty of
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe Further, this software is distributed without any warranty that it is
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe free of the rightful claim of any third person regarding infringement
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe or the like. Any license provided herein, whether implied or
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe otherwise, applies only to this software file. Patent licenses, if
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe any, provided herein do not apply to combinations of this program with
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe other software, or any other product whatsoever.
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe You should have received a copy of the GNU Lesser General Public
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe License along with this program; if not, write the Free Software
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe USA.
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe Mountain View, CA 94043, or:
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe http://www.sgi.com
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe For further information regarding this notice, see:
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe http://oss.sgi.com/projects/GenInfo/NoticeExplan
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe*/
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe#include "config.h"
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe#include "dwarf_incl.h"
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe#include <stdio.h>
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe/*
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe decode ULEB
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe*/
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard LoweDwarf_Unsigned
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe_dwarf_decode_u_leb128(Dwarf_Small * leb128, Dwarf_Word * leb128_length)
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe{
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe unsigned char byte;
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe Dwarf_Word word_number;
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe Dwarf_Unsigned number;
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe Dwarf_Sword shift;
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe Dwarf_Sword byte_length;
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe /* The following unrolls-the-loop for the first few bytes and
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe unpacks into 32 bits to make this as fast as possible.
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe word_number is assumed big enough that the shift has a defined
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe result. */
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe if ((*leb128 & 0x80) == 0) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (leb128_length != NULL)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *leb128_length = 1;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return (*leb128);
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe } else if ((*(leb128 + 1) & 0x80) == 0) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (leb128_length != NULL)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *leb128_length = 2;
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe word_number = *leb128 & 0x7f;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe word_number |= (*(leb128 + 1) & 0x7f) << 7;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return (word_number);
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe } else if ((*(leb128 + 2) & 0x80) == 0) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (leb128_length != NULL)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *leb128_length = 3;
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe word_number = *leb128 & 0x7f;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe word_number |= (*(leb128 + 1) & 0x7f) << 7;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe word_number |= (*(leb128 + 2) & 0x7f) << 14;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return (word_number);
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe } else if ((*(leb128 + 3) & 0x80) == 0) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (leb128_length != NULL)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *leb128_length = 4;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe word_number = *leb128 & 0x7f;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe word_number |= (*(leb128 + 1) & 0x7f) << 7;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe word_number |= (*(leb128 + 2) & 0x7f) << 14;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe word_number |= (*(leb128 + 3) & 0x7f) << 21;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return (word_number);
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe }
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe /* The rest handles long numbers Because the 'number' may be larger
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe than the default int/unsigned, we must cast the 'byte' before
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe the shift for the shift to have a defined result. */
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe number = 0;
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe shift = 0;
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe byte_length = 1;
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe byte = *(leb128);
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe for (;;) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe number |= ((Dwarf_Unsigned) (byte & 0x7f)) << shift;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if ((byte & 0x80) == 0) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if (leb128_length != NULL)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *leb128_length = byte_length;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe return (number);
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe shift += 7;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe byte_length++;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe ++leb128;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe byte = *leb128;
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe }
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe}
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe#define BITSINBYTE 8
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe/*
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe decode SLEB
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe*/
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard LoweDwarf_Signed
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe_dwarf_decode_s_leb128(Dwarf_Small * leb128, Dwarf_Word * leb128_length)
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe{
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe Dwarf_Signed number = 0;
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe Dwarf_Bool sign = 0;
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe Dwarf_Sword shift = 0;
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe unsigned char byte = *leb128;
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe Dwarf_Sword byte_length = 1;
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe /* byte_length being the number of bytes of data absorbed so far in
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe turning the leb into a Dwarf_Signed. */
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe for (;;) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe sign = byte & 0x40;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe number |= ((Dwarf_Signed) ((byte & 0x7f))) << shift;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe shift += 7;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe if ((byte & 0x80) == 0) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe break;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe }
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe ++leb128;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe byte = *leb128;
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe byte_length++;
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe }
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe if ((shift < sizeof(Dwarf_Signed) * BITSINBYTE) && sign) {
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe number |= -((Dwarf_Signed) 1 << shift);
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe }
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe if (leb128_length != NULL)
07dc1947c362e187fb955d283b692f8769dd5defRichard Lowe *leb128_length = byte_length;
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe return (number);
49d3bc91e27cd871b950d56c01398fa2f2e12ab4Richard Lowe}