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