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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [orpsocv2/] [bench/] [sysc/] [src/] [MemoryLoad.cpp] - Blame information for rev 178

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

Line No. Rev Author Line
1 51 julius
/* MemoryLoad.cpp -- Program load functions
2
 
3
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
4
   Copyright (C) 2008 Embecosm Limited
5
   Copyright (C) 2009 Julius Baxter, julius@orsoc.se
6
 
7
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
8
 
9
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
10
 
11
   This program is free software; you can redistribute it and/or modify it
12
   under the terms of the GNU General Public License as published by the Free
13
   Software Foundation; either version 3 of the License, or (at your option)
14
   any later version.
15
 
16
   This program is distributed in the hope that it will be useful, but WITHOUT
17
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
19
   more details.
20
 
21
   You should have received a copy of the GNU General Public License along
22
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
23
 
24
/* This program is commented throughout in a fashion suitable for processing
25
   with Doxygen. */
26
 
27
/* System includes */
28
#include <stdio.h>
29
#include <stdlib.h>
30
#include <string.h>
31
 
32
#include "MemoryLoad.h"
33
#include "OrpsocMain.h"
34
 
35
 
36
//! Constructor for the ORPSoC memory loader class
37
 
38
//! Initializes various values
39
 
40
//! @param[in] orpsoc  The SystemC Verilated ORPSoC instance
41
//! @param[in] accessor  Accessor class for this Verilated ORPSoC model
42
 
43
MemoryLoad::MemoryLoad
44
(
45
 OrpsocAccess             *_accessor
46
 )
47
{
48
  accessor = _accessor;
49
}       // MemoryAccess ()
50
 
51
 
52
/*---------------------------------------------------------------------------*/
53
/*!Copy a string with null termination
54
 
55
   This function is very similar to strncpy, except it null terminates the
56
   string. A global function also used by the CUC.
57
 
58
   @param[in] dst  The destination string
59
   @param[in] src  The source string
60
   @param[in] n    Number of chars to copy EXCLUDING the null terminator
61
                   (i.e. dst had better have room for n+1 chars)
62
 
63
   @return  A pointer to dst                                                 */
64
/*---------------------------------------------------------------------------*/
65
char *
66
MemoryLoad::strstrip (char       *dst,
67
                      const char *src,
68
                      int         n)
69
{
70
  strncpy (dst, src, n);
71
  *(dst + n) = '\0';
72
 
73
  return  dst;
74
 
75
}       /* strstrip () */
76
 
77
/*---------------------------------------------------------------------------*/
78
/*!Translate logical to physical addresses for the loader
79
 
80
   Used only by the simulator loader to translate logical addresses into
81
   physical.  If loadcode() is called with valid @c virtphy_transl pointer to
82
   a table of translations then translate() performs translation otherwise
83
   physical address is equal to logical.
84
 
85
   Currently NOT used
86
 
87
   @param[in] laddr       Logical address
88
   @param[in] breakpoint  Unused
89
 
90
   @return  The physical address                                             */
91
/*---------------------------------------------------------------------------*/
92
 oraddr_t
93
MemoryLoad::translate (oraddr_t  laddr,
94
           int      *breakpoint)
