149d3bc9Richard Lowe/*
249d3bc9Richard Lowe
307dc194Richard Lowe  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
449d3bc9Richard Lowe
549d3bc9Richard Lowe  This program is free software; you can redistribute it and/or modify it
649d3bc9Richard Lowe  under the terms of version 2.1 of the GNU Lesser General Public License
749d3bc9Richard Lowe  as published by the Free Software Foundation.
849d3bc9Richard Lowe
949d3bc9Richard Lowe  This program is distributed in the hope that it would be useful, but
1049d3bc9Richard Lowe  WITHOUT ANY WARRANTY; without even the implied warranty of
1149d3bc9Richard Lowe  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1249d3bc9Richard Lowe
1349d3bc9Richard Lowe  Further, this software is distributed without any warranty that it is
1449d3bc9Richard Lowe  free of the rightful claim of any third person regarding infringement
1549d3bc9Richard Lowe  or the like.  Any license provided herein, whether implied or
1649d3bc9Richard Lowe  otherwise, applies only to this software file.  Patent licenses, if
1749d3bc9Richard Lowe  any, provided herein do not apply to combinations of this program with
1849d3bc9Richard Lowe  other software, or any other product whatsoever.
1949d3bc9Richard Lowe
2049d3bc9Richard Lowe  You should have received a copy of the GNU Lesser General Public
2149d3bc9Richard Lowe  License along with this program; if not, write the Free Software
2207dc194Richard Lowe  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
2349d3bc9Richard Lowe  USA.
2449d3bc9Richard Lowe
2507dc194Richard Lowe  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
2649d3bc9Richard Lowe  Mountain View, CA 94043, or:
2749d3bc9Richard Lowe
2849d3bc9Richard Lowe  http://www.sgi.com
2949d3bc9Richard Lowe
3049d3bc9Richard Lowe  For further information regarding this notice, see:
3149d3bc9Richard Lowe
3249d3bc9Richard Lowe  http://oss.sgi.com/projects/GenInfo/NoticeExplan
3349d3bc9Richard Lowe
3449d3bc9Richard Lowe*/
3549d3bc9Richard Lowe
3649d3bc9Richard Lowe
3749d3bc9Richard Lowe
3849d3bc9Richard Lowe#include "config.h"
3949d3bc9Richard Lowe#include "dwarf_incl.h"
4049d3bc9Richard Lowe#include <stdio.h>
4149d3bc9Richard Lowe
4249d3bc9Richard Lowe
4349d3bc9Richard Lowe/*
4449d3bc9Richard Lowe    decode ULEB
4549d3bc9Richard Lowe*/
4649d3bc9Richard LoweDwarf_Unsigned
4749d3bc9Richard Lowe_dwarf_decode_u_leb128(Dwarf_Small * leb128, Dwarf_Word * leb128_length)
4849d3bc9Richard Lowe{
4949d3bc9Richard Lowe    unsigned char byte;
5049d3bc9Richard Lowe    Dwarf_Word word_number;
5149d3bc9Richard Lowe    Dwarf_Unsigned number;
5249d3bc9Richard Lowe    Dwarf_Sword shift;
5349d3bc9Richard Lowe    Dwarf_Sword byte_length;
5449d3bc9Richard Lowe
5549d3bc9Richard Lowe    /* The following unrolls-the-loop for the first few bytes and
5649d3bc9Richard Lowe       unpacks into 32 bits to make this as fast as possible.
5749d3bc9Richard Lowe       word_number is assumed big enough that the shift has a defined
5849d3bc9Richard Lowe       result. */
5949d3bc9Richard Lowe    if ((*leb128 & 0x80) == 0) {
6007dc194Richard Lowe        if (leb128_length != NULL)
6107dc194Richard Lowe            *leb128_length = 1;
6207dc194Richard Lowe        return (*leb128);
6349d3bc9Richard Lowe    } else if ((*(leb128 + 1) & 0x80) == 0) {
6407dc194Richard Lowe        if (leb128_length != NULL)
6507dc194Richard Lowe            *leb128_length = 2;
6649d3bc9Richard Lowe
6707dc194Richard Lowe        word_number = *leb128 & 0x7f;
6807dc194Richard Lowe        word_number |= (*(leb128 + 1) & 0x7f) << 7;
6907dc194Richard Lowe        return (word_number);
7049d3bc9Richard Lowe    } else if ((*(leb128 + 2) & 0x80) == 0) {
7107dc194Richard Lowe        if (leb128_length != NULL)
7207dc194Richard Lowe            *leb128_length = 3;
7349d3bc9Richard Lowe
7407dc194Richard Lowe        word_number = *leb128 & 0x7f;
7507dc194Richard Lowe        word_number |= (*(leb128 + 1) & 0x7f) << 7;
7607dc194Richard Lowe        word_number |= (*(leb128 + 2) & 0x7f) << 14;
7707dc194Richard Lowe        return (word_number);
7849d3bc9Richard Lowe    } else if ((*(leb128 + 3) & 0x80) == 0) {
7907dc194Richard Lowe        if (leb128_length != NULL)
8007dc194Richard Lowe            *leb128_length = 4;
8107dc194Richard Lowe
8207dc194Richard Lowe        word_number = *leb128 & 0x7f;
8307dc194Richard Lowe        word_number |= (*(leb128 + 1) & 0x7f) << 7;
8407dc194Richard Lowe        word_number |= (*(leb128 + 2) & 0x7f) << 14;
8507dc194Richard Lowe        word_number |= (*(leb128 + 3) & 0x7f) << 21;
8607dc194Richard Lowe        return (word_number);
8749d3bc9Richard Lowe    }
8849d3bc9Richard Lowe
8907dc194Richard Lowe    /* The rest handles long numbers Because the 'number' may be larger
9007dc194Richard Lowe       than the default int/unsigned, we must cast the 'byte' before
9107dc194Richard Lowe       the shift for the shift to have a defined result. */
9249d3bc9Richard Lowe    number = 0;
9349d3bc9Richard Lowe    shift = 0;
9449d3bc9Richard Lowe    byte_length = 1;
9549d3bc9Richard Lowe    byte = *(leb128);
9649d3bc9Richard Lowe    for (;;) {
9707dc194Richard Lowe        number |= ((Dwarf_Unsigned) (byte & 0x7f)) << shift;
9807dc194Richard Lowe
9907dc194Richard Lowe        if ((byte & 0x80) == 0) {
10007dc194Richard Lowe            if (leb128_length != NULL)
10107dc194Richard Lowe                *leb128_length = byte_length;
10207dc194Richard Lowe            return (number);
10307dc194Richard Lowe        }
10407dc194Richard Lowe        shift += 7;
10507dc194Richard Lowe
10607dc194Richard Lowe        byte_length++;
10707dc194Richard Lowe        ++leb128;
10807dc194Richard Lowe        byte = *leb128;
10949d3bc9Richard Lowe    }
11049d3bc9Richard Lowe}
11149d3bc9Richard Lowe
11249d3bc9Richard Lowe#define BITSINBYTE 8
11349d3bc9Richard Lowe
11449d3bc9Richard Lowe/*
11549d3bc9Richard Lowe    decode SLEB
11649d3bc9Richard Lowe*/
11749d3bc9Richard LoweDwarf_Signed
11849d3bc9Richard Lowe_dwarf_decode_s_leb128(Dwarf_Small * leb128, Dwarf_Word * leb128_length)
11949d3bc9Richard Lowe{
12049d3bc9Richard Lowe    Dwarf_Signed number = 0;
12149d3bc9Richard Lowe    Dwarf_Bool sign = 0;
12249d3bc9Richard Lowe    Dwarf_Sword shift = 0;
12349d3bc9Richard Lowe    unsigned char byte = *leb128;
12449d3bc9Richard Lowe    Dwarf_Sword byte_length = 1;
12549d3bc9Richard Lowe
12649d3bc9Richard Lowe    /* byte_length being the number of bytes of data absorbed so far in
12749d3bc9Richard Lowe       turning the leb into a Dwarf_Signed. */
12849d3bc9Richard Lowe
12949d3bc9Richard Lowe    for (;;) {
13007dc194Richard Lowe        sign = byte & 0x40;
13107dc194Richard Lowe        number |= ((Dwarf_Signed) ((byte & 0x7f))) << shift;
13207dc194Richard Lowe        shift += 7;
13307dc194Richard Lowe
13407dc194Richard Lowe        if ((byte & 0x80) == 0) {
13507dc194Richard Lowe            break;
13607dc194Richard Lowe        }
13707dc194Richard Lowe        ++leb128;
13807dc194Richard Lowe        byte = *leb128;
13907dc194Richard Lowe        byte_length++;
14049d3bc9Richard Lowe    }
14149d3bc9Richard Lowe
14249d3bc9Richard Lowe    if ((shift < sizeof(Dwarf_Signed) * BITSINBYTE) && sign) {
14307dc194Richard Lowe        number |= -((Dwarf_Signed) 1 << shift);
14449d3bc9Richard Lowe    }
14549d3bc9Richard Lowe
14649d3bc9Richard Lowe    if (leb128_length != NULL)
14707dc194Richard Lowe        *leb128_length = byte_length;
14849d3bc9Richard Lowe    return (number);
14949d3bc9Richard Lowe}
150