1 /* Routines for restoring various data types from a file stream. This deals 2 with various data types like strings, integers, enums, etc. 3 4 Copyright (C) 2011-2018 Free Software Foundation, Inc. 5 Contributed by Diego Novillo <dnovillo@google.com> 6 7 This file is part of GCC. 8 9 GCC is free software; you can redistribute it and/or modify it under 10 the terms of the GNU General Public License as published by the Free 11 Software Foundation; either version 3, or (at your option) any later 12 version. 13 14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 15 WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with GCC; see the file COPYING3. If not see 21 <http://www.gnu.org/licenses/>. */ 22 23 #include "config.h" 24 #include "system.h" 25 #include "coretypes.h" 26 #include "backend.h" 27 #include "tree.h" 28 #include "gimple.h" 29 #include "cgraph.h" 30 #include "data-streamer.h" 31 32 /* Read a string from the string table in DATA_IN using input block 33 IB. Write the length to RLEN. */ 34 35 static const char * 36 string_for_index (struct data_in *data_in, unsigned int loc, unsigned int *rlen) 37 { 38 unsigned int len; 39 const char *result; 40 41 if (!loc) 42 { 43 *rlen = 0; 44 return NULL; 45 } 46 47 /* Get the string stored at location LOC in DATA_IN->STRINGS. */ 48 lto_input_block str_tab (data_in->strings, loc - 1, data_in->strings_len, NULL); 49 len = streamer_read_uhwi (&str_tab); 50 *rlen = len; 51 52 if (str_tab.p + len > data_in->strings_len) 53 internal_error ("bytecode stream: string too long for the string table"); 54 55 result = (const char *)(data_in->strings + str_tab.p); 56 57 return result; 58 } 59 60 61 /* Read a string from the string table in DATA_IN using input block 62 IB. Write the length to RLEN. */ 63 64 const char * 65 streamer_read_indexed_string (struct data_in *data_in, 66 struct lto_input_block *ib, unsigned int *rlen) 67 { 68 return string_for_index (data_in, streamer_read_uhwi (ib), rlen); 69 } 70 71 72 /* Read a NULL terminated string from the string table in DATA_IN. */ 73 74 const char * 75 streamer_read_string (struct data_in *data_in, struct lto_input_block *ib) 76 { 77 unsigned int len; 78 const char *ptr; 79 80 ptr = streamer_read_indexed_string (data_in, ib, &len); 81 if (!ptr) 82 return NULL; 83 if (ptr[len - 1] != '\0') 84 internal_error ("bytecode stream: found non-null terminated string"); 85 86 return ptr; 87 } 88 89 90 /* Read a string from the string table in DATA_IN using the bitpack BP. 91 Write the length to RLEN. */ 92 93 const char * 94 bp_unpack_indexed_string (struct data_in *data_in, 95 struct bitpack_d *bp, unsigned int *rlen) 96 { 97 return string_for_index (data_in, bp_unpack_var_len_unsigned (bp), rlen); 98 } 99 100 101 /* Read a NULL terminated string from the string table in DATA_IN. */ 102 103 const char * 104 bp_unpack_string (struct data_in *data_in, struct bitpack_d *bp) 105 { 106 unsigned int len; 107 const char *ptr; 108 109 ptr = bp_unpack_indexed_string (data_in, bp, &len); 110 if (!ptr) 111 return NULL; 112 if (ptr[len - 1] != '\0') 113 internal_error ("bytecode stream: found non-null terminated string"); 114 115 return ptr; 116 } 117 118 119 /* Read an unsigned HOST_WIDE_INT number from IB. */ 120 121 unsigned HOST_WIDE_INT 122 streamer_read_uhwi (struct lto_input_block *ib) 123 { 124 unsigned HOST_WIDE_INT result; 125 int shift; 126 unsigned HOST_WIDE_INT byte; 127 unsigned int p = ib->p; 128 unsigned int len = ib->len; 129 130 const char *data = ib->data; 131 result = data[p++]; 132 if ((result & 0x80) != 0) 133 { 134 result &= 0x7f; 135 shift = 7; 136 do 137 { 138 byte = data[p++]; 139 result |= (byte & 0x7f) << shift; 140 shift += 7; 141 } 142 while ((byte & 0x80) != 0); 143 } 144 145 /* We check for section overrun after the fact for performance reason. */ 146 if (p > len) 147 lto_section_overrun (ib); 148 149 ib->p = p; 150 return result; 151 } 152 153 154 /* Read a HOST_WIDE_INT number from IB. */ 155 156 HOST_WIDE_INT 157 streamer_read_hwi (struct lto_input_block *ib) 158 { 159 HOST_WIDE_INT result = 0; 160 int shift = 0; 161 unsigned HOST_WIDE_INT byte; 162 163 while (true) 164 { 165 byte = streamer_read_uchar (ib); 166 result |= (byte & 0x7f) << shift; 167 shift += 7; 168 if ((byte & 0x80) == 0) 169 { 170 if ((shift < HOST_BITS_PER_WIDE_INT) && (byte & 0x40)) 171 result |= - (HOST_WIDE_INT_1U << shift); 172 173 return result; 174 } 175 } 176 } 177 178 /* Read gcov_type value from IB. */ 179 180 gcov_type 181 streamer_read_gcov_count (struct lto_input_block *ib) 182 { 183 gcov_type ret = streamer_read_hwi (ib); 184 return ret; 185 } 186 187 /* Read the physical representation of a wide_int val from 188 input block IB. */ 189 190 wide_int 191 streamer_read_wide_int (struct lto_input_block *ib) 192 { 193 HOST_WIDE_INT a[WIDE_INT_MAX_ELTS]; 194 int i; 195 int prec = streamer_read_uhwi (ib); 196 int len = streamer_read_uhwi (ib); 197 for (i = 0; i < len; i++) 198 a[i] = streamer_read_hwi (ib); 199 return wide_int::from_array (a, len, prec); 200 } 201 202 /* Read the physical representation of a widest_int val from 203 input block IB. */ 204 205 widest_int 206 streamer_read_widest_int (struct lto_input_block *ib) 207 { 208 HOST_WIDE_INT a[WIDE_INT_MAX_ELTS]; 209 int i; 210 int prec ATTRIBUTE_UNUSED = streamer_read_uhwi (ib); 211 int len = streamer_read_uhwi (ib); 212 for (i = 0; i < len; i++) 213 a[i] = streamer_read_hwi (ib); 214 return widest_int::from_array (a, len); 215 } 216 217