149d3bc91SRichard Lowe /*
249d3bc91SRichard Lowe
307dc1947SRichard Lowe Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved.
4*4d9fdb46SRobert Mustacchi Portions Copyright 2011 David Anderson. All Rights Reserved.
549d3bc91SRichard Lowe
649d3bc91SRichard Lowe This program is free software; you can redistribute it and/or modify it
7*4d9fdb46SRobert Mustacchi under the terms of version 2.1 of the GNU Lesser General Public License
849d3bc91SRichard Lowe as published by the Free Software Foundation.
949d3bc91SRichard Lowe
1049d3bc91SRichard Lowe This program is distributed in the hope that it would be useful, but
1149d3bc91SRichard Lowe WITHOUT ANY WARRANTY; without even the implied warranty of
12*4d9fdb46SRobert Mustacchi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1349d3bc91SRichard Lowe
1449d3bc91SRichard Lowe Further, this software is distributed without any warranty that it is
15*4d9fdb46SRobert Mustacchi free of the rightful claim of any third person regarding infringement
16*4d9fdb46SRobert Mustacchi or the like. Any license provided herein, whether implied or
1749d3bc91SRichard Lowe otherwise, applies only to this software file. Patent licenses, if
18*4d9fdb46SRobert Mustacchi any, provided herein do not apply to combinations of this program with
19*4d9fdb46SRobert Mustacchi other software, or any other product whatsoever.
2049d3bc91SRichard Lowe
21*4d9fdb46SRobert Mustacchi You should have received a copy of the GNU Lesser General Public
22*4d9fdb46SRobert Mustacchi License along with this program; if not, write the Free Software
2307dc1947SRichard Lowe Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
2449d3bc91SRichard Lowe USA.
2549d3bc91SRichard Lowe
2649d3bc91SRichard Lowe */
2749d3bc91SRichard Lowe
2849d3bc91SRichard Lowe #include "config.h"
2949d3bc91SRichard Lowe #include "libdwarfdefs.h"
3049d3bc91SRichard Lowe #include <string.h>
31*4d9fdb46SRobert Mustacchi #include "dwarf.h"
32*4d9fdb46SRobert Mustacchi #include "libdwarf.h"
33*4d9fdb46SRobert Mustacchi #include "pro_encode_nm.h"
3449d3bc91SRichard Lowe
3549d3bc91SRichard Lowe #define MORE_BYTES 0x80
3649d3bc91SRichard Lowe #define DATA_MASK 0x7f
3749d3bc91SRichard Lowe #define DIGIT_WIDTH 7
3849d3bc91SRichard Lowe #define SIGN_BIT 0x40
3949d3bc91SRichard Lowe
4049d3bc91SRichard Lowe
41*4d9fdb46SRobert Mustacchi /* Encode val as a leb128. This encodes it as an unsigned
42*4d9fdb46SRobert Mustacchi number. */
43*4d9fdb46SRobert Mustacchi /* Return DW_DLV_ERROR or DW_DLV_OK.
44*4d9fdb46SRobert Mustacchi space to write leb number is provided by caller, with caller
45*4d9fdb46SRobert Mustacchi passing length.
46*4d9fdb46SRobert Mustacchi number of bytes used returned thru nbytes arg */
4749d3bc91SRichard Lowe int
_dwarf_pro_encode_leb128_nm(Dwarf_Unsigned val,int * nbytes,char * space,int splen)4849d3bc91SRichard Lowe _dwarf_pro_encode_leb128_nm(Dwarf_Unsigned val, int *nbytes,
49*4d9fdb46SRobert Mustacchi char *space, int splen)
5049d3bc91SRichard Lowe {
5149d3bc91SRichard Lowe char *a;
5249d3bc91SRichard Lowe char *end = space + splen;
5349d3bc91SRichard Lowe
5449d3bc91SRichard Lowe a = space;
5549d3bc91SRichard Lowe do {
5607dc1947SRichard Lowe unsigned char uc;
5707dc1947SRichard Lowe
5807dc1947SRichard Lowe if (a >= end) {
5907dc1947SRichard Lowe return DW_DLV_ERROR;
6007dc1947SRichard Lowe }
6107dc1947SRichard Lowe uc = val & DATA_MASK;
6207dc1947SRichard Lowe val >>= DIGIT_WIDTH;
6307dc1947SRichard Lowe if (val != 0) {
6407dc1947SRichard Lowe uc |= MORE_BYTES;
6507dc1947SRichard Lowe }
6607dc1947SRichard Lowe *a = uc;
6707dc1947SRichard Lowe a++;
6849d3bc91SRichard Lowe } while (val);
69*4d9fdb46SRobert Mustacchi *nbytes = (int)(a - space);
7049d3bc91SRichard Lowe return DW_DLV_OK;
7149d3bc91SRichard Lowe }
7249d3bc91SRichard Lowe
7349d3bc91SRichard Lowe /* return DW_DLV_ERROR or DW_DLV_OK.
7449d3bc91SRichard Lowe ** space to write leb number is provided by caller, with caller
7549d3bc91SRichard Lowe ** passing length.
7649d3bc91SRichard Lowe ** number of bytes used returned thru nbytes arg
7749d3bc91SRichard Lowe ** encodes a signed number.
7849d3bc91SRichard Lowe */
7949d3bc91SRichard Lowe int
_dwarf_pro_encode_signed_leb128_nm(Dwarf_Signed value,int * nbytes,char * space,int splen)8049d3bc91SRichard Lowe _dwarf_pro_encode_signed_leb128_nm(Dwarf_Signed value, int *nbytes,
81*4d9fdb46SRobert Mustacchi char *space, int splen)
8249d3bc91SRichard Lowe {
8349d3bc91SRichard Lowe char *str;
8449d3bc91SRichard Lowe Dwarf_Signed sign = -(value < 0);
8549d3bc91SRichard Lowe int more = 1;
8649d3bc91SRichard Lowe char *end = space + splen;
8749d3bc91SRichard Lowe
8849d3bc91SRichard Lowe str = space;
8949d3bc91SRichard Lowe
9049d3bc91SRichard Lowe do {
9107dc1947SRichard Lowe unsigned char byte = value & DATA_MASK;
9207dc1947SRichard Lowe
9307dc1947SRichard Lowe value >>= DIGIT_WIDTH;
9407dc1947SRichard Lowe
9507dc1947SRichard Lowe if (str >= end) {
9607dc1947SRichard Lowe return DW_DLV_ERROR;
9707dc1947SRichard Lowe }
98*4d9fdb46SRobert Mustacchi /* Remaining chunks would just contain the sign bit, and this chunk
99*4d9fdb46SRobert Mustacchi has already captured at least one sign bit. */
10007dc1947SRichard Lowe if (value == sign && ((byte & SIGN_BIT) == (sign & SIGN_BIT))) {
10107dc1947SRichard Lowe more = 0;
10207dc1947SRichard Lowe } else {
10307dc1947SRichard Lowe byte |= MORE_BYTES;
10407dc1947SRichard Lowe }
10507dc1947SRichard Lowe *str = byte;
10607dc1947SRichard Lowe str++;
10749d3bc91SRichard Lowe } while (more);
108*4d9fdb46SRobert Mustacchi *nbytes = (int)(str - space);
10949d3bc91SRichard Lowe return DW_DLV_OK;
11049d3bc91SRichard Lowe }
111