source: trunk/IPs/systemC/Environment/Data/src/loadexec.c@ 134

Last change on this file since 134 was 134, checked in by rosiere, 17 years ago

1) valgrind fix
2) debug file on/off

  • Property svn:keywords set to Id
File size: 4.2 KB
Line 
1/*
2 * File : loadexec.c
3 * Author : Frédéric Pétrot
4 *
5 * Load an executable into an array using the GNU BFD
6 *
7 * $Log: loadexec.c,v $
8 * Revision 1.3 2006/06/08 14:32:41 nipo
9 * Use _loading_ memory address rather than _virtual_ memory address when
10 * loading objects.
11 *
12 * Patch from Alexandre Becoulet
13 *
14 * Revision 1.2 2006/02/21 10:37:40 buchmann
15 * Changes :
16 * - random optimizations
17 * - now uses conditional expressions instead of if statements
18 * - disables some useless assignments
19 * - now uses shift operators instead of arithmetic operators
20 * - fix documentations
21 *
22 * Revision 1.1.1.1 2005/01/27 13:42:45 wahid
23 * First project import
24 * Wahid
25 *
26 * Revision 1.1 2003/03/10 10:38:05 fred
27 * Adding the bfd loader for good.
28 *
29 */
30
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <bfd.h>
35#include "../../Common/include/Debug.h"
36
37#ifndef TRUE
38#define TRUE true
39#endif
40
41#ifndef FALSE
42#define FALSE false
43#endif
44
45/* Loading the sections sections of file file into the array
46 * pointed to by emem.
47 * esize is the expected size, but it can be modified by the function if it too
48 * small for the sections
49 * All sizes and addresses are given in bytes
50 * eoffset is the address of the section with the lowest address among
51 * all required sections.
52 * Code should be self explanatory once you've read the 230 pages of
53 * the BFD documentation :) */
54
55typedef struct raminfo {
56 void *mem;
57 unsigned int size;
58 unsigned int ladr;
59 unsigned int hadr;
60 const char *file;
61 const char **sections;
62} raminfo;
63
64static void bindsection(bfd *exec, asection *sect, PTR x)
65{
66 int i;
67 raminfo *rinfo = x;
68
69 for (i = 0; rinfo->sections[i]; i++)
70 if (!strcmp(sect->name, rinfo->sections[i]))
71 break;
72 if (!rinfo->sections[i])
73 return;
74
75 if ((sect->flags & SEC_LOAD) && !(sect->flags & SEC_IN_MEMORY)) {
76 bfd_get_section_contents(exec, sect,
77 rinfo->mem + (sect->lma - rinfo->ladr),
78 0, bfd_section_size(exec, sect));
79 sect->contents = rinfo->mem;
80 }
81}
82
83static void sectionssize(bfd *exec, asection *sect, PTR x)
84{
85 int i;
86 raminfo *rinfo = x;
87
88 for (i = 0; rinfo->sections[i]; i++)
89 if (!strcmp(sect->name, rinfo->sections[i]))
90 break;
91 if (!rinfo->sections[i])
92 return;
93
94 rinfo->size += bfd_section_size(exec, sect);
95 rinfo->ladr = sect->lma < rinfo->ladr ? sect->lma : rinfo->ladr;
96 rinfo->hadr = sect->lma + rinfo->size > rinfo->hadr ?
97 sect->lma + rinfo->size : rinfo->hadr;
98}
99
100void loadexec(void **emem, int *esize, int *eoffset, const char *file, const char **sections)
101{
102 bfd *exec;
103 static int x;
104 raminfo ringo;
105
106 if (!x)
107 bfd_init();
108
109 exec = bfd_openr(file, NULL);
110
111 if (!exec) {
112 cerr("Cannot open File '%s'\n", file);
113 exit(1);
114 }
115
116 if (bfd_check_format(exec, bfd_object) != TRUE && !(exec->flags & EXEC_P)) {
117 cerr("File %s is not an executable file\n",
118 file); //bfd_get_filename(exec));
119 exit(1);
120 }
121
122#if 0
123 cout("Loading sections ");
124 for (i = 0; sections[i]; i++)
125 __cout("%s%s", sections[i], ((sections[i+1]!=NULL)?", ":" "));
126 __cout("from \"%s\"\n",bfd_get_filename(exec));
127 //cout("of executable '%s' for '%s' architecture in format '%s'\n",
128 // bfd_get_filename(exec), bfd_printable_name(exec), exec->xvec->name);
129#endif
130
131 /* Set input parameters to bindsection */
132 ringo.file = file;
133 ringo.sections = sections;
134 ringo.size = 0;
135 ringo.ladr = ~0;
136 ringo.hadr = 0;
137 bfd_map_over_sections(exec, sectionssize, &ringo);
138 /* Get output parameters from sectionssize */
139 if (ringo.size < ringo.hadr - ringo.ladr)
140 ringo.size = ringo.hadr - ringo.ladr;
141 *esize = ringo.size > *esize ? ringo.size : *esize;
142 *eoffset = ringo.ladr;
143 ringo.mem = malloc(*esize * sizeof(char));
144
145 memset((void *)ringo.mem,0,*esize * sizeof(char));
146
147 /* Start over again from the start of the memory */
148 bfd_map_over_sections(exec, bindsection, &ringo);
149 /* Get output parameters from bindsection */
150
151 *emem = ringo.mem;
152
153 if (bfd_close(exec) == FALSE) {
154 bfd_perror(exec->filename);
155 exit(1);
156 }
157}
Note: See TracBrowser for help on using the repository browser.