1// int_encoding.h -- variable length and unaligned integers -*- C++ -*- 2 3// Copyright 2009 Free Software Foundation, Inc. 4// Written by Doug Kwan <dougkwan@google.com> by refactoring scattered 5// contents from other files in gold. Original code written by Ian 6// Lance Taylor <iant@google.com> and Caleb Howe <cshowe@google.com>. 7 8// This file is part of gold. 9 10// This program is free software; you can redistribute it and/or modify 11// it under the terms of the GNU General Public License as published by 12// the Free Software Foundation; either version 3 of the License, or 13// (at your option) any later version. 14 15// This program is distributed in the hope that it will be useful, 16// but WITHOUT ANY WARRANTY; without even the implied warranty of 17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18// GNU General Public License for more details. 19 20// You should have received a copy of the GNU General Public License 21// along with this program; if not, write to the Free Software 22// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 23// MA 02110-1301, USA. 24 25#ifndef GOLD_INT_ENCODING_H 26#define GOLD_INT_ENCODING_H 27 28#include <vector> 29#include "elfcpp.h" 30#include "target.h" 31#include "parameters.h" 32 33namespace gold 34{ 35 36// 37// LEB 128 encoding support. 38// 39 40// Read a ULEB 128 encoded integer from BUFFER. Return the length of the 41// encoded integer at the location PLEN. 42 43uint64_t 44read_unsigned_LEB_128(const unsigned char* buffer, size_t* plen); 45 46// Read an SLEB 128 encoded integer from BUFFER. Return the length of the 47// encoded integer at the location PLEN. 48 49int64_t 50read_signed_LEB_128(const unsigned char* buffer, size_t* plen); 51 52// Write a ULEB 128 encoded VALUE to BUFFER. 53 54void 55write_unsigned_LEB_128(std::vector<unsigned char>* buffer, uint64_t value); 56 57// Return the ULEB 128 encoded size of VALUE. 58 59size_t 60get_length_as_unsigned_LEB_128(uint64_t value); 61 62// 63// Unaligned integer encoding support. 64// 65 66// Insert VALSIZE-bit integer VALUE into DESTINATION. 67 68template <int valsize> 69void insert_into_vector(std::vector<unsigned char>* destination, 70 typename elfcpp::Valtype_base<valsize>::Valtype value) 71{ 72 unsigned char buffer[valsize / 8]; 73 if (parameters->target().is_big_endian()) 74 elfcpp::Swap_unaligned<valsize, true>::writeval(buffer, value); 75 else 76 elfcpp::Swap_unaligned<valsize, false>::writeval(buffer, value); 77 destination->insert(destination->end(), buffer, buffer + valsize / 8); 78} 79 80// Read a possibly unaligned integer of SIZE from SOURCE. 81 82template <int valsize> 83typename elfcpp::Valtype_base<valsize>::Valtype 84read_from_pointer(const unsigned char* source) 85{ 86 typename elfcpp::Valtype_base<valsize>::Valtype return_value; 87 if (parameters->target().is_big_endian()) 88 return_value = elfcpp::Swap_unaligned<valsize, true>::readval(source); 89 else 90 return_value = elfcpp::Swap_unaligned<valsize, false>::readval(source); 91 return return_value; 92} 93 94// Read a possibly unaligned integer of SIZE. Update SOURCE after read. 95 96template <int valsize> 97typename elfcpp::Valtype_base<valsize>::Valtype 98read_from_pointer(unsigned char** source) 99{ 100 typename elfcpp::Valtype_base<valsize>::Valtype return_value; 101 if (parameters->target().is_big_endian()) 102 return_value = elfcpp::Swap_unaligned<valsize, true>::readval(*source); 103 else 104 return_value = elfcpp::Swap_unaligned<valsize, false>::readval(*source); 105 *source += valsize / 8; 106 return return_value; 107} 108 109// Same as the above except for use with const unsigned char data. 110 111template <int valsize> 112typename elfcpp::Valtype_base<valsize>::Valtype 113read_from_pointer(const unsigned char** source) 114{ 115 typename elfcpp::Valtype_base<valsize>::Valtype return_value; 116 if (parameters->target().is_big_endian()) 117 return_value = elfcpp::Swap_unaligned<valsize, true>::readval(*source); 118 else 119 return_value = elfcpp::Swap_unaligned<valsize, false>::readval(*source); 120 *source += valsize / 8; 121 return return_value; 122} 123 124} // End namespace gold. 125 126#endif // !defined(GOLD_INT_ENCODING_H) 127