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

Last change on this file since 106 was 81, checked in by rosiere, 17 years ago
  • Finish Environment (and test)
  • Continue predictor_unit
  • Add external tools
  • svn keyword "Id" set
  • Property svn:keywords set to Id
File size: 4.1 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
36#ifndef TRUE
37#define TRUE true
38#endif
39
40#ifndef FALSE
41#define FALSE false
42#endif
43
44/* Loading the sections sections of file file into the array
45 * pointed to by emem.
46 * esize is the expected size, but it can be modified by the function if it too
47 * small for the sections
48 * All sizes and addresses are given in bytes
49 * eoffset is the address of the section with the lowest address among
50 * all required sections.
51 * Code should be self explanatory once you've read the 230 pages of
52 * the BFD documentation :) */
53
54typedef struct raminfo {
55  void *mem;
56  unsigned int  size;
57  unsigned int  ladr;
58  unsigned int  hadr;
59  const char *file;
60  const char **sections;
61} raminfo;
62
63static void bindsection(bfd *exec, asection *sect, PTR x)
64{
65   int i;
66   raminfo *rinfo = x; 
67
68   for (i = 0; rinfo->sections[i]; i++)
69      if (!strcmp(sect->name, rinfo->sections[i]))
70         break;
71   if (!rinfo->sections[i])
72      return;
73
74   if ((sect->flags & SEC_LOAD) && !(sect->flags & SEC_IN_MEMORY)) {
75      bfd_get_section_contents(exec, sect,
76                               rinfo->mem + (sect->lma - rinfo->ladr),
77                               0, bfd_section_size(exec, sect));
78      sect->contents = rinfo->mem;
79   }
80}
81
82static void sectionssize(bfd *exec, asection *sect, PTR x)
83{
84   int i;
85   raminfo *rinfo = x; 
86
87   for (i = 0; rinfo->sections[i]; i++)
88      if (!strcmp(sect->name, rinfo->sections[i]))
89         break;
90   if (!rinfo->sections[i])
91      return;
92
93   rinfo->size += bfd_section_size(exec, sect);
94   rinfo->ladr  = sect->lma < rinfo->ladr ? sect->lma : rinfo->ladr;
95   rinfo->hadr  = sect->lma + rinfo->size > rinfo->hadr ?
96                  sect->lma + rinfo->size : rinfo->hadr;
97}
98
99void loadexec(void **emem, int *esize, int *eoffset, const char *file, const char **sections)
100{
101  bfd      *exec;
102  static   int x;
103  int      i;
104  raminfo  ringo;
105
106   if (!x)
107      bfd_init();
108
109   exec = bfd_openr(file, NULL);
110
111   if (!exec) {
112      fprintf(stderr, "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      fprintf(stderr, "File %s is not an executable file\n",
118                       file); //bfd_get_filename(exec));
119      exit(1);
120   }
121
122#if 1
123   printf("Loading sections ");
124   for (i = 0; sections[i]; i++)
125      printf("%s%s", sections[i], sections[i+1] ? ", " : " ");
126   printf("from \"%s\"\n",bfd_get_filename(exec));
127   //printf("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   /* Start over again from the start of the memory */
145   bfd_map_over_sections(exec, bindsection, &ringo);
146   /* Get output parameters from bindsection */
147
148   *emem          = ringo.mem;
149
150   if (bfd_close(exec) == FALSE) {
151      bfd_perror(exec->filename);
152      exit(1);
153   }
154}
Note: See TracBrowser for help on using the repository browser.