* sim-utils.c (sim_add_commas): New function.
[external/binutils.git] / sim / common / sim-utils.c
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"
23 #ifdef HAVE_STDLIB_H
24 #include <stdlib.h>
25 #endif
26 #ifdef HAVE_TIME_H
27 #include <time.h>
28 #endif
29 #ifdef HAVE_SYS_TIME_H
30 #include <sys/time.h> /* needed by sys/resource.h */
31 #endif
32 #ifdef HAVE_SYS_RESOURCE_H
33 #include <sys/resource.h>
34 #endif
35 #include "libiberty.h"
36 #include "bfd.h"
37
38 /* Global pointer to all state data.
39    Set by sim_resume.  */
40 struct sim_state *current_state;
41
42 /* Allocate zero filled memory with xmalloc.  */
43
44 void *
45 zalloc (unsigned long size)
46 {
47   void *memory = (void *) xmalloc (size);
48   memset (memory, 0, size);
49   return memory;
50 }
51
52 void
53 zfree (void *data)
54 {
55   free (data);
56 }
57
58 /* Allocate a sim_state struct.  */
59
60 SIM_DESC
61 sim_state_alloc (void)
62 {
63   SIM_DESC sd = zalloc (sizeof (struct sim_state));
64   sd->base.magic = SIM_MAGIC_NUMBER;
65   return sd;
66 }
67
68 /* Free a sim_state struct.  */
69
70 void
71 sim_state_free (SIM_DESC sd)
72 {
73   ASSERT (sd->base.magic == SIM_MAGIC_NUMBER);
74   zfree (sd);
75 }
76
77 /* Turn VALUE into a string with commas.  */
78
79 char *
80 sim_add_commas (char *buf, int sizeof_buf, unsigned long value)
81 {
82   int comma = 3;
83   char *endbuf = buf + sizeof_buf - 1;
84
85   *--endbuf = '\0';
86   do {
87     if (comma-- == 0)
88       {
89         *--endbuf = ',';
90         comma = 2;
91       }
92
93     *--endbuf = (value % 10) + '0';
94   } while ((value /= 10) != 0);
95
96   return endbuf;
97 }
98
99 /* Make a copy of ARGV.
100    This can also be used to copy the environment vector.
101    The result is a pointer to the malloc'd copy or NULL if insufficient
102    memory available.  */
103
104 char **
105 sim_copy_argv (argv)
106      char **argv;
107 {
108   int i,argc,len;
109   char **copy,*p;
110
111   argc = len = 0;
112   if (argv)
113     {
114       for ( ; argv[argc]; ++argc)
115         len += strlen (argv[argc]) + 1;
116     }
117
118   copy = (char **) malloc ((argc + 1) * sizeof (char *) + len);
119   if (copy == NULL)
120     return NULL;
121
122   p = (char *) copy + (argc + 1) * sizeof (char *);
123   for (i = 0; i < argc; ++i)
124     {
125       copy[i] = p;
126       strcpy (p, argv[i]);
127       p += strlen (argv[i]) + 1;
128     }
129   copy[argc] = 0;
130
131   return copy;
132 }
133
134 /* Analyze a bfd and set various fields in the state struct.  */
135
136 void
137 sim_analyze_program (sd, prog_bfd)
138      SIM_DESC sd;
139      bfd *prog_bfd;
140 {
141   asection *s;
142
143   STATE_PROG_BFD (sd) = prog_bfd;
144   STATE_START_ADDR (sd) = bfd_get_start_address (prog_bfd);
145
146   for (s = prog_bfd->sections; s; s = s->next)
147     if (strcmp (bfd_get_section_name (prog_bfd, s), ".text") == 0)
148       {
149         STATE_TEXT_SECTION (sd) = s;
150         STATE_TEXT_START (sd) = bfd_get_section_vma (prog_bfd, s);
151         STATE_TEXT_END (sd) = STATE_TEXT_START (sd) + bfd_section_size (prog_bfd, s);
152         break;
153       }
154 }
155 \f
156 /* Simulator timing support.  */
157
158 /* Called before sim_elapsed_time_since to get a reference point.  */
159
160 SIM_ELAPSED_TIME
161 sim_elapsed_time_get ()
162 {
163 #ifdef HAVE_GETRUSAGE
164   struct rusage mytime;
165   if (getrusage (RUSAGE_SELF, &mytime) == 0)
166     return (SIM_ELAPSED_TIME) (((double) mytime.ru_utime.tv_sec * 1000) + (((double) mytime.ru_utime.tv_usec + 500) / 1000));
167   return 0;
168 #else
169 #ifdef HAVE_TIME
170   return (SIM_ELAPSED_TIME) time ((time_t) 0);
171 #else
172   return 0;
173 #endif
174 #endif
175 }
176
177 /* Return the elapsed time in milliseconds since START.
178    The actual time may be cpu usage (prefered) or wall clock.  */
179
180 unsigned long
181 sim_elapsed_time_since (start)
182      SIM_ELAPSED_TIME start;
183 {
184 #ifdef HAVE_GETRUSAGE
185   return sim_elapsed_time_get () - start;
186 #else
187 #ifdef HAVE_TIME
188   return (sim_elapsed_time_get () - start) * 1000;
189 #else
190   return 0;
191 #endif
192 #endif
193 }