Commit | Line | Data |
---|---|---|
4f787271 DK |
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 | ||
41cbeecc ST |
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 | ||
4f787271 DK |
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) |