95
{
96
  /*
97
  int i;
98
 
99
  // No translation (i.e. when loading kernel into simulator)
100
  if (transl_table == 0)
101
    {
102
      return laddr;
103
    }
104
 
105
  // Try to find our translation in the table.
106
  for (i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
107
    {
108
      if ((laddr & ~(PAGE_SIZE - 1)) == eval_direct32 (transl_table + i, 0, 0))
109
        {
110
          // Page modified
111
          set_direct32 (transl_table + i + 8, -2, 0, 0);
112
          PRINTF ("found paddr=%" PRIx32 "\n",
113
                  eval_direct32 (transl_table + i + 4, 0, 0) |
114
                  (laddr & (PAGE_SIZE - 1)));
115
          return  (oraddr_t) eval_direct32 (transl_table + i + 4, 0, 0) |
116
                  (laddr & (oraddr_t) (PAGE_SIZE - 1));
117
        }
118
    }
119
 
120
  // Allocate new phy page for us.
121
  for (i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
122
    {
123
      if (eval_direct32 (transl_table + i + 8, 0, 0) == 0)
124
        {
125
          // VPN
126
          set_direct32 (transl_table + i, laddr & ~(PAGE_SIZE - 1), 0, 0);
127
          // PPN
128
          set_direct32 (transl_table + i + 4, (i / 16) * PAGE_SIZE, 0, 0);
129
          // Page modified
130
          //set_direct32 (transl_table + i + 8, -2, 0, 0);
131
          PRINTF ("newly allocated ppn=%" PRIx32 "\n",
132
                  eval_direct32 (transl_table + i + 4, 0, 0));
133
          PRINTF ("newly allocated .ppn=%" PRIxADDR "\n", transl_table + i + 4);
134
          PRINTF ("newly allocated ofs=%" PRIxADDR "\n",
135
                  (laddr & (PAGE_SIZE - 1)));
136
          PRINTF ("newly allocated paddr=%" PRIx32 "\n",
137
                  eval_direct32 (transl_table + i + 4, 0,
138
                                 0) | (laddr & (PAGE_SIZE - 1)));
139
          return  (oraddr_t) eval_direct32 (transl_table + i + 4, 0, 0) |
140
                  (laddr & (oraddr_t) (PAGE_SIZE - 1));
141
        }
142
    }
143
 
144
  // If we come this far then all phy memory is used and we can't find our
145
     page nor allocate new page.
146
  transl_error = 1;
147
  PRINTF ("can't translate %" PRIxADDR "\n", laddr);
148
  exit (1);
149
 
150
  return  -1;
151
  */
152
  return 0;
153
 
154
}       /* translate() */
155
 
156
#if IMM_STATS
157
 int
158
MemoryLoad::bits (uint32_t val)
159
{
160
  int i = 1;
161
  if (!val)
162
    return 0;
163
  while (val != 0 && (int32_t) val != -1)
164
    {
165
      i++;
166
      val = (int32_t) val >> 1;
167
    }
168
  return i;
169
}
170
 
171
 void
