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 2011 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 "diagnostic.h" 27 #include "data-streamer.h" 28 29 /* Read a string from the string table in DATA_IN using input block 30 IB. Write the length to RLEN. */ 31 32 const char * 33 string_for_index (struct data_in *data_in, unsigned int loc, unsigned int *rlen) 34 { 35 struct lto_input_block str_tab; 36 unsigned int len; 37 const char *result; 38 39 if (!loc) 40 { 41 *rlen = 0; 42 return NULL; 43 } 44 45 /* Get the string stored at location LOC in DATA_IN->STRINGS. */ 46 LTO_INIT_INPUT_BLOCK (str_tab, data_in->strings, loc - 1, 47 data_in->strings_len); 48 len = streamer_read_uhwi (&str_tab); 49 *rlen = len; 50 51 if (str_tab.p + len > data_in->strings_len) 52 internal_error ("bytecode stream: string too long for the string table"); 53 54 result = (const char *)(data_in->strings + str_tab.p); 55 56 return result; 57 } 58 59 60 /* Read a string from the string table in DATA_IN using input block 61 IB. Write the length to RLEN. */ 62 63 const char * 64 streamer_read_indexed_string (struct data_in *data_in, 65 struct lto_input_block *ib, unsigned int *rlen) 66 { 67 return string_for_index (data_in, streamer_read_uhwi (ib), rlen); 68 } 69 70 71 /* Read a NULL terminated string from the string table in DATA_IN. */ 72 73 const char * 74 streamer_read_string (struct data_in *data_in, struct lto_input_block *ib) 75 { 76 unsigned int len; 77 const char *ptr; 78 79 ptr = streamer_read_indexed_string (data_in, ib, &len); 80 if (!ptr) 81 return NULL; 82 if (ptr[len - 1] != '\0') 83 internal_error ("bytecode stream: found non-null terminated string"); 84 85 return ptr; 86 } 87 88 89 /* Read an unsigned HOST_WIDE_INT number from IB. */ 90 91 unsigned HOST_WIDE_INT 92 streamer_read_uhwi (struct lto_input_block *ib) 93 { 94 unsigned HOST_WIDE_INT result = 0; 95 int shift = 0; 96 unsigned HOST_WIDE_INT byte; 97 98 while (true) 99 { 100 byte = streamer_read_uchar (ib); 101 result |= (byte & 0x7f) << shift; 102 shift += 7; 103 if ((byte & 0x80) == 0) 104 return result; 105 } 106 } 107 108 109 /* Read a HOST_WIDE_INT number from IB. */ 110 111 HOST_WIDE_INT 112 streamer_read_hwi (struct lto_input_block *ib) 113 { 114 HOST_WIDE_INT result = 0; 115 int shift = 0; 116 unsigned HOST_WIDE_INT byte; 117 118 while (true) 119 { 120 byte = streamer_read_uchar (ib); 121 result |= (byte & 0x7f) << shift; 122 shift += 7; 123 if ((byte & 0x80) == 0) 124 { 125 if ((shift < HOST_BITS_PER_WIDE_INT) && (byte & 0x40)) 126 result |= - ((HOST_WIDE_INT)1 << shift); 127 128 return result; 129 } 130 } 131 } 132