LCOV - code coverage report
Current view: top level - include/llvm/Support - LEB128.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 91 91 100.0 %
Date: 2018-07-13 00:08:38 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- llvm/Support/LEB128.h - [SU]LEB128 utility functions -----*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file declares some utility functions for encoding SLEB128 and
      11             : // ULEB128 values.
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #ifndef LLVM_SUPPORT_LEB128_H
      16             : #define LLVM_SUPPORT_LEB128_H
      17             : 
      18             : #include "llvm/Support/raw_ostream.h"
      19             : 
      20             : namespace llvm {
      21             : 
      22             : /// Utility function to encode a SLEB128 value to an output stream. Returns
      23             : /// the length in bytes of the encoded value.
      24     1201815 : inline unsigned encodeSLEB128(int64_t Value, raw_ostream &OS,
      25             :                               unsigned PadTo = 0) {
      26             :   bool More;
      27             :   unsigned Count = 0;
      28     2072858 :   do {
      29     2072858 :     uint8_t Byte = Value & 0x7f;
      30             :     // NOTE: this assumes that this signed shift is an arithmetic right shift.
      31     2072858 :     Value >>= 7;
      32     2072858 :     More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) ||
      33      665383 :               ((Value == -1) && ((Byte & 0x40) != 0))));
      34     2072858 :     Count++;
      35     2072858 :     if (More || Count < PadTo)
      36      871053 :       Byte |= 0x80; // Mark this byte to show that more bytes will follow.
      37     2072858 :     OS << char(Byte);
      38             :   } while (More);
      39             : 
      40             :   // Pad with 0x80 and emit a terminating byte at the end.
      41     1201815 :   if (Count < PadTo) {
      42          10 :     uint8_t PadValue = Value < 0 ? 0x7f : 0x00;
      43          20 :     for (; Count < PadTo - 1; ++Count)
      44           5 :       OS << char(PadValue | 0x80);
      45          10 :     OS << char(PadValue);
      46          10 :     Count++;
      47             :   }
      48     1201815 :   return Count;
      49             : }
      50             : 
      51             : /// Utility function to encode a SLEB128 value to a buffer. Returns
      52             : /// the length in bytes of the encoded value.
      53         137 : inline unsigned encodeSLEB128(int64_t Value, uint8_t *p, unsigned PadTo = 0) {
      54             :   uint8_t *orig_p = p;
      55             :   unsigned Count = 0;
      56             :   bool More;
      57         161 :   do {
      58         161 :     uint8_t Byte = Value & 0x7f;
      59             :     // NOTE: this assumes that this signed shift is an arithmetic right shift.
      60         161 :     Value >>= 7;
      61         161 :     More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) ||
      62          11 :               ((Value == -1) && ((Byte & 0x40) != 0))));
      63         161 :     Count++;
      64         161 :     if (More || Count < PadTo)
      65         153 :       Byte |= 0x80; // Mark this byte to show that more bytes will follow.
      66         161 :     *p++ = Byte;
      67             :   } while (More);
      68             : 
      69             :   // Pad with 0x80 and emit a terminating byte at the end.
      70         137 :   if (Count < PadTo) {
      71         129 :     uint8_t PadValue = Value < 0 ? 0x7f : 0x00;
      72         821 :     for (; Count < PadTo - 1; ++Count)
      73         346 :       *p++ = (PadValue | 0x80);
      74         129 :     *p++ = PadValue;
      75             :   }
      76         137 :   return (unsigned)(p - orig_p);
      77             : }
      78             : 
      79             : /// Utility function to encode a ULEB128 value to an output stream. Returns
      80             : /// the length in bytes of the encoded value.
      81     4300531 : inline unsigned encodeULEB128(uint64_t Value, raw_ostream &OS,
      82             :                               unsigned PadTo = 0) {
      83             :   unsigned Count = 0;
      84             :   do {
      85     4778861 :     uint8_t Byte = Value & 0x7f;
      86     4778861 :     Value >>= 7;
      87     4778861 :     Count++;
      88     4778861 :     if (Value != 0 || Count < PadTo)
      89      478638 :       Byte |= 0x80; // Mark this byte to show that more bytes will follow.
      90     4778861 :     OS << char(Byte);
      91     4778861 :   } while (Value != 0);
      92             : 
      93             :   // Pad with 0x80 and emit a null byte at the end.
      94     4300531 :   if (Count < PadTo) {
      95        2078 :     for (; Count < PadTo - 1; ++Count)
      96             :       OS << '\x80';
      97             :     OS << '\x00';
      98         308 :     Count++;
      99             :   }
     100     4300531 :   return Count;
     101             : }
     102             : 
     103             : /// Utility function to encode a ULEB128 value to a buffer. Returns
     104             : /// the length in bytes of the encoded value.
     105       58499 : inline unsigned encodeULEB128(uint64_t Value, uint8_t *p,
     106             :                               unsigned PadTo = 0) {
     107             :   uint8_t *orig_p = p;
     108             :   unsigned Count = 0;
     109             :   do {
     110       81997 :     uint8_t Byte = Value & 0x7f;
     111       81997 :     Value >>= 7;
     112       81997 :     Count++;
     113       81997 :     if (Value != 0 || Count < PadTo)
     114       25000 :       Byte |= 0x80; // Mark this byte to show that more bytes will follow.
     115       81997 :     *p++ = Byte;
     116       81997 :   } while (Value != 0);
     117             : 
     118             :   // Pad with 0x80 and emit a null byte at the end.
     119       58499 :   if (Count < PadTo) {
     120       10396 :     for (; Count < PadTo - 1; ++Count)
     121        4447 :       *p++ = '\x80';
     122        1502 :     *p++ = '\x00';
     123             :   }
     124             : 
     125       58499 :   return (unsigned)(p - orig_p);
     126             : }
     127             : 
     128             : /// Utility function to decode a ULEB128 value.
     129    40207546 : inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = nullptr,
     130             :                               const uint8_t *end = nullptr,
     131             :                               const char **error = nullptr) {
     132             :   const uint8_t *orig_p = p;
     133             :   uint64_t Value = 0;
     134             :   unsigned Shift = 0;
     135    40207546 :   if (error)
     136       18988 :     *error = nullptr;
     137             :   do {
     138    53167057 :     if (end && p == end) {
     139           4 :       if (error)
     140           4 :         *error = "malformed uleb128, extends past end";
     141           4 :       if (n)
     142           4 :         *n = (unsigned)(p - orig_p);
     143             :       return 0;
     144             :     }
     145    53206376 :     uint64_t Slice = *p & 0x7f;
     146    53206376 :     if (Shift >= 64 || Slice << Shift >> Shift != Slice) {
     147           2 :       if (error)
     148           2 :         *error = "uleb128 too big for uint64";
     149           2 :       if (n)
     150           2 :         *n = (unsigned)(p - orig_p);
     151             :       return 0;
     152             :     }
     153    53206374 :     Value += uint64_t(*p & 0x7f) << Shift;
     154    53206374 :     Shift += 7;
     155    53206374 :   } while (*p++ >= 128);
     156    40207540 :   if (n)
     157    40207540 :     *n = (unsigned)(p - orig_p);
     158             :   return Value;
     159             : }
     160             : 
     161             : /// Utility function to decode a SLEB128 value.
     162        1803 : inline int64_t decodeSLEB128(const uint8_t *p, unsigned *n = nullptr,
     163             :                              const uint8_t *end = nullptr,
     164             :                              const char **error = nullptr) {
     165             :   const uint8_t *orig_p = p;
     166             :   int64_t Value = 0;
     167             :   unsigned Shift = 0;
     168             :   uint8_t Byte;
     169             :   do {
     170        2215 :     if (end && p == end) {
     171           4 :       if (error)
     172           4 :         *error = "malformed sleb128, extends past end";
     173           4 :       if (n)
     174           4 :         *n = (unsigned)(p - orig_p);
     175             :       return 0;
     176             :     }
     177        2243 :     Byte = *p++;
     178        2243 :     Value |= (int64_t(Byte & 0x7f) << Shift);
     179        2243 :     Shift += 7;
     180        2243 :   } while (Byte >= 128);
     181             :   // Sign extend negative numbers.
     182        1812 :   if (Byte & 0x40)
     183          27 :     Value |= (-1ULL) << Shift;
     184        1799 :   if (n)
     185        1818 :     *n = (unsigned)(p - orig_p);
     186             :   return Value;
     187             : }
     188             : 
     189             : /// Utility function to get the size of the ULEB128-encoded value.
     190             : extern unsigned getULEB128Size(uint64_t Value);
     191             : 
     192             : /// Utility function to get the size of the SLEB128-encoded value.
     193             : extern unsigned getSLEB128Size(int64_t Value);
     194             : 
     195             : } // namespace llvm
     196             : 
     197             : #endif // LLVM_SYSTEM_LEB128_H

Generated by: LCOV version 1.13