172
MemoryLoad::check_insn (uint32_t insn)
173
{
174
  int insn_index = insn_decode (insn);
175
  struct insn_op_struct *opd = op_start[insn_index];
176
  uint32_t data = 0;
177
  int dis = 0;
178
  const char *name;
179
  if (!insn || insn_index < 0)
180
    return;
181
  name = insn_name (insn_index);
182
  if (strcmp (name, "l.nop") == 0 || strcmp (name, "l.sys") == 0)
183
    return;
184
 
185
  while (1)
186
    {
187
      uint32_t tmp = 0 unsigned int nbits = 0;
188
      while (1)
189
        {
190
          tmp |=
191
            ((insn >> (opd->type & OPTYPE_SHR)) & ((1 << opd->data) - 1)) <<
192
            nbits;
193
          nbits += opd->data;
194
          if (opd->type & OPTYPE_OP)
195
            break;
196
          opd++;
197
        }
198
 
199
      /* Do we have to sign extend? */
200
      if (opd->type & OPTYPE_SIG)
201
        {
202
          int sbit = (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR;
203
          if (tmp & (1 << sbit))
204
            tmp |= 0xFFFFFFFF << sbit;
205
        }
206
      if (opd->type & OPTYPE_DIS)
207
        {
208
          /* We have to read register later.  */
209
          data += tmp;
210
          dis = 1;
211
        }
212
      else
213
        {
214
          if (!(opd->type & OPTYPE_REG) || dis)
215
            {
216
              if (!dis)
217
                data = tmp;
218
              if (strcmp (name, "l.movhi") == 0)
219
                {
220
                  movhi = data << 16;
221
                }
222
              else
223
                {
224
                  data |= movhi;
225
                  //PRINTF ("%08x %s\n", data, name);
226
                  if (!(or32_opcodes[insn_index].flags & OR32_IF_DELAY))
227
                    {
228
                      bcnt[bits (data)][0]++;
229
                      bsum[0]++;
230
                    }
231
                  else
232
                    {
233
                      if (strcmp (name, "l.bf") == 0
234
                          || strcmp (name, "l.bnf") == 0)
235
                        {
236
                          bcnt[bits (data)][1]++;
237
                          bsum[1]++;
238
                        }
239
                      else
240
                        {
241
                          bcnt[bits (data)][2]++;
242
                          bsum[2]++;
243
                        }
244
                    }
245
                }
246
            }
247
          data = 0;
248
          dis = 0;
249
        }
250
      if (opd->type & OPTYPE_LAST)
251
        {
252
          return;
253
        }
254
      opd++;
255
    }
256
}
257
#endif
258
 
259
/*---------------------------------------------------------------------------*/
260
/*!Add an instruction to the program
261
 
262
  @note insn must be in big endian format
263
 
264
  @param[in] address     The address to use
265
  @param[in] insn        The instruction to add
266
  @param[in] breakpoint  Not used (it is passed to the translate() function,
267
                         which also does not use it.                         */
268
/*---------------------------------------------------------------------------*/
269
 void
270
MemoryLoad::addprogram (oraddr_t  address,
271
            uint32_t  insn,
272
            int      *breakpoint)
273
{
274
 
275 66 julius
  int vaddr = (int) address;
276 51 julius
  /* Use the whole-word write */
277 66 julius
  accessor->set_mem32(vaddr, insn);
278
  PRINTF("*  addprogram: addr 0x%.8x insn: 0x%.8x (conf: 0x%.8x)\n", vaddr, insn, accessor->get_mem32(vaddr));
279 51 julius
  freemem += 4;
280
 
281
}       /* addprogram () */
282
 
283
 
284
/*---------------------------------------------------------------------------*/
285
/*!Load big-endian COFF file
286
 
287
   @param[in] filename  File to load
288
   @param[in] sections  Number of sections in file                           */
289
/*---------------------------------------------------------------------------*/
290
 void
291
MemoryLoad::readfile_coff (char  *filename,
292
               short  sections)
293
{
294
  FILE *inputfs;
295
  char inputbuf[4];
296
  uint32_t insn;
297
  int32_t sectsize;
298
  COFF_AOUTHDR coffaouthdr;
299
  struct COFF_scnhdr coffscnhdr;
300
  int len;
301
  int firstthree = 0;
302
  int breakpoint = 0;
303
 
304
  if (!(inputfs = fopen (filename, "r")))
305
    {
306
      perror ("readfile_coff");
307
      exit (1);
308
    }
309
 
310
  if (fseek (inputfs, sizeof (COFF_FILHDR), SEEK_SET) == -1)
311
    {
312
      fclose (inputfs);
313
      perror ("readfile_coff");
314
      exit (1);
315
    }
316
 
317
  if (fread (&coffaouthdr, sizeof (coffaouthdr), 1, inputfs) != 1)
318
    {
319
      fclose (inputfs);
320
      perror ("readfile_coff");
321
      exit (1);
322
    }
323
 
324
  while (sections--)
325
    {
326
      uint32_t scnhdr_pos =
327
        sizeof (COFF_FILHDR) + sizeof (coffaouthdr) +
328
        sizeof (struct COFF_scnhdr) * firstthree;
329
      if (fseek (inputfs, scnhdr_pos, SEEK_SET) == -1)
330
        {
331
          fclose (inputfs);
332
          perror ("readfile_coff");
333
          exit (1);
334
        }
335
      if (fread (&coffscnhdr, sizeof (struct COFF_scnhdr), 1, inputfs) != 1)
336
        {
337
          fclose (inputfs);
338
          perror ("readfile_coff");
339
          exit (1);
340
        }
341
      PRINTF ("Section: %s,", coffscnhdr.s_name);
342
      PRINTF (" paddr: 0x%.8lx,", COFF_LONG_H (coffscnhdr.s_paddr));
343
      PRINTF (" vaddr: 0x%.8lx,", COFF_LONG_H (coffscnhdr.s_vaddr));
344
      PRINTF (" size: 0x%.8lx,", COFF_LONG_H (coffscnhdr.s_size));
345
      PRINTF (" scnptr: 0x%.8lx\n", COFF_LONG_H (coffscnhdr.s_scnptr));
346
 
347
      sectsize = COFF_LONG_H (coffscnhdr.s_size);
348
      ++firstthree;
349
 
350
      /* loading section */
351
      freemem = COFF_LONG_H (coffscnhdr.s_paddr);
352
      if (fseek (inputfs, COFF_LONG_H (coffscnhdr.s_scnptr), SEEK_SET) == -1)
353
        {
354
          fclose (inputfs);
355
          perror ("readfile_coff");
356
          exit (1);
357
        }
358
      while (sectsize > 0
359
             && (len = fread (&inputbuf, sizeof (inputbuf), 1, inputfs)))
360
        {
361
          insn = COFF_LONG_H (inputbuf);
362
          //len = insn_len (insn_decode (insn));
363
          len = 4;
364
          if (len == 2)
365
            {
366
              fseek (inputfs, -2, SEEK_CUR);
367
            }
368
 
369
          addprogram (freemem, insn, &breakpoint);
370
          sectsize -= len;
371
        }
372
    }
373
  if (firstthree < 3)
374
    {
375
      PRINTF ("One or more missing sections. At least");
376
      PRINTF (" three sections expected (.text, .data, .bss).\n");
377
      exit (1);
378
    }
379
  if (firstthree > 3)
380
    {
381
      PRINTF ("Warning: one or more extra sections. These");
382
      PRINTF (" sections were handled as .data sections.\n");
383
    }
384
 
385
  fclose (inputfs);
386
  PRINTF ("Finished loading COFF.\n");
387
  return;
388
 
389
}       /* readfile_coff () */
390
 
391
 
392
/*---------------------------------------------------------------------------*/
393
/*!Load symbols from big-endian COFF file
394
 
395
   @param[in] filename  File to load
396
   @param[in] symptr    Symbol pointer value
397
   @param[in] syms      Symbols value                                        */
398
/*---------------------------------------------------------------------------*/
399
 
400
 void
401
MemoryLoad::readsyms_coff (char *filename, uint32_t symptr, uint32_t syms)
402
{
403
  FILE *inputfs;
404
  struct COFF_syment coffsymhdr;
405
  int count = 0;
406
  uint32_t nsyms = syms;
407
  if (!(inputfs = fopen (filename, "r")))
408
    {
409
      perror ("readsyms_coff");
410
      exit (1);
411
    }
412
 
413
  if (fseek (inputfs, symptr, SEEK_SET) == -1)
414
    {
415
      fclose (inputfs);
416
      perror ("readsyms_coff");
417
      exit (1);
418
    }
419
 
420
  while (syms--)
421
    {
422
      int i, n;
423
      if (fread (&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1)
424
        {
425
          fclose (inputfs);
426
          perror ("readsyms_coff");
427
          exit (1);
428
        }
429
 
430
      n = (unsigned char) coffsymhdr.e_numaux[0];
431
 
432
      /* check whether this symbol belongs to a section and is external
433
         symbol; ignore all others */
434
      if (COFF_SHORT_H (coffsymhdr.e_scnum) >= 0
435
          && coffsymhdr.e_sclass[0] == C_EXT)
436
        {
437
          if (*((uint32_t *) coffsymhdr.e.e.e_zeroes))
438
            {
439
              if (strlen (coffsymhdr.e.e_name)
440
                  && strlen (coffsymhdr.e.e_name) < 9)
441
                add_label (COFF_LONG_H (coffsymhdr.e_value),
442
                           coffsymhdr.e.e_name);
443
            }
444
          else
445
            {
446
              uint32_t fpos = ftell (inputfs);
447
 
448
              if (fseek
449
                  (inputfs,
450
                   symptr + nsyms * COFF_SYMESZ +
451
                   COFF_LONG_H (coffsymhdr.e.e.e_offset), SEEK_SET) == 0)
452
                {
453
                  char tmp[33], *s = &tmp[0];
454
                  while (s != &tmp[32])
455
                    if ((*(s++) = fgetc (inputfs)) == 0)
456
                      break;
457
                  tmp[32] = 0;
458
                  add_label (COFF_LONG_H (coffsymhdr.e_value), &tmp[0]);
459
                }
460
              fseek (inputfs, fpos, SEEK_SET);
461
            }
462
        }
463
 
464
      for (i = 0; i < n; i++)
465
        if (fread (&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1)
466
          {
467
            fclose (inputfs);
468
            perror ("readsyms_coff3");
469
            exit (1);
470
          }
471
      syms -= n;
472
      count += n;
473
    }
474
 
475
  fclose (inputfs);
476
  PRINTF ("Finished loading symbols.\n");
477
  return;
478
}
479
 
480
/*---------------------------------------------------------------------------*/
481
/*!Read an ELF file
482
 
483
   @param[in] filename  File to load                                         */
484
/*---------------------------------------------------------------------------*/
485
 void
486
MemoryLoad::readfile_elf (char *filename)
487
{
488
 
489
  FILE *inputfs;
490
  struct elf32_hdr elfhdr;
491
  struct elf32_phdr *elf_phdata = NULL;
492
  struct elf32_shdr *elf_spnt, *elf_shdata;
493
  struct elf32_sym *sym_tbl = (struct elf32_sym *) 0;
494
  uint32_t syms = 0;
495
  char *str_tbl = (char *) 0;
496
  char *s_str = (char *) 0;
497
  int breakpoint = 0;
498
  uint32_t inputbuf;
499
  uint32_t padd;
500
  uint32_t insn;
501
  int i, j, sectsize, len;
502
 
503
  if (!(inputfs = fopen (filename, "r")))
504
    {
505
      perror ("readfile_elf");
506
      exit (1);
507
    }
508
 
509
  if (fread (&elfhdr, sizeof (elfhdr), 1, inputfs) != 1)
510
    {
511
      perror ("readfile_elf");
512
      exit (1);
513
    }
514
 
515
  if ((elf_shdata =
516
       (struct elf32_shdr *) malloc (ELF_SHORT_H (elfhdr.e_shentsize) *
517
                                     ELF_SHORT_H (elfhdr.e_shnum))) == NULL)
518
    {
519
      perror ("readfile_elf");
520
      exit (1);
521
    }
522
 
523
  if (fseek (inputfs, ELF_LONG_H (elfhdr.e_shoff), SEEK_SET) != 0)
524
    {
525
      perror ("readfile_elf");
526
      exit (1);
527
    }
528
 
529
  if (fread
530
      (elf_shdata,
531
       ELF_SHORT_H (elfhdr.e_shentsize) * ELF_SHORT_H (elfhdr.e_shnum), 1,
532
       inputfs) != 1)
533
    {
534
      perror ("readfile_elf");
535
      exit (1);
536
    }
537
 
538
  if (ELF_LONG_H (elfhdr.e_phoff))
539
    {
540
      if ((elf_phdata =
541
           (struct elf32_phdr *) malloc (ELF_SHORT_H (elfhdr.e_phnum) *
542
                                         ELF_SHORT_H (elfhdr.e_phentsize))) ==
543
          NULL)
544
        {
545
          perror ("readfile_elf");
546
          exit (1);
547
        }
548
 
549
      if (fseek (inputfs, ELF_LONG_H (elfhdr.e_phoff), SEEK_SET) != 0)
550
        {
551
          perror ("readfile_elf");
552
          exit (1);
553
        }
554
 
555
      if (fread
556
          (elf_phdata,
557
           ELF_SHORT_H (elfhdr.e_phnum) * ELF_SHORT_H (elfhdr.e_phentsize),
558
           1, inputfs) != 1)
559
        {
560
          perror ("readfile_elf");
561
          exit (1);
562
        }
563
    }
564
 
565
  for (i = 0, elf_spnt = elf_shdata; i < ELF_SHORT_H (elfhdr.e_shnum);
566
       i++, elf_spnt++)
567
    {
568
 
569
      if (ELF_LONG_H (elf_spnt->sh_type) == SHT_STRTAB)
570
        {
571
          if (NULL != str_tbl)
572
            {
573
              free (str_tbl);
574
            }
575
 
576
          if ((str_tbl =
577
               (char *) malloc (ELF_LONG_H (elf_spnt->sh_size))) == NULL)
578
            {
579
              perror ("readfile_elf");
580
              exit (1);
581
            }
582
 
583
          if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) !=
584
              0)
585
            {
586
              perror ("readfile_elf");
587
              exit (1);
588
            }
589
 
590
          if (fread (str_tbl, ELF_LONG_H (elf_spnt->sh_size), 1, inputfs) !=
591
              1)
592
            {
593
              perror ("readfile_elf");
594
              exit (1);
595
            }
596
        }
597
      else if (ELF_LONG_H (elf_spnt->sh_type) == SHT_SYMTAB)
598
        {
599
 
600
          if (NULL != sym_tbl)
601
            {
602
              free (sym_tbl);
603
            }
604
 
605
          if ((sym_tbl =
606
               (struct elf32_sym *) malloc (ELF_LONG_H (elf_spnt->sh_size)))
607
              == NULL)
608
            {
609
              perror ("readfile_elf");
610
              exit (1);
611
            }
612
 
613
          if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) !=
614
              0)
615
            {
616
              perror ("readfile_elf");
617
              exit (1);
618
            }
619
 
620
          if (fread (sym_tbl, ELF_LONG_H (elf_spnt->sh_size), 1, inputfs) !=
621
              1)
622
            {
623
              perror ("readfile_elf");
624
              exit (1);
625
            }
626
 
627
          syms =
628
            ELF_LONG_H (elf_spnt->sh_size) /
629
            ELF_LONG_H (elf_spnt->sh_entsize);
630
        }
631
    }
