1 /* Miscellaneous simulator utilities. 2 Copyright (C) 1997-2023 Free Software Foundation, Inc. 3 Contributed by Cygnus Support. 4 5 This file is part of GDB, the GNU debugger. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 /* This must come before any other includes. */ 21 #include "defs.h" 22 23 #include <stdarg.h> 24 #include <stdlib.h> 25 #include <string.h> 26 #include <time.h> 27 #ifdef HAVE_SYS_RESOURCE_H 28 #include <sys/resource.h> 29 #endif 30 #include <sys/time.h> /* needed by sys/resource.h */ 31 32 #include "bfd.h" 33 #include "libiberty.h" 34 35 #include "sim-main.h" 36 #include "sim-assert.h" 37 #include "sim-utils.h" 38 39 /* Allocate zero filled memory with xcalloc - xcalloc aborts if the 40 allocation fails. */ 41 42 void * 43 zalloc (unsigned long size) 44 { 45 return xcalloc (1, size); 46 } 47 48 /* Allocate a sim_state struct. */ 49 50 SIM_DESC 51 sim_state_alloc_extra (SIM_OPEN_KIND kind, host_callback *callback, 52 size_t extra_bytes) 53 { 54 SIM_DESC sd = ZALLOC (struct sim_state); 55 56 STATE_MAGIC (sd) = SIM_MAGIC_NUMBER; 57 STATE_CALLBACK (sd) = callback; 58 STATE_OPEN_KIND (sd) = kind; 59 60 if (extra_bytes) 61 STATE_ARCH_DATA (sd) = zalloc (extra_bytes); 62 63 #if 0 64 { 65 int cpu_nr; 66 67 /* Initialize the back link from the cpu struct to the state struct. */ 68 /* ??? I can envision a design where the state struct contains an array 69 of pointers to cpu structs, rather than an array of structs themselves. 70 Implementing this is trickier as one may not know what to allocate until 71 one has parsed the args. Parsing the args twice wouldn't be unreasonable, 72 IMHO. If the state struct ever does contain an array of pointers then we 73 can't do this here. 74 ??? See also sim_post_argv_init*/ 75 for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++) 76 { 77 CPU_STATE (STATE_CPU (sd, cpu_nr)) = sd; 78 CPU_INDEX (STATE_CPU (sd, cpu_nr)) = cpu_nr; 79 } 80 } 81 #endif 82 83 #ifdef SIM_STATE_INIT 84 SIM_STATE_INIT (sd); 85 #endif 86 87 return sd; 88 } 89 90 /* Free a sim_state struct. */ 91 92 void 93 sim_state_free (SIM_DESC sd) 94 { 95 ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 96 97 #ifdef SIM_STATE_FREE 98 SIM_STATE_FREE (sd); 99 #endif 100 101 free (STATE_PROG_FILE (sd)); 102 free (STATE_PROG_ARGV0 (sd)); 103 freeargv (STATE_PROG_ENVP (sd)); 104 free (sd); 105 } 106 107 /* Return a pointer to the cpu data for CPU_NAME, or NULL if not found. */ 108 109 sim_cpu * 110 sim_cpu_lookup (SIM_DESC sd, const char *cpu_name) 111 { 112 int i; 113 114 for (i = 0; i < MAX_NR_PROCESSORS; ++i) 115 if (strcmp (cpu_name, CPU_NAME (STATE_CPU (sd, i))) == 0) 116 return STATE_CPU (sd, i); 117 return NULL; 118 } 119 120 /* Return the prefix to use for a CPU specific message (typically an 121 error message). */ 122 123 const char * 124 sim_cpu_msg_prefix (sim_cpu *cpu) 125 { 126 #if MAX_NR_PROCESSORS == 1 127 return ""; 128 #else 129 static char *prefix; 130 131 if (prefix == NULL) 132 { 133 int maxlen = 0; 134 for (i = 0; i < MAX_NR_PROCESSORS; ++i) 135 { 136 int len = strlen (CPU_NAME (STATE_CPU (sd, i))); 137 if (len > maxlen) 138 maxlen = len; 139 } 140 prefix = (char *) xmalloc (maxlen + 5); 141 } 142 sprintf (prefix, "%s: ", CPU_NAME (cpu)); 143 return prefix; 144 #endif 145 } 146 147 /* Cover fn to sim_io_eprintf. */ 148 149 void 150 sim_io_eprintf_cpu (sim_cpu *cpu, const char *fmt, ...) 151 { 152 SIM_DESC sd = CPU_STATE (cpu); 153 va_list ap; 154 155 va_start (ap, fmt); 156 sim_io_eprintf (sd, "%s", sim_cpu_msg_prefix (cpu)); 157 sim_io_evprintf (sd, fmt, ap); 158 va_end (ap); 159 } 160 161 /* Turn VALUE into a string with commas. */ 162 163 char * 164 sim_add_commas (char *buf, int sizeof_buf, unsigned long value) 165 { 166 int comma = 3; 167 char *endbuf = buf + sizeof_buf - 1; 168 169 *--endbuf = '\0'; 170 do { 171 if (comma-- == 0) 172 { 173 *--endbuf = ','; 174 comma = 2; 175 } 176 177 *--endbuf = (value % 10) + '0'; 178 } while ((value /= 10) != 0); 179 180 return endbuf; 181 } 182 183 /* Analyze PROG_NAME/PROG_BFD and set these fields in the state struct: 184 STATE_ARCHITECTURE, if not set already and can be determined from the bfd 185 STATE_PROG_BFD 186 STATE_START_ADDR 187 STATE_TEXT_SECTION 188 STATE_TEXT_START 189 STATE_TEXT_END 190 191 PROG_NAME is the file name of the executable or NULL. 192 PROG_BFD is its bfd or NULL. 193 194 If both PROG_NAME and PROG_BFD are NULL, this function returns immediately. 195 If PROG_BFD is not NULL, PROG_NAME is ignored. 196 197 Implicit inputs: STATE_MY_NAME(sd), STATE_TARGET(sd), 198 STATE_ARCHITECTURE(sd). 199 200 A new bfd is created so the app isn't required to keep its copy of the 201 bfd open. */ 202 203 SIM_RC 204 sim_analyze_program (SIM_DESC sd, const char *prog_name, bfd *prog_bfd) 205 { 206 asection *s; 207 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 208 209 if (prog_bfd != NULL) 210 { 211 if (prog_bfd == STATE_PROG_BFD (sd)) 212 /* already analyzed */ 213 return SIM_RC_OK; 214 else 215 /* duplicate needed, save the name of the file to be re-opened */ 216 prog_name = bfd_get_filename (prog_bfd); 217 } 218 219 /* do we need to duplicate anything? */ 220 if (prog_name == NULL) 221 return SIM_RC_OK; 222 223 /* open a new copy of the prog_bfd */ 224 prog_bfd = bfd_openr (prog_name, STATE_TARGET (sd)); 225 if (prog_bfd == NULL) 226 { 227 sim_io_eprintf (sd, "%s: can't open \"%s\": %s\n", 228 STATE_MY_NAME (sd), 229 prog_name, 230 bfd_errmsg (bfd_get_error ())); 231 return SIM_RC_FAIL; 232 } 233 if (!bfd_check_format (prog_bfd, bfd_object)) 234 { 235 sim_io_eprintf (sd, "%s: \"%s\" is not an object file: %s\n", 236 STATE_MY_NAME (sd), 237 prog_name, 238 bfd_errmsg (bfd_get_error ())); 239 bfd_close (prog_bfd); 240 return SIM_RC_FAIL; 241 } 242 if (STATE_ARCHITECTURE (sd) != NULL) 243 bfd_set_arch_info (prog_bfd, STATE_ARCHITECTURE (sd)); 244 else 245 { 246 if (bfd_get_arch (prog_bfd) != bfd_arch_unknown 247 && bfd_get_arch (prog_bfd) != bfd_arch_obscure) 248 { 249 STATE_ARCHITECTURE (sd) = bfd_get_arch_info (prog_bfd); 250 } 251 } 252 253 /* update the sim structure */ 254 if (STATE_PROG_BFD (sd) != NULL) 255 bfd_close (STATE_PROG_BFD (sd)); 256 STATE_PROG_BFD (sd) = prog_bfd; 257 STATE_START_ADDR (sd) = bfd_get_start_address (prog_bfd); 258 259 for (s = prog_bfd->sections; s; s = s->next) 260 if (strcmp (bfd_section_name (s), ".text") == 0) 261 { 262 STATE_TEXT_SECTION (sd) = s; 263 STATE_TEXT_START (sd) = bfd_section_vma (s); 264 STATE_TEXT_END (sd) = STATE_TEXT_START (sd) + bfd_section_size (s); 265 break; 266 } 267 268 bfd_cache_close (prog_bfd); 269 270 return SIM_RC_OK; 271 } 272 273 /* Simulator timing support. */ 274 275 /* Called before sim_elapsed_time_since to get a reference point. */ 276 277 SIM_ELAPSED_TIME 278 sim_elapsed_time_get (void) 279 { 280 #ifdef HAVE_GETRUSAGE 281 struct rusage mytime; 282 if (getrusage (RUSAGE_SELF, &mytime) == 0) 283 return 1 + (SIM_ELAPSED_TIME) (((double) mytime.ru_utime.tv_sec * 1000) + (((double) mytime.ru_utime.tv_usec + 500) / 1000)); 284 return 1; 285 #else 286 #ifdef HAVE_TIME 287 return 1 + (SIM_ELAPSED_TIME) time ((time_t) 0); 288 #else 289 return 1; 290 #endif 291 #endif 292 } 293 294 /* Return the elapsed time in milliseconds since START. 295 The actual time may be cpu usage (preferred) or wall clock. */ 296 297 unsigned long 298 sim_elapsed_time_since (SIM_ELAPSED_TIME start) 299 { 300 #ifdef HAVE_GETRUSAGE 301 return sim_elapsed_time_get () - start; 302 #else 303 #ifdef HAVE_TIME 304 return (sim_elapsed_time_get () - start) * 1000; 305 #else 306 return 0; 307 #endif 308 #endif 309 } 310 311 312 313 /* do_command but with printf style formatting of the arguments */ 314 void 315 sim_do_commandf (SIM_DESC sd, 316 const char *fmt, 317 ...) 318 { 319 va_list ap; 320 char *buf; 321 int ret; 322 323 va_start (ap, fmt); 324 ret = vasprintf (&buf, fmt, ap); 325 va_end (ap); 326 327 if (ret < 0) 328 { 329 sim_io_eprintf (sd, "%s: asprintf failed for `%s'\n", 330 STATE_MY_NAME (sd), fmt); 331 return; 332 } 333 334 sim_do_command (sd, buf); 335 free (buf); 336 } 337 338 339 /* sim-basics.h defines a number of enumerations, convert each of them 340 to a string representation */ 341 const char * 342 map_to_str (unsigned map) 343 { 344 switch (map) 345 { 346 case read_map: return "read"; 347 case write_map: return "write"; 348 case exec_map: return "exec"; 349 case io_map: return "io"; 350 default: 351 { 352 static char str[16]; 353 snprintf (str, sizeof(str), "(%ld)", (long) map); 354 return str; 355 } 356 } 357 } 358 359 const char * 360 access_to_str (unsigned access) 361 { 362 switch (access) 363 { 364 case access_invalid: return "invalid"; 365 case access_read: return "read"; 366 case access_write: return "write"; 367 case access_exec: return "exec"; 368 case access_io: return "io"; 369 case access_read_write: return "read_write"; 370 case access_read_exec: return "read_exec"; 371 case access_write_exec: return "write_exec"; 372 case access_read_write_exec: return "read_write_exec"; 373 case access_read_io: return "read_io"; 374 case access_write_io: return "write_io"; 375 case access_read_write_io: return "read_write_io"; 376 case access_exec_io: return "exec_io"; 377 case access_read_exec_io: return "read_exec_io"; 378 case access_write_exec_io: return "write_exec_io"; 379 case access_read_write_exec_io: return "read_write_exec_io"; 380 default: 381 { 382 static char str[16]; 383 snprintf (str, sizeof(str), "(%ld)", (long) access); 384 return str; 385 } 386 } 387 } 388 389 const char * 390 transfer_to_str (unsigned transfer) 391 { 392 switch (transfer) 393 { 394 case read_transfer: return "read"; 395 case write_transfer: return "write"; 396 default: return "(error)"; 397 } 398 } 399