OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [sim/] [common/] [sim-load.c] - Blame information for rev 26

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 jlechner
/* Utility to load a file into the simulator.
2
   Copyright (C) 1997, 1998, 2001, 2002, 2004, 2007, 2008
3
   Free Software Foundation, Inc.
4
 
5
This program is free software; you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation; either version 3 of the License, or
8
(at your option) any later version.
9
 
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU General Public License for more details.
14
 
15
You should have received a copy of the GNU General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
 
18
/* This is a standalone loader, independent of the sim-basic.h machinery,
19
   as it is used by simulators that don't use it [though that doesn't mean
20
   to suggest that they shouldn't :-)].  */
21
 
22
#ifdef HAVE_CONFIG_H
23
#include "cconfig.h"
24
#endif
25
#include "ansidecl.h"
26
#include <stdio.h> /* for NULL */
27
#include <stdarg.h>
28
#ifdef HAVE_STDLIB_H
29
#include <stdlib.h>
30
#endif
31
#include <time.h>
32
 
33
#include "sim-basics.h"
34
#include "bfd.h"
35
#include "sim-utils.h"
36
 
37
#include "gdb/callback.h"
38
#include "gdb/remote-sim.h"
39
 
40
static void eprintf PARAMS ((host_callback *, const char *, ...));
41
static void xprintf PARAMS ((host_callback *, const char *, ...));
42
static void report_transfer_performance
43
  PARAMS ((host_callback *, unsigned long, time_t, time_t));
44
static void xprintf_bfd_vma PARAMS ((host_callback *, bfd_vma));
45
 
46
/* Load program PROG into the simulator using the function DO_LOAD.
47
   If PROG_BFD is non-NULL, the file has already been opened.
48
   If VERBOSE_P is non-zero statistics are printed of each loaded section
49
   and the transfer rate (for consistency with gdb).
50
   If LMA_P is non-zero the program sections are loaded at the LMA
51
   rather than the VMA
52
   If this fails an error message is printed and NULL is returned.
53
   If it succeeds the bfd is returned.
54
   NOTE: For historical reasons, older hardware simulators incorrectly
55
   write the program sections at LMA interpreted as a virtual address.
56
   This is still accommodated for backward compatibility reasons. */
57
 
58
 
59
bfd *
60
sim_load_file (sd, myname, callback, prog, prog_bfd, verbose_p, lma_p, do_write)
61
     SIM_DESC sd;
62
     const char *myname;
63
     host_callback *callback;
64
     char *prog;
65
     bfd *prog_bfd;
66
     int verbose_p;
67
     int lma_p;
68
     sim_write_fn do_write;