632
 
633
  if (ELF_SHORT_H (elfhdr.e_shstrndx) != SHN_UNDEF)
634
    {
635
      elf_spnt = &elf_shdata[ELF_SHORT_H (elfhdr.e_shstrndx)];
636
 
637
      if ((s_str = (char *) malloc (ELF_LONG_H (elf_spnt->sh_size))) == NULL)
638
        {
639
          perror ("readfile_elf");
640
          exit (1);
641
        }
642
 
643
      if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) != 0)
644
        {
645
          perror ("readfile_elf");
646
          exit (1);
647
        }
648
 
649
      if (fread (s_str, ELF_LONG_H (elf_spnt->sh_size), 1, inputfs) != 1)
650
        {
651
          perror ("readfile_elf");
652
          exit (1);
653
        }
654
    }
655
 
656
 
657
  for (i = 0, elf_spnt = elf_shdata; i < ELF_SHORT_H (elfhdr.e_shnum);
658
       i++, elf_spnt++)
659
    {
660
 
661
      if ((ELF_LONG_H (elf_spnt->sh_type) & SHT_PROGBITS)
662
          && (ELF_LONG_H (elf_spnt->sh_flags) & SHF_ALLOC))
663
        {
664
 
665
          padd = ELF_LONG_H (elf_spnt->sh_addr);
666
          for (j = 0; j < ELF_SHORT_H (elfhdr.e_phnum); j++)
667
            {
668
              if (ELF_LONG_H (elf_phdata[j].p_offset) &&
669
                  ELF_LONG_H (elf_phdata[j].p_offset) <=
670
                  ELF_LONG_H (elf_spnt->sh_offset)
671
                  && (ELF_LONG_H (elf_phdata[j].p_offset) +
672
                      ELF_LONG_H (elf_phdata[j].p_memsz)) >
673
                  ELF_LONG_H (elf_spnt->sh_offset))
674
                padd =
675
                  ELF_LONG_H (elf_phdata[j].p_paddr) +
676
                  ELF_LONG_H (elf_spnt->sh_offset) -
677
                  ELF_LONG_H (elf_phdata[j].p_offset);
678
            }
679
 
680
 
681
 
682
          if (ELF_LONG_H (elf_spnt->sh_name) && s_str)
683 63 julius
            //PRINTF ("Section: %s,", &s_str[ELF_LONG_H (elf_spnt->sh_name)]);
684
            printf("* Section: %s,", &s_str[ELF_LONG_H (elf_spnt->sh_name)]);
685 51 julius
          else
686 63 julius
            //PRINTF ("Section: noname,");
687
            printf ("* Section: noname,");
688
          printf ("* vaddr: 0x%.8lx,", ELF_LONG_H (elf_spnt->sh_addr));
689
          printf ("* paddr: 0x%" PRIx32, padd);
690
          printf ("* offset: 0x%.8lx,", ELF_LONG_H (elf_spnt->sh_offset));
691
          printf ("* size: 0x%.8lx\n", ELF_LONG_H (elf_spnt->sh_size));
692 51 julius
 
693
          freemem = padd;
694
          sectsize = ELF_LONG_H (elf_spnt->sh_size);
695
 
696
          if (fseek (inputfs, ELF_LONG_H (elf_spnt->sh_offset), SEEK_SET) !=
697
              0)
698
            {
699
              perror ("readfile_elf");
700
              free (elf_phdata);
701
              exit (1);
702
            }
703
 
704
          while (sectsize > 0
705
                 && (len = fread (&inputbuf, sizeof (inputbuf), 1, inputfs)))
706
            {
707
              insn = ELF_LONG_H (inputbuf);
708
              //PRINTF("* addprogram(%.8x, %.8x, %d)\n", freemem, insn, breakpoint);
709
              addprogram (freemem, insn, &breakpoint);
710
              sectsize -= 4;
711
            }
712
        }
713
    }
