OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [sim/] [rx/] [load.c] - Blame information for rev 859

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* load.c --- loading object files into the RX simulator.
2
 
3
Copyright (C) 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4
Contributed by Red Hat, Inc.
5
 
6
This file is part of the GNU simulators.
7
 
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 3 of the License, or
11
(at your option) any later version.
12
 
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
GNU General Public License for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
 
21
 
22
#include <stdlib.h>
23
#include <stdio.h>
24
#include <string.h>
25
 
26
#include "bfd.h"
27
#include "libbfd.h"
28
#include "cpu.h"
29
#include "mem.h"
30
#include "elf/internal.h"
31
#include "elf/common.h"
32
 
33
/* A note about endianness and swapping...
34
 
35
   The RX chip is CISC-like in that the opcodes are variable length
36
   and are read as a stream of bytes.  However, the chip itself shares
37
   the code prefetch block with the data fetch block, so when it's
38
   configured for big endian mode, the memory fetched for opcodes is
39
   word-swapped.  To compensate for this, the ELF file has the code
40
   sections pre-swapped.  Our BFD knows this, and for the convenience
41
   of all the other tools, hides this swapping at a very low level.
42
   I.e.  it swaps words on the way out and on the way back in.
43
 
44
   Fortunately the iovector routines are unaffected by this, so we
45
   can use them to read in the segments directly, without having
46
   to worry about byte swapping anything.
47
 
48
   However, our opcode decoder and disassemblers need to swap the data
49
   after reading it from the chip memory, just like the chip does.
50
   All in all, the code words are swapped four times between the
51
   assembler and our decoder.
52
 
53
   If the chip is running in little-endian mode, no swapping is done
54
   anywhere.  Note also that the *operands* within opcodes are always
55
   encoded in little-endian format.  */
56
 
57
void
58
rx_load (bfd *prog)
59
{
60
  unsigned long highest_addr_loaded = 0;
61
  Elf_Internal_Phdr * phdrs;
62
  long sizeof_phdrs;
63
  int num_headers;
64
  int i;
65
 
66
  rx_big_endian = bfd_big_endian (prog);
67
 
68
  /* Note we load by ELF program header not by BFD sections.
69
     This is because BFD sections get their information from
70
     the ELF section structure, which only includes a VMA value
71
     and not an LMA value.  */
72
  sizeof_phdrs = bfd_get_elf_phdr_upper_bound (prog);
73
  if (sizeof_phdrs == 0)
74
    {
75
      fprintf (stderr, "Failed to get size of program headers\n");
76
      return;
77
    }
78
  phdrs = malloc (sizeof_phdrs);
79
  if (phdrs == NULL)
80
    {
81
      fprintf (stderr, "Failed allocate memory to hold program headers\n");
82
      return;
83
    }
84
  num_headers = bfd_get_elf_phdrs (prog, phdrs);
85
  if (num_headers < 1)
86
    {
87
      fprintf (stderr, "Failed to read program headers\n");
88
      return;
89
    }
90
 
91
  for (i = 0; i < num_headers; i++)
92
    {
93
      Elf_Internal_Phdr * p = phdrs + i;
94
      char *buf;
95
      bfd_vma size;
96
      bfd_vma base;
97
      file_ptr offset;
98
 
99
      size = p->p_filesz;
100
      if (size <= 0)
101
        continue;
102
 
103
      base = p->p_paddr;
104
      if (verbose > 1)
105
        fprintf (stderr, "[load segment: lma=%08x vma=%08x size=%08x]\n",
106
                 (int) base, (int) p->p_vaddr, (int) size);
107
 
108
      buf = malloc (size);
109
      if (buf == NULL)
110
        {
111
          fprintf (stderr, "Failed to allocate buffer to hold program segment\n");
112
          continue;
113
        }
114
 
115
      offset = p->p_offset;
116
      if (prog->iovec->bseek (prog, offset, SEEK_SET) != 0)
117
        {
118
          fprintf (stderr, "Failed to seek to offset %lx\n", (long) offset);
119
          continue;
120
        }
121
      if (prog->iovec->bread (prog, buf, size) != size)
122
        {
123
          fprintf (stderr, "Failed to read %lx bytes\n", size);
124
          continue;
125
        }
126
 
127
      mem_put_blk (base, buf, size);
128
      free (buf);
129
      if (highest_addr_loaded < base + size - 1 && size >= 4)
130
        highest_addr_loaded = base + size - 1;
131
    }
132
 
133
  free (phdrs);
134
 
135
  regs.r_pc = prog->start_address;
136
 
137
  if (strcmp (bfd_get_target (prog), "srec") == 0
138
      || regs.r_pc == 0)
139
    {
140
      regs.r_pc = mem_get_si (0xfffffffc);
141
      heaptop = heapbottom = 0;
142
    }
143
 
144
  if (verbose > 1)
145
    fprintf (stderr, "[start pc=%08x %s]\n",
146
             (unsigned int) regs.r_pc,
147
             rx_big_endian ? "BE" : "LE");
148
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.