source: trunk/IPs/systemC/shared/loadexec.c @ 47

Last change on this file since 47 was 2, checked in by kane, 18 years ago

Import Morpheo

File size: 3.7 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.1.1.1  2006/09/24 23:09:24  kane
9 * Initalisation de l'arborescence CVS
10 *
11 * Revision 1.1  2005/09/20 20:43:43  kane
12 * Init CVS
13 *
14 * Revision 1.1  2003/03/10 10:38:05  fred
15 * Adding the bfd loader for good.
16 *
17 */
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22#include <bfd.h>
23
24#ifndef TRUE
25#define TRUE true
26#endif
27
28#ifndef FALSE
29#define FALSE false
30#endif
31
32/* Loading the sections sections of file file into the array
33 * pointed to by emem.
34 * esize is the expected size, but it can be modified by the function if it too
35 * small for the sections
36 * All sizes and addresses are given in bytes
37 * eoffset is the address of the section with the lowest address among
38 * all required sections.
39 * Code should be self explanatory once you've read the 230 pages of
40 * the BFD documentation :) */
41
42typedef struct raminfo {
43  void *mem;
44  unsigned int  size;
45  unsigned int  ladr;
46  unsigned int  hadr;
47  const char *file;
48  const char **sections;
49} raminfo;
50
51static void bindsection(bfd *exec, asection *sect, PTR x)
52{
53   int i;
54   raminfo *rinfo = x; 
55
56   for (i = 0; rinfo->sections[i]; i++)
57      if (!strcmp(sect->name, rinfo->sections[i]))
58         break;
59   if (!rinfo->sections[i])
60      return;
61
62   if ((sect->flags & SEC_LOAD) && !(sect->flags & SEC_IN_MEMORY)) {
63      bfd_get_section_contents(exec, sect,
64                               rinfo->mem + (sect->vma - rinfo->ladr),
65                               0, bfd_section_size(exec, sect));
66      sect->contents = rinfo->mem;
67   }
68}
69
70static void sectionssize(bfd *exec, asection *sect, PTR x)
71{
72   int i;
73   raminfo *rinfo = x; 
74
75   for (i = 0; rinfo->sections[i]; i++)
76      if (!strcmp(sect->name, rinfo->sections[i]))
77         break;
78   if (!rinfo->sections[i])
79      return;
80
81   rinfo->size += bfd_section_size(exec, sect);
82   rinfo->ladr  = sect->vma < rinfo->ladr ? sect->vma : rinfo->ladr;
83   rinfo->hadr  = sect->vma + rinfo->size > rinfo->hadr ?
84                  sect->vma + rinfo->size : rinfo->hadr;
85}
86
87void loadexec(void **emem, int *esize, int *eoffset, const char *file, const char **sections)
88{
89  bfd      *exec;
90  static   int x;
91  int      i;
92  raminfo  ringo;
93 
94   if (!x)
95      bfd_init();
96
97   exec = bfd_openr(file, NULL);
98
99   if (!exec) {
100      fprintf(stderr, "Cannot open File '%s'\n", file);
101      exit(1);
102   }
103
104   if (bfd_check_format(exec, bfd_object) != TRUE && !(exec->flags & EXEC_P)) {
105      fprintf(stderr, "File %s is not an executable file\n",
106                       bfd_get_filename(exec));
107      exit(1);
108   }
109
110#if 1
111   printf("Loading sections ");
112   for (i = 0; sections[i]; i++)
113      printf("%s%s", sections[i], sections[i+1] ? ", " : " ");
114   printf("from \"%s\"\n",bfd_get_filename(exec));
115   //printf("of executable '%s' for '%s' architecture in format '%s'\n",
116   //        bfd_get_filename(exec), bfd_printable_name(exec), exec->xvec->name);
117#endif
118
119   /* Set input parameters to bindsection */
120   ringo.file     = file;
121   ringo.sections = sections;
122   ringo.size     = 0;
123   ringo.ladr     = ~0;
124   ringo.hadr     = 0;
125   bfd_map_over_sections(exec, sectionssize, &ringo);
126   /* Get output parameters from sectionssize */
127   if (ringo.size < ringo.hadr - ringo.ladr)
128      ringo.size = ringo.hadr - ringo.ladr;
129   *esize         = ringo.size > *esize ? ringo.size : *esize;
130   *eoffset       = ringo.ladr;
131   ringo.mem      = malloc(*esize * sizeof(char));
132   /* Start over again from the start of the memory */
133   bfd_map_over_sections(exec, bindsection, &ringo);
134   /* Get output parameters from bindsection */
135
136   *emem          = ringo.mem;
137
138   if (bfd_close(exec) == FALSE) {
139      bfd_perror(exec->filename);
140      exit(1);
141   }
142}
Note: See TracBrowser for help on using the repository browser.