714
 
715
  if (str_tbl)
716
    {
717
      i = 0;
718
      while (syms--)
719
        {
720
          if (sym_tbl[i].st_name && sym_tbl[i].st_info
721
              && ELF_SHORT_H (sym_tbl[i].st_shndx) < 0x8000)
722
            {
723
              add_label (ELF_LONG_H (sym_tbl[i].st_value),
724
                         &str_tbl[ELF_LONG_H (sym_tbl[i].st_name)]);
725
            }
726
          i++;
727
        }
728
    }
729
 
730
  if (NULL != str_tbl)
731
    {
732
      free (str_tbl);
733
    }
734
 
735
  if (NULL != sym_tbl)
736
    {
737
      free (sym_tbl);
738
    }
739
 
740
  free (s_str);
741
  free (elf_phdata);
742
  free (elf_shdata);
743
 
744
}
745
 
746
/* Identify file type and call appropriate readfile_X routine. It only
747
handles orX-coff-big executables at the moment. */
748
 
749
void
750
MemoryLoad::identifyfile (char *filename)
751
{
752
  FILE *inputfs;
753
  COFF_FILHDR coffhdr;
754
  struct elf32_hdr elfhdr;
755
 
756
  if (!(inputfs = fopen (filename, "r")))
757
    {
758
      perror (filename);
759
      fflush (stdout);
760
      fflush (stderr);
761
      exit (1);
762
    }
763
 
764
  if (fread (&coffhdr, sizeof (coffhdr), 1, inputfs) == 1)
765
    {
766
      if (COFF_SHORT_H (coffhdr.f_magic) == 0x17a)
767
        {
768
          uint32_t opthdr_size;
769
          PRINTF ("COFF magic: 0x%.4x\n", COFF_SHORT_H (coffhdr.f_magic));
770
          PRINTF ("COFF flags: 0x%.4x\n", COFF_SHORT_H (coffhdr.f_flags));
771
          PRINTF ("COFF symptr: 0x%.8lx\n", COFF_LONG_H (coffhdr.f_symptr));
772
          if ((COFF_SHORT_H (coffhdr.f_flags) & COFF_F_EXEC) != COFF_F_EXEC)
773
            {
774
              PRINTF ("This COFF is not an executable.\n");
775
              exit (1);
776
            }
777
          opthdr_size = COFF_SHORT_H (coffhdr.f_opthdr);
778
          if (opthdr_size != sizeof (COFF_AOUTHDR))
779
            {
780
              PRINTF ("COFF optional header is missing or not recognized.\n");
781
              PRINTF ("COFF f_opthdr: 0x%" PRIx32 "\n", opthdr_size);
782
              exit (1);
783
            }
784
          fclose (inputfs);
785
          readfile_coff (filename, COFF_SHORT_H (coffhdr.f_nscns));
786
          readsyms_coff (filename, COFF_LONG_H (coffhdr.f_symptr),
787
                         COFF_LONG_H (coffhdr.f_nsyms));
788
          return;
789
        }
790
      else
791
        {
792
          PRINTF ("Not COFF file format\n");
793
          fseek (inputfs, 0, SEEK_SET);
794
        }
795
    }
796
  if (fread (&elfhdr, sizeof (elfhdr), 1, inputfs) == 1)
797
    {
798
      if (elfhdr.e_ident[0] == 0x7f && elfhdr.e_ident[1] == 0x45
799
          && elfhdr.e_ident[2] == 0x4c && elfhdr.e_ident[3] == 0x46)
800
        {
801
          PRINTF ("ELF type: 0x%.4x\n", ELF_SHORT_H (elfhdr.e_type));
802
          PRINTF ("ELF machine: 0x%.4x\n", ELF_SHORT_H (elfhdr.e_machine));
803
          PRINTF ("ELF version: 0x%.8lx\n", ELF_LONG_H (elfhdr.e_version));
804
          PRINTF ("ELF sec = %d\n", ELF_SHORT_H (elfhdr.e_shnum));
805
          if (ELF_SHORT_H (elfhdr.e_type) != ET_EXEC)
806
            {
807
              PRINTF ("This ELF is not an executable.\n");
808
              exit (1);
809
            }
810
          fclose (inputfs);
811
          readfile_elf (filename);
812
          return;
813
        }
814
      else
815
        {
816
          PRINTF ("Not ELF file format.\n");
817
          fseek (inputfs, 0, SEEK_SET);
818
        }
819
    }
820
 
821
  perror ("identifyfile2");
822
  fclose (inputfs);
823
 
824
  return;
825
}
826
 
