Commit | Line | Data |
---|---|---|
ba65b2f4 DE |
1 | /* Miscellaneous simulator utilities. |
2 | Copyright (C) 1997 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 2, or (at your option) | |
10 | 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 along | |
18 | with this program; if not, write to the Free Software Foundation, Inc., | |
19 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
20 | ||
21 | #include "sim-main.h" | |
22 | #include "sim-assert.h" | |
d07dddd2 | 23 | |
ba65b2f4 DE |
24 | #ifdef HAVE_STDLIB_H |
25 | #include <stdlib.h> | |
26 | #endif | |
d07dddd2 | 27 | |
2317a499 DE |
28 | #ifdef HAVE_TIME_H |
29 | #include <time.h> | |
30 | #endif | |
d07dddd2 | 31 | |
2317a499 DE |
32 | #ifdef HAVE_SYS_TIME_H |
33 | #include <sys/time.h> /* needed by sys/resource.h */ | |
34 | #endif | |
d07dddd2 | 35 | |
2317a499 DE |
36 | #ifdef HAVE_SYS_RESOURCE_H |
37 | #include <sys/resource.h> | |
38 | #endif | |
d07dddd2 AC |
39 | |
40 | #ifdef HAVE_STRING_H | |
41 | #include <string.h> | |
42 | #else | |
43 | #ifdef HAVE_STRINGS_H | |
44 | #include <strings.h> | |
45 | #endif | |
46 | #endif | |
47 | ||
ba65b2f4 DE |
48 | #include "libiberty.h" |
49 | #include "bfd.h" | |
d07dddd2 | 50 | #include "sim-utils.h" |
ba65b2f4 DE |
51 | |
52 | /* Global pointer to all state data. | |
53 | Set by sim_resume. */ | |
54 | struct sim_state *current_state; | |
55 | ||
4b2a6aed AC |
56 | /* Allocate zero filled memory with xmalloc - xmalloc aborts of the |
57 | allocation fails. */ | |
ba65b2f4 DE |
58 | |
59 | void * | |
60 | zalloc (unsigned long size) | |
61 | { | |
62 | void *memory = (void *) xmalloc (size); | |
63 | memset (memory, 0, size); | |
64 | return memory; | |
65 | } | |
66 | ||
67 | void | |
68 | zfree (void *data) | |
69 | { | |
70 | free (data); | |
71 | } | |
72 | ||
73 | /* Allocate a sim_state struct. */ | |
74 | ||
75 | SIM_DESC | |
4b2a6aed AC |
76 | sim_state_alloc (SIM_OPEN_KIND kind, |
77 | host_callback *callback) | |
ba65b2f4 | 78 | { |
4b2a6aed AC |
79 | int cpu_nr; |
80 | SIM_DESC sd = ZALLOC (struct sim_state); | |
81 | STATE_MAGIC (sd) = SIM_MAGIC_NUMBER; | |
82 | STATE_CALLBACK (sd) = callback; | |
83 | STATE_OPEN_KIND (sd) = kind; | |
84 | for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++) | |
85 | CPU_STATE (STATE_CPU (sd, cpu_nr)) = sd; | |
ba65b2f4 DE |
86 | return sd; |
87 | } | |
88 | ||
89 | /* Free a sim_state struct. */ | |
90 | ||
91 | void | |
92 | sim_state_free (SIM_DESC sd) | |
93 | { | |
94 | ASSERT (sd->base.magic == SIM_MAGIC_NUMBER); | |
95 | zfree (sd); | |
96 | } | |
97 | ||
2317a499 DE |
98 | /* Turn VALUE into a string with commas. */ |
99 | ||
100 | char * | |
101 | sim_add_commas (char *buf, int sizeof_buf, unsigned long value) | |
102 | { | |
103 | int comma = 3; | |
104 | char *endbuf = buf + sizeof_buf - 1; | |
105 | ||
106 | *--endbuf = '\0'; | |
107 | do { | |
108 | if (comma-- == 0) | |
109 | { | |
110 | *--endbuf = ','; | |
111 | comma = 2; | |
112 | } | |
113 | ||
114 | *--endbuf = (value % 10) + '0'; | |
115 | } while ((value /= 10) != 0); | |
116 | ||
117 | return endbuf; | |
118 | } | |
119 | ||
fafce69a AC |
120 | /* Analyze a prog_name/prog_bfd and set various fields in the state |
121 | struct. */ | |
ba65b2f4 | 122 | |
fafce69a AC |
123 | SIM_RC |
124 | sim_analyze_program (sd, prog_name, prog_bfd) | |
ba65b2f4 | 125 | SIM_DESC sd; |
fafce69a | 126 | char *prog_name; |
ba65b2f4 DE |
127 | bfd *prog_bfd; |
128 | { | |
129 | asection *s; | |
d07dddd2 | 130 | SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); |
fafce69a AC |
131 | |
132 | if (prog_bfd != NULL) | |
133 | { | |
134 | if (prog_bfd == STATE_PROG_BFD (sd)) | |
135 | /* already analyzed */ | |
136 | return SIM_RC_OK; | |
137 | else | |
138 | /* duplicate needed, save the name of the file to be re-opened */ | |
139 | prog_name = bfd_get_filename (prog_bfd); | |
140 | } | |
141 | ||
142 | /* do we need to duplicate anything? */ | |
143 | if (prog_name == NULL) | |
144 | return SIM_RC_OK; | |
145 | ||
146 | /* open a new copy of the prog_bfd */ | |
18c319ae | 147 | prog_bfd = bfd_openr (prog_name, STATE_TARGET (sd)); |
fafce69a AC |
148 | if (prog_bfd == NULL) |
149 | { | |
150 | sim_io_eprintf (sd, "%s: can't open \"%s\": %s\n", | |
151 | STATE_MY_NAME (sd), | |
152 | prog_name, | |
153 | bfd_errmsg (bfd_get_error ())); | |
154 | return SIM_RC_FAIL; | |
155 | } | |
156 | if (!bfd_check_format (prog_bfd, bfd_object)) | |
157 | { | |
158 | sim_io_eprintf (sd, "%s: \"%s\" is not an object file: %s\n", | |
159 | STATE_MY_NAME (sd), | |
160 | prog_name, | |
161 | bfd_errmsg (bfd_get_error ())); | |
162 | bfd_close (prog_bfd); | |
163 | return SIM_RC_FAIL; | |
164 | } | |
18c319ae AC |
165 | if (STATE_ARCHITECTURE (sd) != NULL) |
166 | bfd_set_arch_info (prog_bfd, STATE_ARCHITECTURE (sd)); | |
fafce69a AC |
167 | |
168 | /* update the sim structure */ | |
169 | if (STATE_PROG_BFD (sd) != NULL) | |
170 | bfd_close (STATE_PROG_BFD (sd)); | |
ba65b2f4 DE |
171 | STATE_PROG_BFD (sd) = prog_bfd; |
172 | STATE_START_ADDR (sd) = bfd_get_start_address (prog_bfd); | |
173 | ||
174 | for (s = prog_bfd->sections; s; s = s->next) | |
175 | if (strcmp (bfd_get_section_name (prog_bfd, s), ".text") == 0) | |
176 | { | |
177 | STATE_TEXT_SECTION (sd) = s; | |
178 | STATE_TEXT_START (sd) = bfd_get_section_vma (prog_bfd, s); | |
179 | STATE_TEXT_END (sd) = STATE_TEXT_START (sd) + bfd_section_size (prog_bfd, s); | |
180 | break; | |
181 | } | |
fafce69a AC |
182 | |
183 | return SIM_RC_OK; | |
ba65b2f4 | 184 | } |
2317a499 DE |
185 | \f |
186 | /* Simulator timing support. */ | |
187 | ||
188 | /* Called before sim_elapsed_time_since to get a reference point. */ | |
189 | ||
190 | SIM_ELAPSED_TIME | |
191 | sim_elapsed_time_get () | |
192 | { | |
193 | #ifdef HAVE_GETRUSAGE | |
194 | struct rusage mytime; | |
195 | if (getrusage (RUSAGE_SELF, &mytime) == 0) | |
a34abff8 AC |
196 | return 1 + (SIM_ELAPSED_TIME) (((double) mytime.ru_utime.tv_sec * 1000) + (((double) mytime.ru_utime.tv_usec + 500) / 1000)); |
197 | return 1; | |
2317a499 DE |
198 | #else |
199 | #ifdef HAVE_TIME | |
a34abff8 | 200 | return 1 + (SIM_ELAPSED_TIME) time ((time_t) 0); |
2317a499 | 201 | #else |
a34abff8 | 202 | return 1; |
2317a499 DE |
203 | #endif |
204 | #endif | |
205 | } | |
206 | ||
207 | /* Return the elapsed time in milliseconds since START. | |
208 | The actual time may be cpu usage (prefered) or wall clock. */ | |
209 | ||
210 | unsigned long | |
211 | sim_elapsed_time_since (start) | |
212 | SIM_ELAPSED_TIME start; | |
213 | { | |
214 | #ifdef HAVE_GETRUSAGE | |
215 | return sim_elapsed_time_get () - start; | |
216 | #else | |
217 | #ifdef HAVE_TIME | |
218 | return (sim_elapsed_time_get () - start) * 1000; | |
219 | #else | |
220 | return 0; | |
221 | #endif | |
222 | #endif | |
223 | } |