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

Subversion Repositories openrisc

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

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
//! Constructor for the ORPSoC memory loader class
36
 
37
//! Initializes various values
38
 
39
//! @param[in] orpsoc  The SystemC Verilated ORPSoC instance
40
//! @param[in] accessor  Accessor class for this Verilated ORPSoC model
41
 
42 462 julius
MemoryLoad::MemoryLoad(OrpsocAccess * _accessor)
43 51 julius
{
44 462 julius
        accessor = _accessor;
45
}                               // MemoryAccess ()
46 51 julius
 
47
/*---------------------------------------------------------------------------*/
48
/*!Copy a string with null termination
49
 
50
   This function is very similar to strncpy, except it null terminates the
51
   string. A global function also used by the CUC.
52
 
53
   @param[in] dst  The destination string
54
   @param[in] src  The source string
55
   @param[in] n    Number of chars to copy EXCLUDING the null terminator
56
                   (i.e. dst had better have room for n+1 chars)
57
 
58
   @return  A pointer to dst                                                 */
59
/*---------------------------------------------------------------------------*/
60 462 julius
char *MemoryLoad::strstrip(char *dst, const char *src, int n)
61 51 julius
{
62 462 julius
        strncpy(dst, src, n);
63
        *(dst + n) = '\0';
64 51 julius
 
65 462 julius
        return dst;
66 51 julius
 
67 462 julius
}                               /* strstrip () */
68 51 julius
 
69 462 julius
#if IMM_STATS
70
int MemoryLoad::bits(uint32_t val)
71 51 julius
{
72 462 julius
        int i = 1;
73
        if (!val)
74
                return 0;
75
        while (val != 0 && (int32_t) val != -1) {
76
                i++;
77
                val = (int32_t) val >> 1;
78 51 julius
        }
79 462 julius
        return i;
80 51 julius
}
81
 
