149d3bc91SRichard Lowe /*
249d3bc91SRichard Lowe
3*07dc1947SRichard Lowe Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved.
449d3bc91SRichard Lowe
549d3bc91SRichard Lowe This program is free software; you can redistribute it and/or modify it
649d3bc91SRichard Lowe under the terms of version 2.1 of the GNU Lesser General Public License
749d3bc91SRichard Lowe as published by the Free Software Foundation.
849d3bc91SRichard Lowe
949d3bc91SRichard Lowe This program is distributed in the hope that it would be useful, but
1049d3bc91SRichard Lowe WITHOUT ANY WARRANTY; without even the implied warranty of
1149d3bc91SRichard Lowe MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1249d3bc91SRichard Lowe
1349d3bc91SRichard Lowe Further, this software is distributed without any warranty that it is
1449d3bc91SRichard Lowe free of the rightful claim of any third person regarding infringement
1549d3bc91SRichard Lowe or the like. Any license provided herein, whether implied or
1649d3bc91SRichard Lowe otherwise, applies only to this software file. Patent licenses, if
1749d3bc91SRichard Lowe any, provided herein do not apply to combinations of this program with
1849d3bc91SRichard Lowe other software, or any other product whatsoever.
1949d3bc91SRichard Lowe
2049d3bc91SRichard Lowe You should have received a copy of the GNU Lesser General Public
2149d3bc91SRichard Lowe License along with this program; if not, write the Free Software
22*07dc1947SRichard Lowe Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
2349d3bc91SRichard Lowe USA.
2449d3bc91SRichard Lowe
25*07dc1947SRichard Lowe Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
2649d3bc91SRichard Lowe Mountain View, CA 94043, or:
2749d3bc91SRichard Lowe
2849d3bc91SRichard Lowe http://www.sgi.com
2949d3bc91SRichard Lowe
3049d3bc91SRichard Lowe For further information regarding this notice, see:
3149d3bc91SRichard Lowe
3249d3bc91SRichard Lowe http://oss.sgi.com/projects/GenInfo/NoticeExplan
3349d3bc91SRichard Lowe
3449d3bc91SRichard Lowe */
3549d3bc91SRichard Lowe
3649d3bc91SRichard Lowe
3749d3bc91SRichard Lowe
3849d3bc91SRichard Lowe #include "config.h"
3949d3bc91SRichard Lowe #include "dwarf_incl.h"
4049d3bc91SRichard Lowe #include <stdio.h>
4149d3bc91SRichard Lowe
4249d3bc91SRichard Lowe
4349d3bc91SRichard Lowe /*
4449d3bc91SRichard Lowe decode ULEB
4549d3bc91SRichard Lowe */
4649d3bc91SRichard Lowe Dwarf_Unsigned
_dwarf_decode_u_leb128(Dwarf_Small * leb128,Dwarf_Word * leb128_length)4749d3bc91SRichard Lowe _dwarf_decode_u_leb128(Dwarf_Small * leb128, Dwarf_Word * leb128_length)
4849d3bc91SRichard Lowe {
4949d3bc91SRichard Lowe unsigned char byte;
5049d3bc91SRichard Lowe Dwarf_Word word_number;
5149d3bc91SRichard Lowe Dwarf_Unsigned number;
5249d3bc91SRichard Lowe Dwarf_Sword shift;
5349d3bc91SRichard Lowe Dwarf_Sword byte_length;
5449d3bc91SRichard Lowe
5549d3bc91SRichard Lowe /* The following unrolls-the-loop for the first few bytes and
5649d3bc91SRichard Lowe unpacks into 32 bits to make this as fast as possible.
5749d3bc91SRichard Lowe word_number is assumed big enough that the shift has a defined
5849d3bc91SRichard Lowe result. */
5949d3bc91SRichard Lowe if ((*leb128 & 0x80) == 0) {
6049d3bc91SRichard Lowe if (leb128_length != NULL)
6149d3bc91SRichard Lowe *leb128_length = 1;
6249d3bc91SRichard Lowe return (*leb128);
6349d3bc91SRichard Lowe } else if ((*(leb128 + 1) & 0x80) == 0) {
6449d3bc91SRichard Lowe if (leb128_length != NULL)
6549d3bc91SRichard Lowe *leb128_length = 2;
6649d3bc91SRichard Lowe
6749d3bc91SRichard Lowe word_number = *leb128 & 0x7f;
6849d3bc91SRichard Lowe word_number |= (*(leb128 + 1) & 0x7f) << 7;
6949d3bc91SRichard Lowe return (word_number);
7049d3bc91SRichard Lowe } else if ((*(leb128 + 2) & 0x80) == 0) {
7149d3bc91SRichard Lowe if (leb128_length != NULL)
7249d3bc91SRichard Lowe *leb128_length = 3;
7349d3bc91SRichard Lowe
7449d3bc91SRichard Lowe word_number = *leb128 & 0x7f;
7549d3bc91SRichard Lowe word_number |= (*(leb128 + 1) & 0x7f) << 7;
7649d3bc91SRichard Lowe word_number |= (*(leb128 + 2) & 0x7f) << 14;
7749d3bc91SRichard Lowe return (word_number);
7849d3bc91SRichard Lowe } else if ((*(leb128 + 3) & 0x80) == 0) {
7949d3bc91SRichard Lowe if (leb128_length != NULL)
8049d3bc91SRichard Lowe *leb128_length = 4;
8149d3bc91SRichard Lowe
8249d3bc91SRichard Lowe word_number = *leb128 & 0x7f;
8349d3bc91SRichard Lowe word_number |= (*(leb128 + 1) & 0x7f) << 7;
8449d3bc91SRichard Lowe word_number |= (*(leb128 + 2) & 0x7f) << 14;
8549d3bc91SRichard Lowe word_number |= (*(leb128 + 3) & 0x7f) << 21;
8649d3bc91SRichard Lowe return (word_number);
8749d3bc91SRichard Lowe }
8849d3bc91SRichard Lowe
89*07dc1947SRichard Lowe /* The rest handles long numbers Because the 'number' may be larger
90*07dc1947SRichard Lowe than the default int/unsigned, we must cast the 'byte' before
91*07dc1947SRichard Lowe the shift for the shift to have a defined result. */
9249d3bc91SRichard Lowe number = 0;
9349d3bc91SRichard Lowe shift = 0;
9449d3bc91SRichard Lowe byte_length = 1;
9549d3bc91SRichard Lowe byte = *(leb128);
9649d3bc91SRichard Lowe for (;;) {
9749d3bc91SRichard Lowe number |= ((Dwarf_Unsigned) (byte & 0x7f)) << shift;
9849d3bc91SRichard Lowe
9949d3bc91SRichard Lowe if ((byte & 0x80) == 0) {
10049d3bc91SRichard Lowe if (leb128_length != NULL)
10149d3bc91SRichard Lowe *leb128_length = byte_length;
10249d3bc91SRichard Lowe return (number);
10349d3bc91SRichard Lowe }
10449d3bc91SRichard Lowe shift += 7;
10549d3bc91SRichard Lowe
10649d3bc91SRichard Lowe byte_length++;
10749d3bc91SRichard Lowe ++leb128;
10849d3bc91SRichard Lowe byte = *leb128;
10949d3bc91SRichard Lowe }
11049d3bc91SRichard Lowe }
11149d3bc91SRichard Lowe
11249d3bc91SRichard Lowe #define BITSINBYTE 8
11349d3bc91SRichard Lowe
11449d3bc91SRichard Lowe /*
11549d3bc91SRichard Lowe decode SLEB
11649d3bc91SRichard Lowe */
11749d3bc91SRichard Lowe Dwarf_Signed
_dwarf_decode_s_leb128(Dwarf_Small * leb128,Dwarf_Word * leb128_length)11849d3bc91SRichard Lowe _dwarf_decode_s_leb128(Dwarf_Small * leb128, Dwarf_Word * leb128_length)
11949d3bc91SRichard Lowe {
12049d3bc91SRichard Lowe Dwarf_Signed number = 0;
12149d3bc91SRichard Lowe Dwarf_Bool sign = 0;
12249d3bc91SRichard Lowe Dwarf_Sword shift = 0;
12349d3bc91SRichard Lowe unsigned char byte = *leb128;
12449d3bc91SRichard Lowe Dwarf_Sword byte_length = 1;
12549d3bc91SRichard Lowe
12649d3bc91SRichard Lowe /* byte_length being the number of bytes of data absorbed so far in
12749d3bc91SRichard Lowe turning the leb into a Dwarf_Signed. */
12849d3bc91SRichard Lowe
12949d3bc91SRichard Lowe for (;;) {
13049d3bc91SRichard Lowe sign = byte & 0x40;
13149d3bc91SRichard Lowe number |= ((Dwarf_Signed) ((byte & 0x7f))) << shift;
13249d3bc91SRichard Lowe shift += 7;
13349d3bc91SRichard Lowe
13449d3bc91SRichard Lowe if ((byte & 0x80) == 0) {
13549d3bc91SRichard Lowe break;
13649d3bc91SRichard Lowe }
13749d3bc91SRichard Lowe ++leb128;
13849d3bc91SRichard Lowe byte = *leb128;
13949d3bc91SRichard Lowe byte_length++;
14049d3bc91SRichard Lowe }
14149d3bc91SRichard Lowe
14249d3bc91SRichard Lowe if ((shift < sizeof(Dwarf_Signed) * BITSINBYTE) && sign) {
14349d3bc91SRichard Lowe number |= -((Dwarf_Signed) 1 << shift);
14449d3bc91SRichard Lowe }
14549d3bc91SRichard Lowe
14649d3bc91SRichard Lowe if (leb128_length != NULL)
14749d3bc91SRichard Lowe *leb128_length = byte_length;
14849d3bc91SRichard Lowe return (number);
14949d3bc91SRichard Lowe }
150