827
 
828
/*---------------------------------------------------------------------------*/
829
/*!Load file to memory
830
 
831
   Loads file to memory starting at address startaddr and returns freemem.
832
 
833
   @param[in] filename        File to load
834
   @param[in] startaddr       Start address at which to load
835
   @param[in] virtphy_transl  Virtual to physical transation table if
836
                              required. Only used for microkernel simulation,
837
                              and not used in Ork1sim at present (set to NULL)
838
 
839
   @return  zero on success, negative on failure.                            */
840
/*---------------------------------------------------------------------------*/
841
uint32_t
842
MemoryLoad::loadcode (char *filename, oraddr_t startaddr, oraddr_t virtphy_transl)
843
{
844
  //int breakpoint = 0;
845
 
846
  init_labels (); // jb
847
 
848
  transl_error = 0;
849
  transl_table = virtphy_transl;
850
  freemem      = startaddr;
851
  PRINTF ("*  MemoryLoad::loadcode: filename %s  startaddr=%" PRIxADDR "  virtphy_transl=%"
852
          PRIxADDR "\n", filename, startaddr, virtphy_transl);
853
  identifyfile (filename);
854
 
855
#if IMM_STATS
856
  {
857
    int i = 0, a = 0, b = 0, c = 0;
858
    PRINTF ("index:arith/branch/jump\n");
859
    for (i = 0; i < 33; i++)
860
      PRINTF ("%2i:\t%3.0f%% / %3.0f%%/ %3.0f%%\t%5i / %5i / %5i\n", i,
861
              100. * (a += bcnt[i][0]) / bsum[0], 100. * (b +=
862
                                                          bcnt[i][1]) /
863
              bsum[1], 100. * (c +=
864
                               bcnt[i][2]) / bsum[2], bcnt[i][0],
865
              bcnt[i][1], bcnt[i][2]);
866
    PRINTF ("\nsum %i %i %i\n", bsum[0], bsum[1], bsum[2]);
867
  }
868
#endif
869
 
870
  /*
871
  if (transl_error)
872
    return -1;
873
  else
874
    return translate (freemem, &breakpoint);
875
  */
876
  return (uint32_t) freemem;
877
 
878
}
879
 
