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
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 "libdwarfdefs.h"
4049d3bc9Richard Lowe#include <string.h>
4149d3bc9Richard Lowe#include "pro_incl.h"
4249d3bc9Richard Lowe
4349d3bc9Richard Lowe#define MORE_BYTES      0x80
4449d3bc9Richard Lowe#define DATA_MASK       0x7f
4549d3bc9Richard Lowe#define DIGIT_WIDTH     7
4649d3bc9Richard Lowe#define SIGN_BIT        0x40
4749d3bc9Richard Lowe
4849d3bc9Richard Lowe
4949d3bc9Richard Lowe/*-------------------------------------------------------------
5007dc194Richard Lowe        Encode val as a leb128. This encodes it as an unsigned
5107dc194Richard Lowe        number.
5249d3bc9Richard Lowe---------------------------------------------------------------*/
5349d3bc9Richard Lowe/* return DW_DLV_ERROR or DW_DLV_OK.
5449d3bc9Richard Lowe** space to write leb number is provided by caller, with caller
5549d3bc9Richard Lowe** passing length.
5649d3bc9Richard Lowe** number of bytes used returned thru nbytes arg
5749d3bc9Richard Lowe*/
5849d3bc9Richard Loweint
5949d3bc9Richard Lowe_dwarf_pro_encode_leb128_nm(Dwarf_Unsigned val, int *nbytes,
6007dc194Richard Lowe                            char *space, int splen)
6149d3bc9Richard Lowe{
6249d3bc9Richard Lowe    char *a;
6349d3bc9Richard Lowe    char *end = space + splen;
6449d3bc9Richard Lowe
6549d3bc9Richard Lowe    a = space;
6649d3bc9Richard Lowe    do {
6707dc194Richard Lowe        unsigned char uc;
6807dc194Richard Lowe
6907dc194Richard Lowe        if (a >= end) {
7007dc194Richard Lowe            return DW_DLV_ERROR;
7107dc194Richard Lowe        }
7207dc194Richard Lowe        uc = val & DATA_MASK;
7307dc194Richard Lowe        val >>= DIGIT_WIDTH;
7407dc194Richard Lowe        if (val != 0) {
7507dc194Richard Lowe            uc |= MORE_BYTES;
7607dc194Richard Lowe        }
7707dc194Richard Lowe        *a = uc;
7807dc194Richard Lowe        a++;
7949d3bc9Richard Lowe    } while (val);
8049d3bc9Richard Lowe    *nbytes = a - space;
8149d3bc9Richard Lowe    return DW_DLV_OK;
8249d3bc9Richard Lowe}
8349d3bc9Richard Lowe
8449d3bc9Richard Lowe/* return DW_DLV_ERROR or DW_DLV_OK.
8549d3bc9Richard Lowe** space to write leb number is provided by caller, with caller
8649d3bc9Richard Lowe** passing length.
8749d3bc9Richard Lowe** number of bytes used returned thru nbytes arg
8849d3bc9Richard Lowe** encodes a signed number.
8949d3bc9Richard Lowe*/
9049d3bc9Richard Loweint
9149d3bc9Richard Lowe_dwarf_pro_encode_signed_leb128_nm(Dwarf_Signed value, int *nbytes,
9207dc194Richard Lowe                                   char *space, int splen)
9349d3bc9Richard Lowe{
9449d3bc9Richard Lowe    char *str;
9549d3bc9Richard Lowe    Dwarf_Signed sign = -(value < 0);
9649d3bc9Richard Lowe    int more = 1;
9749d3bc9Richard Lowe    char *end = space + splen;
9849d3bc9Richard Lowe
9949d3bc9Richard Lowe    str = space;
10049d3bc9Richard Lowe
10149d3bc9Richard Lowe    do {
10207dc194Richard Lowe        unsigned char byte = value & DATA_MASK;
10307dc194Richard Lowe
10407dc194Richard Lowe        value >>= DIGIT_WIDTH;
10507dc194Richard Lowe
10607dc194Richard Lowe        if (str >= end) {
10707dc194Richard Lowe            return DW_DLV_ERROR;
10807dc194Richard Lowe        }
10907dc194Richard Lowe        /*
11007dc194Richard Lowe         * Remaining chunks would just contain the sign bit, and this chunk
11107dc194Richard Lowe         * has already captured at least one sign bit.
11207dc194Richard Lowe         */
11307dc194Richard Lowe        if (value == sign && ((byte & SIGN_BIT) == (sign & SIGN_BIT))) {
11407dc194Richard Lowe            more = 0;
11507dc194Richard Lowe        } else {
11607dc194Richard Lowe            byte |= MORE_BYTES;
11707dc194Richard Lowe        }
11807dc194Richard Lowe        *str = byte;
11907dc194Richard Lowe        str++;
12049d3bc9Richard Lowe    } while (more);
12149d3bc9Richard Lowe    *nbytes = str - space;
12249d3bc9Richard Lowe    return DW_DLV_OK;
12349d3bc9Richard Lowe}