1 1.1 christos /* String reading 2 1.1 christos 3 1.1.1.2 christos Copyright (C) 2022-2024 Free Software Foundation, Inc. 4 1.1 christos 5 1.1 christos This file is part of GDB. 6 1.1 christos 7 1.1 christos This program is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3 of the License, or 10 1.1 christos (at your option) any later version. 11 1.1 christos 12 1.1 christos This program is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 1.1 christos 20 1.1 christos #include "target/target.h" 21 1.1 christos 22 1.1 christos /* Read LEN bytes of target memory at address MEMADDR, placing the 23 1.1 christos results in GDB's memory at MYADDR. Returns a count of the bytes 24 1.1 christos actually read, and optionally a target_xfer_status value in the 25 1.1 christos location pointed to by ERRPTR if ERRPTR is non-null. */ 26 1.1 christos 27 1.1 christos static int 28 1.1 christos partial_memory_read (CORE_ADDR memaddr, gdb_byte *myaddr, 29 1.1 christos int len, int *errptr) 30 1.1 christos { 31 1.1 christos int nread; /* Number of bytes actually read. */ 32 1.1 christos int errcode; /* Error from last read. */ 33 1.1 christos 34 1.1 christos /* First try a complete read. */ 35 1.1 christos errcode = target_read_memory (memaddr, myaddr, len); 36 1.1 christos if (errcode == 0) 37 1.1 christos { 38 1.1 christos /* Got it all. */ 39 1.1 christos nread = len; 40 1.1 christos } 41 1.1 christos else 42 1.1 christos { 43 1.1 christos /* Loop, reading one byte at a time until we get as much as we can. */ 44 1.1 christos for (errcode = 0, nread = 0; len > 0 && errcode == 0; nread++, len--) 45 1.1 christos { 46 1.1 christos errcode = target_read_memory (memaddr++, myaddr++, 1); 47 1.1 christos } 48 1.1 christos /* If an error, the last read was unsuccessful, so adjust count. */ 49 1.1 christos if (errcode != 0) 50 1.1 christos { 51 1.1 christos nread--; 52 1.1 christos } 53 1.1 christos } 54 1.1 christos if (errptr != NULL) 55 1.1 christos { 56 1.1 christos *errptr = errcode; 57 1.1 christos } 58 1.1 christos return (nread); 59 1.1 christos } 60 1.1 christos 61 1.1 christos /* See target/target.h. */ 62 1.1 christos 63 1.1 christos int 64 1.1 christos target_read_string (CORE_ADDR addr, int len, int width, 65 1.1 christos unsigned int fetchlimit, 66 1.1 christos gdb::unique_xmalloc_ptr<gdb_byte> *buffer, 67 1.1 christos int *bytes_read) 68 1.1 christos { 69 1.1 christos int errcode; /* Errno returned from bad reads. */ 70 1.1 christos unsigned int nfetch; /* Chars to fetch / chars fetched. */ 71 1.1 christos gdb_byte *bufptr; /* Pointer to next available byte in 72 1.1 christos buffer. */ 73 1.1 christos 74 1.1 christos /* Loop until we either have all the characters, or we encounter 75 1.1 christos some error, such as bumping into the end of the address space. */ 76 1.1 christos 77 1.1 christos buffer->reset (nullptr); 78 1.1 christos 79 1.1 christos if (len > 0) 80 1.1 christos { 81 1.1 christos /* We want fetchlimit chars, so we might as well read them all in 82 1.1 christos one operation. */ 83 1.1 christos unsigned int fetchlen = std::min ((unsigned) len, fetchlimit); 84 1.1 christos 85 1.1 christos buffer->reset ((gdb_byte *) xmalloc (fetchlen * width)); 86 1.1 christos bufptr = buffer->get (); 87 1.1 christos 88 1.1 christos nfetch = partial_memory_read (addr, bufptr, fetchlen * width, &errcode) 89 1.1 christos / width; 90 1.1 christos addr += nfetch * width; 91 1.1 christos bufptr += nfetch * width; 92 1.1 christos } 93 1.1 christos else if (len == -1) 94 1.1 christos { 95 1.1 christos unsigned long bufsize = 0; 96 1.1 christos unsigned int chunksize; /* Size of each fetch, in chars. */ 97 1.1 christos int found_nul; /* Non-zero if we found the nul char. */ 98 1.1 christos gdb_byte *limit; /* First location past end of fetch buffer. */ 99 1.1 christos 100 1.1 christos found_nul = 0; 101 1.1 christos /* We are looking for a NUL terminator to end the fetching, so we 102 1.1 christos might as well read in blocks that are large enough to be efficient, 103 1.1 christos but not so large as to be slow if fetchlimit happens to be large. 104 1.1 christos So we choose the minimum of 8 and fetchlimit. We used to use 200 105 1.1 christos instead of 8 but 200 is way too big for remote debugging over a 106 1.1 christos serial line. */ 107 1.1 christos chunksize = std::min (8u, fetchlimit); 108 1.1 christos 109 1.1 christos do 110 1.1 christos { 111 1.1 christos nfetch = std::min ((unsigned long) chunksize, fetchlimit - bufsize); 112 1.1 christos 113 1.1 christos if (*buffer == NULL) 114 1.1 christos buffer->reset ((gdb_byte *) xmalloc (nfetch * width)); 115 1.1 christos else 116 1.1 christos buffer->reset ((gdb_byte *) xrealloc (buffer->release (), 117 1.1 christos (nfetch + bufsize) * width)); 118 1.1 christos 119 1.1 christos bufptr = buffer->get () + bufsize * width; 120 1.1 christos bufsize += nfetch; 121 1.1 christos 122 1.1 christos /* Read as much as we can. */ 123 1.1 christos nfetch = partial_memory_read (addr, bufptr, nfetch * width, &errcode) 124 1.1 christos / width; 125 1.1 christos 126 1.1 christos /* Scan this chunk for the null character that terminates the string 127 1.1 christos to print. If found, we don't need to fetch any more. Note 128 1.1 christos that bufptr is explicitly left pointing at the next character 129 1.1 christos after the null character, or at the next character after the end 130 1.1 christos of the buffer. */ 131 1.1 christos 132 1.1 christos limit = bufptr + nfetch * width; 133 1.1 christos while (bufptr < limit) 134 1.1 christos { 135 1.1 christos bool found_nonzero = false; 136 1.1 christos 137 1.1 christos for (int i = 0; !found_nonzero && i < width; ++i) 138 1.1 christos if (bufptr[i] != 0) 139 1.1 christos found_nonzero = true; 140 1.1 christos 141 1.1 christos addr += width; 142 1.1 christos bufptr += width; 143 1.1 christos if (!found_nonzero) 144 1.1 christos { 145 1.1 christos /* We don't care about any error which happened after 146 1.1 christos the NUL terminator. */ 147 1.1 christos errcode = 0; 148 1.1 christos found_nul = 1; 149 1.1 christos break; 150 1.1 christos } 151 1.1 christos } 152 1.1 christos } 153 1.1 christos while (errcode == 0 /* no error */ 154 1.1 christos && bufptr - buffer->get () < fetchlimit * width /* no overrun */ 155 1.1 christos && !found_nul); /* haven't found NUL yet */ 156 1.1 christos } 157 1.1 christos else 158 1.1 christos { /* Length of string is really 0! */ 159 1.1 christos /* We always allocate *buffer. */ 160 1.1 christos buffer->reset ((gdb_byte *) xmalloc (1)); 161 1.1 christos bufptr = buffer->get (); 162 1.1 christos errcode = 0; 163 1.1 christos } 164 1.1 christos 165 1.1 christos /* bufptr and addr now point immediately beyond the last byte which we 166 1.1 christos consider part of the string (including a '\0' which ends the string). */ 167 1.1 christos *bytes_read = bufptr - buffer->get (); 168 1.1 christos 169 1.1 christos return errcode; 170 1.1 christos } 171 1.1 christos 172 1.1 christos /* See target/target.h. */ 173 1.1 christos 174 1.1 christos gdb::unique_xmalloc_ptr<char> 175 1.1 christos target_read_string (CORE_ADDR memaddr, int len, int *bytes_read) 176 1.1 christos { 177 1.1 christos gdb::unique_xmalloc_ptr<gdb_byte> buffer; 178 1.1 christos 179 1.1 christos int ignore; 180 1.1 christos if (bytes_read == nullptr) 181 1.1 christos bytes_read = &ignore; 182 1.1 christos 183 1.1 christos /* Note that the endian-ness does not matter here. */ 184 1.1 christos int errcode = target_read_string (memaddr, -1, 1, len, &buffer, bytes_read); 185 1.1 christos if (errcode != 0) 186 1.1 christos return {}; 187 1.1 christos 188 1.1 christos return gdb::unique_xmalloc_ptr<char> ((char *) buffer.release ()); 189 1.1 christos } 190 1.1.1.2 christos 191 1.1.1.2 christos /* See target/target.h. */ 192 1.1.1.2 christos 193 1.1.1.2 christos std::string 194 1.1.1.2 christos to_string (gdb_thread_options options) 195 1.1.1.2 christos { 196 1.1.1.2 christos static constexpr gdb_thread_options::string_mapping mapping[] = { 197 1.1.1.2 christos MAP_ENUM_FLAG (GDB_THREAD_OPTION_CLONE), 198 1.1.1.2 christos MAP_ENUM_FLAG (GDB_THREAD_OPTION_EXIT), 199 1.1.1.2 christos }; 200 1.1.1.2 christos return options.to_string (mapping); 201 1.1.1.2 christos } 202