xref: /illumos-gate/usr/src/lib/libdwarf/common/pro_encode_nm.c (revision 4d9fdb46b215739778ebc12079842c9905586999)
1bc1f688bSRobert Mustacchi /*
2bc1f688bSRobert Mustacchi 
3bc1f688bSRobert Mustacchi   Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
4*4d9fdb46SRobert Mustacchi   Portions Copyright 2011 David Anderson.  All Rights Reserved.
5bc1f688bSRobert Mustacchi 
6bc1f688bSRobert Mustacchi   This program is free software; you can redistribute it and/or modify it
7bc1f688bSRobert Mustacchi   under the terms of version 2.1 of the GNU Lesser General Public License
8bc1f688bSRobert Mustacchi   as published by the Free Software Foundation.
9bc1f688bSRobert Mustacchi 
10bc1f688bSRobert Mustacchi   This program is distributed in the hope that it would be useful, but
11bc1f688bSRobert Mustacchi   WITHOUT ANY WARRANTY; without even the implied warranty of
12bc1f688bSRobert Mustacchi   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13bc1f688bSRobert Mustacchi 
14bc1f688bSRobert Mustacchi   Further, this software is distributed without any warranty that it is
15bc1f688bSRobert Mustacchi   free of the rightful claim of any third person regarding infringement
16bc1f688bSRobert Mustacchi   or the like.  Any license provided herein, whether implied or
17bc1f688bSRobert Mustacchi   otherwise, applies only to this software file.  Patent licenses, if
18bc1f688bSRobert Mustacchi   any, provided herein do not apply to combinations of this program with
19bc1f688bSRobert Mustacchi   other software, or any other product whatsoever.
20bc1f688bSRobert Mustacchi 
21bc1f688bSRobert Mustacchi   You should have received a copy of the GNU Lesser General Public
22bc1f688bSRobert Mustacchi   License along with this program; if not, write the Free Software
23bc1f688bSRobert Mustacchi   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
24bc1f688bSRobert Mustacchi   USA.
25bc1f688bSRobert Mustacchi 
26bc1f688bSRobert Mustacchi */
27bc1f688bSRobert Mustacchi 
28bc1f688bSRobert Mustacchi #include "config.h"
29bc1f688bSRobert Mustacchi #include "libdwarfdefs.h"
30bc1f688bSRobert Mustacchi #include <string.h>
31*4d9fdb46SRobert Mustacchi #include "dwarf.h"
32*4d9fdb46SRobert Mustacchi #include "libdwarf.h"
33*4d9fdb46SRobert Mustacchi #include "pro_encode_nm.h"
34bc1f688bSRobert Mustacchi 
35bc1f688bSRobert Mustacchi #define MORE_BYTES      0x80
36bc1f688bSRobert Mustacchi #define DATA_MASK       0x7f
37bc1f688bSRobert Mustacchi #define DIGIT_WIDTH     7
38bc1f688bSRobert Mustacchi #define SIGN_BIT        0x40
39bc1f688bSRobert Mustacchi 
40bc1f688bSRobert Mustacchi 
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 */
47bc1f688bSRobert Mustacchi int
_dwarf_pro_encode_leb128_nm(Dwarf_Unsigned val,int * nbytes,char * space,int splen)48bc1f688bSRobert Mustacchi _dwarf_pro_encode_leb128_nm(Dwarf_Unsigned val, int *nbytes,
49bc1f688bSRobert Mustacchi     char *space, int splen)
50bc1f688bSRobert Mustacchi {
51bc1f688bSRobert Mustacchi     char *a;
52bc1f688bSRobert Mustacchi     char *end = space + splen;
53bc1f688bSRobert Mustacchi 
54bc1f688bSRobert Mustacchi     a = space;
55bc1f688bSRobert Mustacchi     do {
56bc1f688bSRobert Mustacchi         unsigned char uc;
57bc1f688bSRobert Mustacchi 
58bc1f688bSRobert Mustacchi         if (a >= end) {
59bc1f688bSRobert Mustacchi             return DW_DLV_ERROR;
60bc1f688bSRobert Mustacchi         }
61bc1f688bSRobert Mustacchi         uc = val & DATA_MASK;
62bc1f688bSRobert Mustacchi         val >>= DIGIT_WIDTH;
63bc1f688bSRobert Mustacchi         if (val != 0) {
64bc1f688bSRobert Mustacchi             uc |= MORE_BYTES;
65bc1f688bSRobert Mustacchi         }
66bc1f688bSRobert Mustacchi         *a = uc;
67bc1f688bSRobert Mustacchi         a++;
68bc1f688bSRobert Mustacchi     } while (val);
69*4d9fdb46SRobert Mustacchi     *nbytes = (int)(a - space);
70bc1f688bSRobert Mustacchi     return DW_DLV_OK;
71bc1f688bSRobert Mustacchi }
72bc1f688bSRobert Mustacchi 
73bc1f688bSRobert Mustacchi /* return DW_DLV_ERROR or DW_DLV_OK.
74bc1f688bSRobert Mustacchi ** space to write leb number is provided by caller, with caller
75bc1f688bSRobert Mustacchi ** passing length.
76bc1f688bSRobert Mustacchi ** number of bytes used returned thru nbytes arg
77bc1f688bSRobert Mustacchi ** encodes a signed number.
78bc1f688bSRobert Mustacchi */
79bc1f688bSRobert Mustacchi int
_dwarf_pro_encode_signed_leb128_nm(Dwarf_Signed value,int * nbytes,char * space,int splen)80bc1f688bSRobert Mustacchi _dwarf_pro_encode_signed_leb128_nm(Dwarf_Signed value, int *nbytes,
81bc1f688bSRobert Mustacchi     char *space, int splen)
82bc1f688bSRobert Mustacchi {
83bc1f688bSRobert Mustacchi     char *str;
84bc1f688bSRobert Mustacchi     Dwarf_Signed sign = -(value < 0);
85bc1f688bSRobert Mustacchi     int more = 1;
86bc1f688bSRobert Mustacchi     char *end = space + splen;
87bc1f688bSRobert Mustacchi 
88bc1f688bSRobert Mustacchi     str = space;
89bc1f688bSRobert Mustacchi 
90bc1f688bSRobert Mustacchi     do {
91bc1f688bSRobert Mustacchi         unsigned char byte = value & DATA_MASK;
92bc1f688bSRobert Mustacchi 
93bc1f688bSRobert Mustacchi         value >>= DIGIT_WIDTH;
94bc1f688bSRobert Mustacchi 
95bc1f688bSRobert Mustacchi         if (str >= end) {
96bc1f688bSRobert Mustacchi             return DW_DLV_ERROR;
97bc1f688bSRobert Mustacchi         }
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.  */
100bc1f688bSRobert Mustacchi         if (value == sign && ((byte & SIGN_BIT) == (sign & SIGN_BIT))) {
101bc1f688bSRobert Mustacchi             more = 0;
102bc1f688bSRobert Mustacchi         } else {
103bc1f688bSRobert Mustacchi             byte |= MORE_BYTES;
104bc1f688bSRobert Mustacchi         }
105bc1f688bSRobert Mustacchi         *str = byte;
106bc1f688bSRobert Mustacchi         str++;
107bc1f688bSRobert Mustacchi     } while (more);
108*4d9fdb46SRobert Mustacchi     *nbytes = (int)(str - space);
109bc1f688bSRobert Mustacchi     return DW_DLV_OK;
110bc1f688bSRobert Mustacchi }
111