| // int_encoding.h -- variable length and unaligned integers -*- C++ -*- |
| |
| // Copyright 2009 Free Software Foundation, Inc. |
| // Written by Doug Kwan <dougkwan@google.com> by refactoring scattered |
| // contents from other files in gold. Original code written by Ian |
| // Lance Taylor <iant@google.com> and Caleb Howe <cshowe@google.com>. |
| |
| // This file is part of gold. |
| |
| // This program is free software; you can redistribute it and/or modify |
| // it under the terms of the GNU General Public License as published by |
| // the Free Software Foundation; either version 3 of the License, or |
| // (at your option) any later version. |
| |
| // This program is distributed in the hope that it will be useful, |
| // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| // GNU General Public License for more details. |
| |
| // You should have received a copy of the GNU General Public License |
| // along with this program; if not, write to the Free Software |
| // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
| // MA 02110-1301, USA. |
| |
| #ifndef GOLD_INT_ENCODING_H |
| #define GOLD_INT_ENCODING_H |
| |
| #include <vector> |
| #include "elfcpp.h" |
| #include "target.h" |
| #include "parameters.h" |
| |
| namespace gold |
| { |
| |
| // |
| // LEB 128 encoding support. |
| // |
| |
| // Read a ULEB 128 encoded integer from BUFFER. Return the length of the |
| // encoded integer at the location PLEN. |
| |
| uint64_t |
| read_unsigned_LEB_128(const unsigned char* buffer, size_t* plen); |
| |
| // Read an SLEB 128 encoded integer from BUFFER. Return the length of the |
| // encoded integer at the location PLEN. |
| |
| int64_t |
| read_signed_LEB_128(const unsigned char* buffer, size_t* plen); |
| |
| // Write a ULEB 128 encoded VALUE to BUFFER. |
| |
| void |
| write_unsigned_LEB_128(std::vector<unsigned char>* buffer, uint64_t value); |
| |
| // Return the ULEB 128 encoded size of VALUE. |
| |
| size_t |
| get_length_as_unsigned_LEB_128(uint64_t value); |
| |
| // |
| // Unaligned integer encoding support. |
| // |
| |
| // Insert VALSIZE-bit integer VALUE into DESTINATION. |
| |
| template <int valsize> |
| void insert_into_vector(std::vector<unsigned char>* destination, |
| typename elfcpp::Valtype_base<valsize>::Valtype value) |
| { |
| unsigned char buffer[valsize / 8]; |
| if (parameters->target().is_big_endian()) |
| elfcpp::Swap_unaligned<valsize, true>::writeval(buffer, value); |
| else |
| elfcpp::Swap_unaligned<valsize, false>::writeval(buffer, value); |
| destination->insert(destination->end(), buffer, buffer + valsize / 8); |
| } |
| |
| // Read a possibly unaligned integer of SIZE from SOURCE. |
| |
| template <int valsize> |
| typename elfcpp::Valtype_base<valsize>::Valtype |
| read_from_pointer(const unsigned char* source) |
| { |
| typename elfcpp::Valtype_base<valsize>::Valtype return_value; |
| if (parameters->target().is_big_endian()) |
| return_value = elfcpp::Swap_unaligned<valsize, true>::readval(source); |
| else |
| return_value = elfcpp::Swap_unaligned<valsize, false>::readval(source); |
| return return_value; |
| } |
| |
| // Read a possibly unaligned integer of SIZE. Update SOURCE after read. |
| |
| template <int valsize> |
| typename elfcpp::Valtype_base<valsize>::Valtype |
| read_from_pointer(unsigned char** source) |
| { |
| typename elfcpp::Valtype_base<valsize>::Valtype return_value; |
| if (parameters->target().is_big_endian()) |
| return_value = elfcpp::Swap_unaligned<valsize, true>::readval(*source); |
| else |
| return_value = elfcpp::Swap_unaligned<valsize, false>::readval(*source); |
| *source += valsize / 8; |
| return return_value; |
| } |
| |
| // Same as the above except for use with const unsigned char data. |
| |
| template <int valsize> |
| typename elfcpp::Valtype_base<valsize>::Valtype |
| read_from_pointer(const unsigned char** source) |
| { |
| typename elfcpp::Valtype_base<valsize>::Valtype return_value; |
| if (parameters->target().is_big_endian()) |
| return_value = elfcpp::Swap_unaligned<valsize, true>::readval(*source); |
| else |
| return_value = elfcpp::Swap_unaligned<valsize, false>::readval(*source); |
| *source += valsize / 8; |
| return return_value; |
| } |
| |
| } // End namespace gold. |
| |
| #endif // !defined(GOLD_INT_ENCODING_H) |