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

Last change on this file was 138, checked in by rosiere, 14 years ago

1) add counters_t type for interface
2) fix in check load in load_store_unit
3) add parameters (but not yet implemented)
4) change environment and add script (distcc_env.sh ...)
5) add warning if an unser change rename flag with l.mtspr instruction
6) ...

  • Property svn:keywords set to Id
File size: 5.8 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     {
77/* #if 1 */
78/*        printf("  * bindsection : \n"); */
79/*        printf("    * exec         : %x\n",(int)exec); */
80/*        printf("    * sect         : %x\n",(int)sect); */
81/*        printf("    * size         : %d\n",(int)(rinfo->mem + (sect->lma - rinfo->ladr))); */
82/*        printf("      * mem        : %d\n",(int)rinfo->mem); */
83/*        printf("      * lma        : %d\n",(int)sect->lma); */
84/*        printf("      * ladr       : %d\n",(int)rinfo->ladr); */
85/*        fflush(stdout);        */
86/* #endif */
87
88       bfd_get_section_contents(exec,
89                                sect,
90                                rinfo->mem + (sect->lma - rinfo->ladr),
91                                0,
92                                bfd_section_size(exec, sect));
93       sect->contents = rinfo->mem;
94   }
95}
96
97static void sectionssize(bfd *exec, asection *sect, PTR x)
98{
99   int i;
100   raminfo *rinfo = x; 
101
102   for (i = 0; rinfo->sections[i]; i++)
103      if (!strcmp(sect->name, rinfo->sections[i]))
104         break;
105   if (!rinfo->sections[i])
106      return;
107
108/* #if 1 */
109/*    printf("  * sectionsize : \n"); */
110/*    printf("    * name         : %s\n",rinfo->sections[i]); */
111/*    printf("    * size (before): %d (%x)\n",rinfo->size,rinfo->size); */
112/*    printf("    * ladr (before): %d (%x)\n",rinfo->ladr,rinfo->ladr); */
113/*    printf("    * hadr (before): %d (%x)\n",rinfo->hadr,rinfo->hadr); */
114/* #endif */
115
116   rinfo->size += bfd_section_size(exec, sect);
117   rinfo->ladr  = sect->lma < rinfo->ladr ? sect->lma : rinfo->ladr;
118   rinfo->hadr  = sect->lma + rinfo->size > rinfo->hadr ?
119                  sect->lma + rinfo->size : rinfo->hadr;
120
121/* #if 1 */
122/*    printf("    * size (after ): %d (%x)\n",rinfo->size,rinfo->size); */
123/*    printf("    * ladr (after ): %d (%x)\n",rinfo->ladr,rinfo->ladr); */
124/*    printf("    * hadr (after ): %d (%x)\n",rinfo->hadr,rinfo->hadr); */
125/* #endif */
126
127}
128
129void loadexec(void **emem, int *esize, int *eoffset, const char *file, const char **sections)
130{
131  static   int x;
132  raminfo  ringo;
133
134   if (!x)
135      bfd_init();
136
137   bfd * exec = bfd_openr(file, NULL);
138
139   if (!exec) {
140      cerr("Cannot open File '%s'\n", file);
141      exit(1);
142   }
143
144   if (bfd_check_format(exec, bfd_object) != TRUE && !(exec->flags & EXEC_P)) {
145      cerr("File %s is not an executable file\n",
146            file); //bfd_get_filename(exec));
147      exit(1);
148   }
149
150/* #if 1 */
151/*    printf("  * Loading sections from \"%s\" :\n",bfd_get_filename(exec)); */
152/*    { */
153/*      int i; */
154/*      for (i = 0; sections[i]; i++) */
155/*        printf("    * %s\n", sections[i]); */
156/*    } */
157   
158/*    //cout("of executable '%s' for '%s' architecture in format '%s'\n", */
159/*    //        bfd_get_filename(exec), bfd_printable_name(exec), exec->xvec->name); */
160/* #endif */
161
162   /* Set input parameters to bindsection */
163   ringo.file     = file;
164   ringo.sections = sections;
165   ringo.size     = 0;
166   ringo.ladr     = ~0;
167   ringo.hadr     = 0;
168   ringo.mem      = NULL;
169
170   bfd_map_over_sections(exec, sectionssize, &ringo);
171
172/* #if 1 */
173/*    printf("  * Meminfo : \n"); */
174/*    printf("    * size         : %d (%x)\n",ringo.size,ringo.size); */
175/*    printf("    * esize        : %d (%x)\n",*esize,*esize); */
176/*    printf("    * ladr         : %d (%x)\n",ringo.ladr,ringo.ladr); */
177/*    printf("    * hadr         : %d (%x)\n",ringo.hadr,ringo.hadr); */
178/* #endif */
179
180   /* Get output parameters from sectionssize */
181   if (ringo.size < ringo.hadr - ringo.ladr)
182      ringo.size = ringo.hadr - ringo.ladr;
183   *esize         = ringo.size > *esize ? ringo.size : *esize;
184   *eoffset       = ringo.ladr;
185   ringo.mem      = malloc(*esize * sizeof(char));
186
187   memset((void *)ringo.mem,0,*esize * sizeof(char));
188   
189   /* Start over again from the start of the memory */
190   bfd_map_over_sections(exec,
191                         bindsection,
192                         &ringo);
193   /* Get output parameters from bindsection */
194
195   *emem          = ringo.mem;
196
197   if (bfd_close(exec) == FALSE) {
198      bfd_perror(exec->filename);
199      exit(1);
200   }
201}
Note: See TracBrowser for help on using the repository browser.