103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// found in the LICENSE file. 403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#ifndef CRAZY_LINKER_LEB128_H 603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#define CRAZY_LINKER_LEB128_H 703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <stdint.h> 903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Helper classes for decoding LEB128, used in packed relocation data. 1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// http://en.wikipedia.org/wiki/LEB128 1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace crazy { 1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class Leb128Decoder { 1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) public: 1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) explicit Leb128Decoder(const uint8_t* encoding) 1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) : encoding_(encoding), cursor_(0) { } 1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) size_t Dequeue() { 2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) uint32_t value = 0; 2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) size_t shift = 0; 2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) uint8_t byte; 2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) do { 2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) byte = encoding_[cursor_++]; 2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) value |= static_cast<uint32_t>(byte & 127) << shift; 2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) shift += 7; 3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } while (byte & 128); 3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return value; 3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) private: 3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const uint8_t* encoding_; 3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) size_t cursor_; 3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}; 3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class Sleb128Decoder { 4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) public: 4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) explicit Sleb128Decoder(const uint8_t* encoding) 4303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) : encoding_(encoding), cursor_(0) { } 4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ssize_t Dequeue() { 4603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ssize_t value = 0; 4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) static const size_t size = CHAR_BIT * sizeof(value); 4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) size_t shift = 0; 5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) uint8_t byte; 5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) do { 5303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) byte = encoding_[cursor_++]; 5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) value |= (static_cast<ssize_t>(byte & 127) << shift); 5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) shift += 7; 5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } while (byte & 128); 5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (shift < size && (byte & 64)) 5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) value |= -(static_cast<ssize_t>(1) << shift); 6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return value; 6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) private: 6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const uint8_t* encoding_; 6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) size_t cursor_; 6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}; 6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} // namespace crazy 7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif // CRAZY_LINKER_LEB128_H 72