69
{
70
  asection *s;
71
  /* Record separately as we don't want to close PROG_BFD if it was passed.  */
72
  bfd *result_bfd;
73
  time_t start_time = 0; /* Start and end times of download */
74
  time_t end_time = 0;
75
  unsigned long data_count = 0;  /* Number of bytes transferred to memory */
76
  int found_loadable_section;
77
 
78
  if (prog_bfd != NULL)
79
    result_bfd = prog_bfd;
80
  else
81
    {
82
      result_bfd = bfd_openr (prog, 0);
83
      if (result_bfd == NULL)
84
        {
85
          eprintf (callback, "%s: can't open \"%s\": %s\n",
86
                   myname, prog, bfd_errmsg (bfd_get_error ()));
87
          return NULL;
88
        }
89
    }
90
 
91
  if (!bfd_check_format (result_bfd, bfd_object))
92
    {
93
      eprintf (callback, "%s: \"%s\" is not an object file: %s\n",
94
               myname, prog, bfd_errmsg (bfd_get_error ()));
95
      /* Only close if we opened it.  */
96
      if (prog_bfd == NULL)
97
        bfd_close (result_bfd);
98
      return NULL;
99
    }
100
 
101
  if (verbose_p)
102
    start_time = time (NULL);
103
 
104
  found_loadable_section = 0;
105
  for (s = result_bfd->sections; s; s = s->next)
106
    {
107
      if (s->flags & SEC_LOAD)
108
        {
109
          bfd_size_type size;
110
 
111
          size = bfd_get_section_size (s);
112
          if (size > 0)
113
            {
114
              char *buffer;
115
              bfd_vma lma;
116
 
117
              buffer = malloc (size);
118
              if (buffer == NULL)
119
                {
120
                  eprintf (callback,
121
                           "%s: insufficient memory to load \"%s\"\n",
122
                           myname, prog);
123
                  /* Only close if we opened it.  */
124
                  if (prog_bfd == NULL)
125
                    bfd_close (result_bfd);
126
                  return NULL;
127
                }
128
              if (lma_p)
129
                lma = bfd_section_lma (result_bfd, s);
130
              else
131
                lma = bfd_section_vma (result_bfd, s);
132
              if (verbose_p)
133
                {
134
                  xprintf (callback, "Loading section %s, size 0x%lx %s ",
135
                           bfd_get_section_name (result_bfd, s),
136
                           (unsigned long) size,
137
                           (lma_p ? "lma" : "vma"));
138
                  xprintf_bfd_vma (callback, lma);
139
                  xprintf (callback, "\n");
140
                }
141
              data_count += size;
142
              bfd_get_section_contents (result_bfd, s, buffer, 0, size);
143
              do_write (sd, lma, buffer, size);
144
              found_loadable_section = 1;
145
              free (buffer);
146
            }
147
        }
148
    }
149
 
150
  if (!found_loadable_section)
151
    {
152
      eprintf (callback,
153
               "%s: no loadable sections \"%s\"\n",
154
               myname, prog);
155
      return NULL;
156
    }
157
 
158
  if (verbose_p)
159
    {
160
      end_time = time (NULL);
161
      xprintf (callback, "Start address ");
162
      xprintf_bfd_vma (callback, bfd_get_start_address (result_bfd));
163
      xprintf (callback, "\n");
164
      report_transfer_performance (callback, data_count, start_time, end_time);
165
    }
166
 
167
  bfd_cache_close (result_bfd);
168
 
169
  return result_bfd;
170
}
171
 
172
static void
173
xprintf VPARAMS ((host_callback *callback, const char *fmt, ...))
174
{
175
  va_list ap;
176
 
177
  VA_START (ap, fmt);
178
 
179
  (*callback->vprintf_filtered) (callback, fmt, ap);
180
 
181
  va_end (ap);
182
}
183
 
184
static void
185
eprintf VPARAMS ((host_callback *callback, const char *fmt, ...))
186
{
187
  va_list ap;
188
 
189
  VA_START (ap, fmt);
190
 
191
  (*callback->evprintf_filtered) (callback, fmt, ap);
192
 
193
  va_end (ap);
194
}
195
 
196
/* Report how fast the transfer went. */
197
 
198
static void
199
report_transfer_performance (callback, data_count, start_time, end_time)
200
     host_callback *callback;
201
     unsigned long data_count;
202
     time_t start_time, end_time;
203
{
204
  xprintf (callback, "Transfer rate: ");
205
  if (end_time != start_time)
206
    xprintf (callback, "%ld bits/sec",
207
             (data_count * 8) / (end_time - start_time));
208
  else
209
    xprintf (callback, "%ld bits in <1 sec", (data_count * 8));
210
  xprintf (callback, ".\n");
211
}
212
 
213
/* Print a bfd_vma.
214
   This is intended to handle the vagaries of 32 vs 64 bits, etc.  */
215
 
216
static void
217
xprintf_bfd_vma (callback, vma)
218
     host_callback *callback;
219
     bfd_vma vma;
220
{
221
  /* FIXME: for now */
222
  xprintf (callback, "0x%lx", (unsigned long) vma);
223
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.