82 462 julius
void MemoryLoad::check_insn(uint32_t insn)
83 51 julius
{
84 462 julius
        int insn_index = insn_decode(insn);
85
        struct insn_op_struct *opd = op_start[insn_index];
86
        uint32_t data = 0;
87
        int dis = 0;
88
        const char *name;
89
        if (!insn || insn_index < 0)
90
                return;
91
        name = insn_name(insn_index);
92
        if (strcmp(name, "l.nop") == 0 || strcmp(name, "l.sys") == 0)
93
                return;
94 51 julius
 
95 462 julius
        while (1) {
96
                uint32_t tmp = 0 unsigned int nbits = 0;
97
                while (1) {
98
                        tmp |=
99
                            ((insn >> (opd->type & OPTYPE_SHR)) &
100
                             ((1 << opd->data) - 1)) << nbits;
101
                        nbits += opd->data;
102
                        if (opd->type & OPTYPE_OP)
103
                                break;
104
                        opd++;
105
                }
106 51 julius
 
107 462 julius
                /* Do we have to sign extend? */
108
                if (opd->type & OPTYPE_SIG) {
109
                        int sbit = (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR;
110
                        if (tmp & (1 << sbit))
111
                                tmp |= 0xFFFFFFFF << sbit;
112 51 julius
                }
113 462 julius
                if (opd->type & OPTYPE_DIS) {
114
                        /* We have to read register later.  */
115
                        data += tmp;
116
                        dis = 1;
117
                } else {
118
                        if (!(opd->type & OPTYPE_REG) || dis) {
119
                                if (!dis)
120
                                        data = tmp;
121
                                if (strcmp(name, "l.movhi") == 0) {
122
                                        movhi = data << 16;
123
                                } else {
124
                                        data |= movhi;
125
                                        //PRINTF ("%08x %s\n", data, name);
126
                                        if (!
127
                                            (or32_opcodes[insn_index].flags &
128
                                             OR32_IF_DELAY)) {
129
                                                bcnt[bits(data)][0]++;
130
                                                bsum[0]++;
131
                                        } else {
132
                                                if (strcmp(name, "l.bf") == 0
133
                                                    || strcmp(name,
134
                                                              "l.bnf") == 0) {
135
                                                        bcnt[bits(data)][1]++;
136
                                                        bsum[1]++;
137
                                                } else {
138
                                                        bcnt[bits(data)][2]++;
139
                                                        bsum[2]++;
140
                                                }
141
                                        }
142
                                }
143 51 julius
                        }
144 462 julius
                        data = 0;
145
                        dis = 0;
146 51 julius
                }
147 462 julius
                if (opd->type & OPTYPE_LAST) {
148
                        return;
149
                }
150
                opd++;
151 51 julius
        }
152
}
153
#endif
154
 
155
/*---------------------------------------------------------------------------*/
156
/*!Add an instruction to the program
157
 
158
  @note insn must be in big endian format
159
 
160
  @param[in] address     The address to use
161 462 julius
  @param[in] insn        The instruction to add                              */
162 51 julius
/*---------------------------------------------------------------------------*/
163 462 julius
void MemoryLoad::addprogram(oraddr_t address, uint32_t insn)
164 51 julius
{
165
 
166 462 julius
        int vaddr = (int)address;
167
        /* Use the whole-word write */
168
        accessor->set_mem32(vaddr, insn);
169
        /*printf("*  addprogram: addr 0x%.8x insn: 0x%.8x (conf: 0x%.8x)\n",
170
           vaddr, insn, accessor->get_mem32(vaddr)); */
171
        freemem += 4;
172 51 julius
 
173 462 julius
}                               /* addprogram () */
174
 
175 51 julius
/*---------------------------------------------------------------------------*/
176
/*!Load big-endian COFF file
177
 
178
   @param[in] filename  File to load
179
   @param[in] sections  Number of sections in file                           */
180
/*---------------------------------------------------------------------------*/
181 462 julius
void MemoryLoad::readfile_coff(char *filename, short sections)
182 51 julius
{
183 462 julius
        FILE *inputfs;
184
        char inputbuf[4];
185
        uint32_t insn;
186
        int32_t sectsize;
187
        COFF_AOUTHDR coffaouthdr;
188
        struct COFF_scnhdr coffscnhdr;
189
        int len;
190
        int firstthree = 0;
191
        int breakpoint = 0;
192 51 julius
 
193 462 julius
        if (!(inputfs = fopen(filename, "r"))) {
194
                perror("readfile_coff");
195
                exit(1);
196
        }
197 51 julius
 
198 462 julius
        if (fseek(inputfs, sizeof(COFF_FILHDR), SEEK_SET) == -1) {
199
                fclose(inputfs);
200
                perror("readfile_coff");
201
                exit(1);
202
        }
203 51 julius
 
204 462 julius
        if (fread(&coffaouthdr, sizeof(coffaouthdr), 1, inputfs) != 1) {
205
                fclose(inputfs);
206
                perror("readfile_coff");
207
                exit(1);
208 51 julius
        }
209
 
210 462 julius
        while (sections--) {
211
                uint32_t scnhdr_pos =
212
                    sizeof(COFF_FILHDR) + sizeof(coffaouthdr) +
213
                    sizeof(struct COFF_scnhdr) * firstthree;
214
                if (fseek(inputfs, scnhdr_pos, SEEK_SET) == -1) {
215
                        fclose(inputfs);
216
                        perror("readfile_coff");
217
                        exit(1);
218
                }
219
                if (fread(&coffscnhdr, sizeof(struct COFF_scnhdr), 1, inputfs)
220
                    != 1) {
221
                        fclose(inputfs);
222
                        perror("readfile_coff");
223
                        exit(1);
224
                }
225
                PRINTF("Section: %s,", coffscnhdr.s_name);
226
                PRINTF(" paddr: 0x%.8lx,", COFF_LONG_H(coffscnhdr.s_paddr));
227
                PRINTF(" vaddr: 0x%.8lx,", COFF_LONG_H(coffscnhdr.s_vaddr));
228
                PRINTF(" size: 0x%.8lx,", COFF_LONG_H(coffscnhdr.s_size));
229
                PRINTF(" scnptr: 0x%.8lx\n", COFF_LONG_H(coffscnhdr.s_scnptr));
230 51 julius
 
231 462 julius
                sectsize = COFF_LONG_H(coffscnhdr.s_size);
232
                ++firstthree;
233 51 julius
 
234 462 julius
                /* loading section */
235
                freemem = COFF_LONG_H(coffscnhdr.s_paddr);
236
                if (fseek(inputfs, COFF_LONG_H(coffscnhdr.s_scnptr), SEEK_SET)
237
                    == -1) {
238
                        fclose(inputfs);
239
                        perror("readfile_coff");
240
                        exit(1);
241
                }
242
                while (sectsize > 0
243
                       && (len =
244
                           fread(&inputbuf, sizeof(inputbuf), 1, inputfs))) {
245
                        insn = COFF_LONG_H(inputbuf);
246
                        //len = insn_len (insn_decode (insn));
247
                        len = 4;
248
                        if (len == 2) {
249
                                fseek(inputfs, -2, SEEK_CUR);
250
                        }
251
 
252
                        addprogram(freemem, insn);
253
                        sectsize -= len;
254
                }
255 51 julius
        }
256 462 julius
        if (firstthree < 3) {
257
                PRINTF("One or more missing sections. At least");
258
                PRINTF(" three sections expected (.text, .data, .bss).\n");
259
                exit(1);
260
        }
261
        if (firstthree > 3) {
262
                PRINTF("Warning: one or more extra sections. These");
263
                PRINTF(" sections were handled as .data sections.\n");
264
        }
265 51 julius
 
266 462 julius
        fclose(inputfs);
267
        PRINTF("Finished loading COFF.\n");
268
        return;
269 51 julius
 
270 462 julius
}                               /* readfile_coff () */
271 51 julius
 
272
/*---------------------------------------------------------------------------*/
273
/*!Load symbols from big-endian COFF file
274
 
275
   @param[in] filename  File to load
276
   @param[in] symptr    Symbol pointer value
277
   @param[in] syms      Symbols value                                        */
278
/*---------------------------------------------------------------------------*/
279
 
280 462 julius
void MemoryLoad::readsyms_coff(char *filename, uint32_t symptr, uint32_t syms)
281 51 julius
{
282 462 julius
        FILE *inputfs;
283
        struct COFF_syment coffsymhdr;
284
        int count = 0;
285
        uint32_t nsyms = syms;
286
        if (!(inputfs = fopen(filename, "r"))) {
287
                perror("readsyms_coff");
288
                exit(1);
289
        }
290 51 julius
 
291 462 julius
        if (fseek(inputfs, symptr, SEEK_SET) == -1) {
292
                fclose(inputfs);
293
                perror("readsyms_coff");
294
                exit(1);
295 51 julius
        }
296
 
297 462 julius
        while (syms--) {
298
                int i, n;
299
                if (fread(&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1) {
300
                        fclose(inputfs);
301
                        perror("readsyms_coff");
302
                        exit(1);
303
                }
304 51 julius
 
305 462 julius
                n = (unsigned char)coffsymhdr.e_numaux[0];
306 51 julius
 
307 462 julius
                /* check whether this symbol belongs to a section and is external
308
                   symbol; ignore all others */
309
                if (COFF_SHORT_H(coffsymhdr.e_scnum) >= 0
310
                    && coffsymhdr.e_sclass[0] == C_EXT) {
311
                        if (*((uint32_t *) coffsymhdr.e.e.e_zeroes)) {
312
                                if (strlen(coffsymhdr.e.e_name)
313
                                    && strlen(coffsymhdr.e.e_name) < 9)
314
                                        add_label(COFF_LONG_H
315
                                                  (coffsymhdr.e_value),
316
                                                  coffsymhdr.e.e_name);
317
                        } else {
318
                                uint32_t fpos = ftell(inputfs);
319
 
320
                                if (fseek
321
                                    (inputfs,
322
                                     symptr + nsyms * COFF_SYMESZ +
323
                                     COFF_LONG_H(coffsymhdr.e.e.e_offset),
324
                                     SEEK_SET) == 0) {
325
                                        char tmp[33], *s = &tmp[0];
326
                                        while (s != &tmp[32])
327
                                                if ((*(s++) =
328
                                                     fgetc(inputfs)) == 0)
329
                                                        break;
330
                                        tmp[32] = 0;
331
                                        add_label(COFF_LONG_H
332
                                                  (coffsymhdr.e_value),
333
                                                  &tmp[0]);
334
                                }
335
                                fseek(inputfs, fpos, SEEK_SET);
336
                        }
337 51 julius
                }
338 462 julius
 
339
                for (i = 0; i < n; i++)
340
                        if (fread(&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1) {
341
                                fclose(inputfs);
342
                                perror("readsyms_coff3");
343
                                exit(1);
344
                        }
345
                syms -= n;
346
                count += n;
347 51 julius
        }
348
 
349 462 julius
        fclose(inputfs);
350
        PRINTF("Finished loading symbols.\n");
351
        return;
352 51 julius
}
353
 
354
/*---------------------------------------------------------------------------*/
355
/*!Read an ELF file
356
 
357
   @param[in] filename  File to load                                         */
358
/*---------------------------------------------------------------------------*/
359 462 julius
void MemoryLoad::readfile_elf(char *filename)
360 51 julius
{
361
 
362 462 julius
        FILE *inputfs;
363
        struct elf32_hdr elfhdr;
364
        struct elf32_phdr *elf_phdata = NULL;
365
        struct elf32_shdr *elf_spnt, *elf_shdata;
366
        struct elf32_sym *sym_tbl = (struct elf32_sym *)0;
367
        uint32_t syms = 0;
368
        char *str_tbl = (char *)0;
369
        char *s_str = (char *)0;
370
        int breakpoint = 0;
371
        uint32_t inputbuf;
372
        uint32_t padd;
373
        uint32_t insn;
374
        int i, j, sectsize, len;
375 51 julius
 
376 462 julius
        if (!(inputfs = fopen(filename, "r"))) {
377
                perror("readfile_elf");
378
                exit(1);
379
        }
380 51 julius
 
381 462 julius
        if (fread(&elfhdr, sizeof(elfhdr), 1, inputfs) != 1) {
382
                perror("readfile_elf");
383
                exit(1);
384
        }
385 51 julius
 
386 462 julius
        if ((elf_shdata =
387
             (struct elf32_shdr *)malloc(ELF_SHORT_H(elfhdr.e_shentsize) *
388
                                         ELF_SHORT_H(elfhdr.e_shnum))) == NULL)
389 51 julius
        {
390 462 julius
                perror("readfile_elf");
391
                exit(1);
392 51 julius
        }
393
 
394 462 julius
        if (fseek(inputfs, ELF_LONG_H(elfhdr.e_shoff), SEEK_SET) != 0) {
395
                perror("readfile_elf");
396
                exit(1);
397 51 julius
        }
398
 
399 462 julius
        if (fread
400
            (elf_shdata,
401
             ELF_SHORT_H(elfhdr.e_shentsize) * ELF_SHORT_H(elfhdr.e_shnum), 1,
402
             inputfs) != 1) {
403
                perror("readfile_elf");
404
                exit(1);
405 51 julius
        }
406
 
407 462 julius
        if (ELF_LONG_H(elfhdr.e_phoff)) {
408
                if ((elf_phdata =
409
                     (struct elf32_phdr *)malloc(ELF_SHORT_H(elfhdr.e_phnum) *
410
                                                 ELF_SHORT_H
411
                                                 (elfhdr.e_phentsize))) ==
412
                    NULL) {
413
                        perror("readfile_elf");
414
                        exit(1);
415
                }
416 51 julius
 
417 462 julius
                if (fseek(inputfs, ELF_LONG_H(elfhdr.e_phoff), SEEK_SET) != 0) {
418
                        perror("readfile_elf");
419
                        exit(1);
420
                }
421 51 julius
 
422 462 julius
                if (fread
423
                    (elf_phdata,
424
                     ELF_SHORT_H(elfhdr.e_phnum) *
425
                     ELF_SHORT_H(elfhdr.e_phentsize), 1, inputfs) != 1) {
426
                        perror("readfile_elf");
427
                        exit(1);
428
                }
429
        }
430 51 julius
 
431 462 julius
        for (i = 0, elf_spnt = elf_shdata; i < ELF_SHORT_H(elfhdr.e_shnum);
432
             i++, elf_spnt++) {
433 51 julius
 
434 462 julius
                if (ELF_LONG_H(elf_spnt->sh_type) == SHT_STRTAB) {
435
                        if (NULL != str_tbl) {
436
                                free(str_tbl);
437
                        }
438 51 julius
 
439 462 julius
                        if ((str_tbl =
440
                             (char *)malloc(ELF_LONG_H(elf_spnt->sh_size))) ==
441
                            NULL) {
442
                                perror("readfile_elf");
443
                                exit(1);
444
                        }
445 51 julius
 
446 462 julius
                        if (fseek
447
                            (inputfs, ELF_LONG_H(elf_spnt->sh_offset),
448
                             SEEK_SET) != 0) {
449
                                perror("readfile_elf");
450
                                exit(1);
451
                        }
452 51 julius
 
453 462 julius
                        if (fread
454
                            (str_tbl, ELF_LONG_H(elf_spnt->sh_size), 1,
455
                             inputfs) != 1) {
456
                                perror("readfile_elf");
457
                                exit(1);
458
                        }
459
                } else if (ELF_LONG_H(elf_spnt->sh_type) == SHT_SYMTAB) {
460 51 julius
 
461 462 julius
                        if (NULL != sym_tbl) {
462
                                free(sym_tbl);
463
                        }
464 51 julius
 
465 462 julius
                        if ((sym_tbl = (struct elf32_sym *)
466
                             malloc(ELF_LONG_H(elf_spnt->sh_size)))
467
                            == NULL) {
468
                                perror("readfile_elf");
469
                                exit(1);
470
                        }
471 51 julius
 
472 462 julius
                        if (fseek
473
                            (inputfs, ELF_LONG_H(elf_spnt->sh_offset),
474
                             SEEK_SET) != 0) {
475
                                perror("readfile_elf");
476
                                exit(1);
477
                        }
478 51 julius
 
479 462 julius
                        if (fread
480
                            (sym_tbl, ELF_LONG_H(elf_spnt->sh_size), 1,
481
                             inputfs) != 1) {
482
                                perror("readfile_elf");
483
                                exit(1);
484
                        }
485 51 julius
 
486 462 julius
                        syms =
487
                            ELF_LONG_H(elf_spnt->sh_size) /
488
                            ELF_LONG_H(elf_spnt->sh_entsize);
489
                }
490 51 julius
        }
491
 
492 462 julius
        if (ELF_SHORT_H(elfhdr.e_shstrndx) != SHN_UNDEF) {
493
                elf_spnt = &elf_shdata[ELF_SHORT_H(elfhdr.e_shstrndx)];
494 51 julius
 
495 462 julius
                if ((s_str =
496
                     (char *)malloc(ELF_LONG_H(elf_spnt->sh_size))) == NULL) {
497
                        perror("readfile_elf");
498
                        exit(1);
499
                }
500 51 julius
 
501 462 julius
                if (fseek(inputfs, ELF_LONG_H(elf_spnt->sh_offset), SEEK_SET) !=
502
                    0) {
503
                        perror("readfile_elf");
504
                        exit(1);
505
                }
506 51 julius
 
507 462 julius
                if (fread(s_str, ELF_LONG_H(elf_spnt->sh_size), 1, inputfs) !=
508
                    1) {
509
                        perror("readfile_elf");
510
                        exit(1);
511
                }
512
        }
513 51 julius
 
514 462 julius
        for (i = 0, elf_spnt = elf_shdata; i < ELF_SHORT_H(elfhdr.e_shnum);
515
             i++, elf_spnt++) {
516 51 julius
 
517 462 julius
                if ((ELF_LONG_H(elf_spnt->sh_type) & SHT_PROGBITS)
518
                    && (ELF_LONG_H(elf_spnt->sh_flags) & SHF_ALLOC)) {
519 51 julius
 
520 462 julius
                        padd = ELF_LONG_H(elf_spnt->sh_addr);
521
                        for (j = 0; j < ELF_SHORT_H(elfhdr.e_phnum); j++) {
522
                                if (ELF_LONG_H(elf_phdata[j].p_offset) &&
523
                                    ELF_LONG_H(elf_phdata[j].p_offset) <=
524
                                    ELF_LONG_H(elf_spnt->sh_offset)
525
                                    && (ELF_LONG_H(elf_phdata[j].p_offset) +
526
                                        ELF_LONG_H(elf_phdata[j].p_memsz)) >
527
                                    ELF_LONG_H(elf_spnt->sh_offset))
528
                                        padd =
529
                                            ELF_LONG_H(elf_phdata[j].p_paddr) +
530
                                            ELF_LONG_H(elf_spnt->sh_offset) -
531
                                            ELF_LONG_H(elf_phdata[j].p_offset);
532
                        }
533
 
534
                        if (!gQuiet)
535
                        {
536
                                if (ELF_LONG_H(elf_spnt->sh_name) && s_str)
537
                                        printf("* Section: %s,",
538
                                               &s_str[ELF_LONG_H(elf_spnt->sh_name)]);
539
                                else
540
                                        printf("* Section: noname,");
541
                                printf("* vaddr: 0x%.8lx,",
542
                                       ELF_LONG_H(elf_spnt->sh_addr));
543
                                printf("* paddr: 0x%" PRIx32, padd);
544
                                printf("* offset: 0x%.8lx,",
545
                                       ELF_LONG_H(elf_spnt->sh_offset));
546
                                printf("* size: 0x%.8lx\n",
547
                                       ELF_LONG_H(elf_spnt->sh_size));
548
                        }
549
 
550
                        freemem = padd;
551
                        sectsize = ELF_LONG_H(elf_spnt->sh_size);
552 51 julius
 
553 462 julius
                        if (fseek
554
                            (inputfs, ELF_LONG_H(elf_spnt->sh_offset),
555
                             SEEK_SET) != 0) {
556
                                perror("readfile_elf");
557
                                free(elf_phdata);
558
                                exit(1);
559
                        }
560 51 julius
 
561 462 julius
                        while (sectsize > 0
562
                               && (len =
563
                                   fread(&inputbuf, sizeof(inputbuf), 1,
564
                                         inputfs))) {
565
                                insn = ELF_LONG_H(inputbuf);
566
                                //PRINTF("* addprogram(%.8x, %.8x, %d)\n", freemem, insn, breakpoint);
567
                                addprogram(freemem, insn);
568
                                sectsize -= 4;
569
                        }
570
                }
571
        }
572 51 julius
 
573 462 julius
        if (str_tbl) {
574
                i = 0;
575
                while (syms--) {
576
                        if (sym_tbl[i].st_name && sym_tbl[i].st_info
577
                            && ELF_SHORT_H(sym_tbl[i].st_shndx) < 0x8000) {
578
                                add_label(ELF_LONG_H(sym_tbl[i].st_value),
579
                                          &str_tbl[ELF_LONG_H
580
                                                   (sym_tbl[i].st_name)]);
581
                        }
582
                        i++;
583
                }
584
        }
585 51 julius
 
586 462 julius
        if (NULL != str_tbl) {
587
                free(str_tbl);
588 51 julius
        }
589
 
590 462 julius
        if (NULL != sym_tbl) {
591
                free(sym_tbl);
592 51 julius
        }
593
 
594 462 julius
        free(s_str);
595
        free(elf_phdata);
596
        free(elf_shdata);
597 51 julius
 
598
}
599
 
600
/* Identify file type and call appropriate readfile_X routine. It only
601
handles orX-coff-big executables at the moment. */
602
 
603 462 julius
void MemoryLoad::identifyfile(char *filename)
604 51 julius
{
605 462 julius
        FILE *inputfs;
606
        COFF_FILHDR coffhdr;
607
        struct elf32_hdr elfhdr;
608 51 julius
 
609 462 julius
        if (!(inputfs = fopen(filename, "r"))) {
610
                perror(filename);
611
                fflush(stdout);
612
                fflush(stderr);
613
                exit(1);
614 51 julius
        }
615 462 julius
 
616
        if (fread(&coffhdr, sizeof(coffhdr), 1, inputfs) == 1) {
617
                if (COFF_SHORT_H(coffhdr.f_magic) == 0x17a) {
618
                        uint32_t opthdr_size;
619
                        PRINTF("COFF magic: 0x%.4x\n",
620
                               COFF_SHORT_H(coffhdr.f_magic));
621
                        PRINTF("COFF flags: 0x%.4x\n",
622
                               COFF_SHORT_H(coffhdr.f_flags));
623
                        PRINTF("COFF symptr: 0x%.8lx\n",
624
                               COFF_LONG_H(coffhdr.f_symptr));
625
                        if ((COFF_SHORT_H(coffhdr.f_flags) & COFF_F_EXEC) !=
626
                            COFF_F_EXEC) {
627
                                PRINTF("This COFF is not an executable.\n");
628
                                exit(1);
629
                        }
630
                        opthdr_size = COFF_SHORT_H(coffhdr.f_opthdr);
631
                        if (opthdr_size != sizeof(COFF_AOUTHDR)) {
632
                                PRINTF
633
                                    ("COFF optional header is missing or not recognized.\n");
634
                                PRINTF("COFF f_opthdr: 0x%" PRIx32 "\n",
635
                                       opthdr_size);
636
                                exit(1);
637
                        }
638
                        fclose(inputfs);
639
                        readfile_coff(filename, COFF_SHORT_H(coffhdr.f_nscns));
640
                        readsyms_coff(filename, COFF_LONG_H(coffhdr.f_symptr),
641
                                      COFF_LONG_H(coffhdr.f_nsyms));
642
                        return;
643
                } else {
644
                        PRINTF("Not COFF file format\n");
645
                        fseek(inputfs, 0, SEEK_SET);
646
                }
647 51 julius
        }
648 462 julius
        if (fread(&elfhdr, sizeof(elfhdr), 1, inputfs) == 1) {
649
                if (elfhdr.e_ident[0] == 0x7f && elfhdr.e_ident[1] == 0x45
650
                    && elfhdr.e_ident[2] == 0x4c && elfhdr.e_ident[3] == 0x46) {
651
                        PRINTF("ELF type: 0x%.4x\n",
652
                               ELF_SHORT_H(elfhdr.e_type));
653
                        PRINTF("ELF machine: 0x%.4x\n",
654
                               ELF_SHORT_H(elfhdr.e_machine));
655
                        PRINTF("ELF version: 0x%.8lx\n",
656
                               ELF_LONG_H(elfhdr.e_version));
657
                        PRINTF("ELF sec = %d\n", ELF_SHORT_H(elfhdr.e_shnum));
658
                        if (ELF_SHORT_H(elfhdr.e_type) != ET_EXEC) {
659
                                PRINTF("This ELF is not an executable.\n");
660
                                exit(1);
661
                        }
662
                        fclose(inputfs);
663
                        readfile_elf(filename);
664
                        return;
665
                } else {
666
                        PRINTF("Not ELF file format.\n");
667
                        fseek(inputfs, 0, SEEK_SET);
668
                }
669 51 julius
        }
670
 
671 462 julius
        perror("identifyfile2");
672
        fclose(inputfs);
673 51 julius
 
674 462 julius
        return;
675 51 julius
}
676
 
677
/*---------------------------------------------------------------------------*/
678
/*!Load file to memory
679
 
680
   Loads file to memory starting at address startaddr and returns freemem.
681
 
682
   @param[in] filename        File to load
683
   @param[in] startaddr       Start address at which to load
684
   @param[in] virtphy_transl  Virtual to physical transation table if
685
                              required. Only used for microkernel simulation,
686
                              and not used in Ork1sim at present (set to NULL)
687
 
688
   @return  zero on success, negative on failure.                            */
689
/*---------------------------------------------------------------------------*/
690
uint32_t
691 462 julius
    MemoryLoad::loadcode(char *filename, oraddr_t startaddr,
692
                         oraddr_t virtphy_transl)
693 51 julius
{
694
 
695 462 julius
        init_labels();          // jb
696 51 julius
 
697 462 julius
        transl_table = virtphy_transl;
698
        freemem = startaddr;
699
        /*printf ("*  MemoryLoad::loadcode: filename %s  startaddr=%" PRIxADDR "  virtphy_transl=%" PRIxADDR "\n", filename, startaddr, virtphy_transl); */
700 51 julius
 
701 462 julius
        identifyfile(filename);
702
 
703
        return (uint32_t) freemem;
704
 
705 51 julius
}
706
 
707
/* From arch sim labels.c */
708
void
709 462 julius
 MemoryLoad::init_labels()
710 51 julius
{
711 462 julius
        int i;
712
        for (i = 0; i < LABELS_HASH_SIZE; i++)
713
                label_hash[i] = NULL;
714 51 julius
}
715
 
716 462 julius
void MemoryLoad::add_label(oraddr_t addr, char *name)
717 51 julius
{
718 462 julius
        struct label_entry **tmp;
719
        tmp = &(label_hash[addr % LABELS_HASH_SIZE]);
720
        for (; *tmp; tmp = &((*tmp)->next)) ;
721
        *tmp = (label_entry *) malloc(sizeof(**tmp));
722
        (*tmp)->name = (char *)malloc(strlen(name) + 1);
723
        (*tmp)->addr = addr;
724
        strcpy((*tmp)->name, name);
725
        (*tmp)->next = NULL;
726 51 julius
}
727
 
728 462 julius
struct label_entry *MemoryLoad::get_label(oraddr_t addr)
729 51 julius
{
730 462 julius
        struct label_entry *tmp = label_hash[addr % LABELS_HASH_SIZE];
731
        while (tmp) {
732
                if (tmp->addr == addr)
733
                        return tmp;
734
                tmp = tmp->next;
735
        }
736
        return NULL;
737 51 julius
}
738
 
739 462 julius
struct label_entry *MemoryLoad::find_label(char *name)
740 51 julius
{
741 462 julius
        int i;
742
        for (i = 0; i < LABELS_HASH_SIZE; i++) {
743
                struct label_entry *tmp = label_hash[i % LABELS_HASH_SIZE];
744
                while (tmp) {
745
                        if (strcmp(tmp->name, name) == 0)
746
                                return tmp;
747
                        tmp = tmp->next;
748
                }
749 51 julius
        }
750 462 julius
        return NULL;
751 51 julius
}
752
 
753
/* Searches mem array for a particular label and returns label's address.
754
   If label does not exist, returns 0. */
755 462 julius
oraddr_t MemoryLoad::eval_label(char *name)
756 51 julius
{
757 462 julius
        struct label_entry *le;
758
        char *plus;
759
        char *minus;
760
        int positive_offset = 0;
761
        int negative_offset = 0;
762 51 julius
 
763 462 julius
        if ((plus = strchr(name, '+'))) {
764
                *plus = '\0';
765
                positive_offset = atoi(++plus);
766
        }
767 51 julius
 
768 462 julius
        if ((minus = strchr(name, '-'))) {
769
                *minus = '\0';
770
                negative_offset = atoi(++minus);
771
        }
772
        le = find_label(name);
773
        if (!le)
774
                return 0;
775 51 julius
 
776 462 julius
        return le->addr + positive_offset - negative_offset;
777 51 julius
}

powered by: WebSVN 2.1.0

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