1#
2# Copyright (C) 2018 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#      http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
16"""This file contains ELF utility functions."""
17
18
19def ByteToInt(obj):
20    """Converts an element of a bytes object to an integer."""
21    return obj if isinstance(obj, int) else ord(obj)
22
23
24def BytesToString(obj):
25    """Converts bytes to a python3 string."""
26    return obj if isinstance(obj, str) else obj.decode("utf-8")
27
28
29def DecodeSLEB128(data, begin_offset=0):
30    """Decode one int64 from SLEB128 encoded bytes.
31
32    Args:
33        data: A bytes object to decode.
34        begin_offset: An integer, offset in data to start decode from.
35
36    Returns:
37        A tuple (value, num), the decoded value and number of consumed bytes.
38
39    Raises:
40        IndexError: String index out of range.
41    """
42    cur = begin_offset
43    value = 0
44    shift = 0
45    while True:
46        try:
47            byte, cur = ByteToInt(data[cur]), cur + 1
48        except IndexError:
49            raise
50        value |= (byte & 0x7F) << shift
51        shift += 7
52        if byte & 0x80 == 0:
53            break
54    if byte & 0x40:
55        value |= (-1) << shift
56    return value, cur - begin_offset
57