LCOV - code coverage report
Current view: top level - include/llvm/Support - LEB128.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 94 94 100.0 %
Date: 2018-10-20 13:21:21 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     1811437 : inline unsigned encodeSLEB128(int64_t Value, raw_ostream &OS,
      25             :                               unsigned PadTo = 0) {
      26             :   bool More;
      27             :   unsigned Count = 0;
      28     3203932 :   do {
      29     3203932 :     uint8_t Byte = Value & 0x7f;
      30             :     // NOTE: this assumes that this signed shift is an arithmetic right shift.
      31     3203932 :     Value >>= 7;
      32     3203932 :     More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) ||
      33      971173 :               ((Value == -1) && ((Byte & 0x40) != 0))));
      34     3203932 :     Count++;
      35     3203932 :     if (More || Count < PadTo)
      36     1392506 :       Byte |= 0x80; // Mark this byte to show that more bytes will follow.
      37     3203932 :     OS << char(Byte);
      38             :   } while (More);
      39             : 
      40             :   // Pad with 0x80 and emit a terminating byte at the end.
      41     1811437 :   if (Count < PadTo) {
      42          10 :     uint8_t PadValue = Value < 0 ? 0x7f : 0x00;
      43          15 :     for (; Count < PadTo - 1; ++Count)
      44           5 :       OS << char(PadValue | 0x80);
      45          10 :     OS << char(PadValue);
      46          10 :     Count++;
      47             :   }
      48     1811437 :   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         136 : 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         160 :   do {
      58         160 :     uint8_t Byte = Value & 0x7f;
      59             :     // NOTE: this assumes that this signed shift is an arithmetic right shift.
      60         160 :     Value >>= 7;
      61         160 :     More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) ||
      62          11 :               ((Value == -1) && ((Byte & 0x40) != 0))));
      63         160 :     Count++;
      64         160 :     if (More || Count < PadTo)
      65         152 :       Byte |= 0x80; // Mark this byte to show that more bytes will follow.
      66         160 :     *p++ = Byte;
      67             :   } while (More);
      68             : 
      69             :   // Pad with 0x80 and emit a terminating byte at the end.
      70         136 :   if (Count < PadTo) {
      71         128 :     uint8_t PadValue = Value < 0 ? 0x7f : 0x00;
      72         471 :     for (; Count < PadTo - 1; ++Count)
      73         343 :       *p++ = (PadValue | 0x80);
      74         128 :     *p++ = PadValue;
      75             :   }
      76         136 :   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     6202101 : inline unsigned encodeULEB128(uint64_t Value, raw_ostream &OS,
      82             :                               unsigned PadTo = 0) {
      83             :   unsigned Count = 0;
      84             :   do {
      85     8212408 :     uint8_t Byte = Value & 0x7f;
      86     8212408 :     Value >>= 7;
      87     8212408 :     Count++;
      88     8212408 :     if (Value != 0 || Count < PadTo)
      89     2010637 :       Byte |= 0x80; // Mark this byte to show that more bytes will follow.
      90     8212408 :     OS << char(Byte);
      91     8212409 :   } while (Value != 0);
      92             : 
      93             :   // Pad with 0x80 and emit a null byte at the end.
      94     6202102 :   if (Count < PadTo) {
      95        1281 :     for (; Count < PadTo - 1; ++Count)
      96             :       OS << '\x80';
      97             :     OS << '\x00';
      98         330 :     Count++;
      99             :   }
     100     6202102 :   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       60738 : 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       84974 :     uint8_t Byte = Value & 0x7f;
     111       84974 :     Value >>= 7;
     112       84974 :     Count++;
     113       84974 :     if (Value != 0 || Count < PadTo)
     114       25861 :       Byte |= 0x80; // Mark this byte to show that more bytes will follow.
     115       84974 :     *p++ = Byte;
     116       84974 :   } while (Value != 0);
     117             : 
     118             :   // Pad with 0x80 and emit a null byte at the end.
     119       60738 :   if (Count < PadTo) {
     120        6436 :     for (; Count < PadTo - 1; ++Count)
     121        4811 :       *p++ = '\x80';
     122        1625 :     *p++ = '\x00';
     123             :   }
     124             : 
     125       60738 :   return (unsigned)(p - orig_p);
     126             : }
     127             : 
     128             : /// Utility function to decode a ULEB128 value.
     129    41038607 : 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    41038607 :   if (error)
     136       21256 :     *error = nullptr;
     137             :   do {
     138    54118832 :     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           4 :       return 0;
     144             :     }
     145    54159683 :     uint64_t Slice = *p & 0x7f;
     146    54159683 :     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           2 :       return 0;
     152             :     }
     153    54159681 :     Value += uint64_t(*p & 0x7f) << Shift;
     154    54159681 :     Shift += 7;
     155    54159681 :   } while (*p++ >= 128);
     156    41038601 :   if (n)
     157    41038601 :     *n = (unsigned)(p - orig_p);
     158             :   return Value;
     159             : }
     160             : 
     161             : /// Utility function to decode a SLEB128 value.
     162        2061 : 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        2582 :     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           4 :       return 0;
     176             :     }
     177        2610 :     Byte = *p++;
     178        2610 :     Value |= (int64_t(Byte & 0x7f) << Shift);
     179        2610 :     Shift += 7;
     180        2610 :   } while (Byte >= 128);
     181             :   // Sign extend negative numbers.
     182        2070 :   if (Byte & 0x40)
     183          27 :     Value |= (-1ULL) << Shift;
     184        2057 :   if (n)
     185        2076 :     *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