1 /* 2 * Copyright (C) 2015 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 17 #ifndef _LINKER_SLEB128_H 18 #define _LINKER_SLEB128_H 19 20 #include <stdint.h> 21 22 // Helper classes for decoding LEB128, used in packed relocation data. 23 // http://en.wikipedia.org/wiki/LEB128 24 25 class sleb128_decoder { 26 public: sleb128_decoder(const uint8_t * buffer,size_t count)27 sleb128_decoder(const uint8_t* buffer, size_t count) 28 : current_(buffer), end_(buffer+count) { } 29 pop_front()30 size_t pop_front() { 31 size_t value = 0; 32 static const size_t size = CHAR_BIT * sizeof(value); 33 34 size_t shift = 0; 35 uint8_t byte; 36 37 do { 38 if (current_ >= end_) { 39 __libc_fatal("sleb128_decoder ran out of bounds"); 40 } 41 byte = *current_++; 42 value |= (static_cast<size_t>(byte & 127) << shift); 43 shift += 7; 44 } while (byte & 128); 45 46 if (shift < size && (byte & 64)) { 47 value |= -(static_cast<size_t>(1) << shift); 48 } 49 50 return value; 51 } 52 53 private: 54 const uint8_t* current_; 55 const uint8_t* const end_; 56 }; 57 58 #endif // __LINKER_SLEB128_H 59