880
/* From arch sim labels.c */
881
void
882
MemoryLoad::init_labels ()
883
{
884
  int i;
885
  for (i = 0; i < LABELS_HASH_SIZE; i++)
886
    label_hash[i] = NULL;
887
}
888
 
889
void
890
MemoryLoad::add_label (oraddr_t addr, char *name)
891
{
892
  struct label_entry **tmp;
893
  tmp = &(label_hash[addr % LABELS_HASH_SIZE]);
894
  for (; *tmp; tmp = &((*tmp)->next));
895
  *tmp = (label_entry *) malloc (sizeof (**tmp));
896
  (*tmp)->name = (char *) malloc (strlen (name) + 1);
897
  (*tmp)->addr = addr;
898
  strcpy ((*tmp)->name, name);
899
  (*tmp)->next = NULL;
900
}
901
 
902
struct label_entry *
903
MemoryLoad::get_label (oraddr_t addr)
904
{
905
  struct label_entry *tmp = label_hash[addr % LABELS_HASH_SIZE];
906
  while (tmp)
907
    {
908
      if (tmp->addr == addr)
909
        return tmp;
910
      tmp = tmp->next;
911
    }
912
  return NULL;
913
}
914
 
915
struct label_entry *
916
MemoryLoad::find_label (char *name)
917
{
918
  int i;
919
  for (i = 0; i < LABELS_HASH_SIZE; i++)
920
    {
921
      struct label_entry *tmp = label_hash[i % LABELS_HASH_SIZE];
922
      while (tmp)
923
        {
924
          if (strcmp (tmp->name, name) == 0)
925
            return tmp;
926
          tmp = tmp->next;
927
        }
928
    }
929
  return NULL;
930
}
931
 
932
/* Searches mem array for a particular label and returns label's address.
933
   If label does not exist, returns 0. */
934
oraddr_t
935
MemoryLoad::eval_label (char *name)
936
{
937
  struct label_entry *le;
938
  char *plus;
939
  char *minus;
940
  int positive_offset = 0;
941
  int negative_offset = 0;
942
 
943
  if ((plus = strchr (name, '+')))
944
    {
945
      *plus = '\0';
946
      positive_offset = atoi (++plus);
947
    }
948
 
949
  if ((minus = strchr (name, '-')))
950
    {
951
      *minus = '\0';
952
      negative_offset = atoi (++minus);
953
    }
954
  le = find_label (name);
955
  if (!le)
956
    return 0;
957
 
958
  return le->addr + positive_offset - negative_offset;
959
}

powered by: WebSVN 2.1.0

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