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 33 namespace 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 43 uint64_t 44 read_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 49 int64_t 50 read_signed_LEB_128(const unsigned char* buffer, size_t* plen); 51 52 // Write a ULEB 128 encoded VALUE to BUFFER. 53 54 void 55 write_unsigned_LEB_128(std::vector<unsigned char>* buffer, uint64_t value); 56 57 // Return the ULEB 128 encoded size of VALUE. 58 59 size_t 60 get_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 68 template <int valsize> 69 void 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 82 template <int valsize> 83 typename elfcpp::Valtype_base<valsize>::Valtype 84 read_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 96 template <int valsize> 97 typename elfcpp::Valtype_base<valsize>::Valtype 98 read_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 111 template <int valsize> 112 typename elfcpp::Valtype_base<valsize>::Valtype 113 read_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