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

Subversion Repositories or1k

[/] [or1k/] [tags/] [stable_0_2_0_rc2/] [or1ksim/] [cpu/] [common/] [parse.c] - Diff between revs 26 and 28

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 26 Rev 28
Line 23... Line 23...
#include <stdlib.h>
#include <stdlib.h>
 
 
#include "parse.h"
#include "parse.h"
#include "abstract.h"
#include "abstract.h"
#include "arch.h"
#include "arch.h"
 
#include "coff.h"
 
 
#define MAXLINE_LEN     18000
#define MAXLINE_LEN     18000
 
 
 
extern char *disassembled;
 
 
/* Unused mem memory marker. It is used when allocating program and data memory
/* Unused mem memory marker. It is used when allocating program and data memory
   during parsing */
   during parsing */
unsigned int freemem;
unsigned int freemem;
 
 
int nonempty(char *line)
int nonempty(char *line)
Line 148... Line 151...
void adddataspace(char *num)
void adddataspace(char *num)
{
{
        freemem += atol(num);
        freemem += atol(num);
}
}
 
 
void addlabel(char *label)
void addlabel(char *label, unsigned long freemem)
{
{
        if (strstr(label, LABELEND_CHAR)) {
        struct label_entry **tmp;
                *strstr(label, LABELEND_CHAR) = '\0';
 
                strcpy(mem[freemem].label, label);
        printf("adding label %s at %x\n", label, freemem);
        }
        tmp = &mem[freemem].label;
 
        for (; *tmp; tmp = &((*tmp)->next));
 
        *tmp = malloc(sizeof(**tmp));
 
        (*tmp)->name = malloc(strlen(label)+1);
 
        strcpy((*tmp)->name, label);
 
        (*tmp)->next = NULL;
 
 
        return;
        return;
}
}
 
 
 
char null_str[1] = "\0";
 
 
void addprogram(char *insn, char *operands)
void addprogram(char *insn, char *operands)
{
{
#ifdef  __HALF_WORD_INSN__
 
        int h_insn_is_word_flag=0;
        int h_insn_is_word_flag=0;
        char insn_first2_char[3];
        char insn_first2_char[3];
 
 
        strcpy(mem[freemem].insn, insn);
        debug("addprogram 1\n");
 
        if (!mem[freemem].insn) {
 
                mem[freemem].insn = malloc(sizeof(*mem[freemem].insn));
 
                mem[freemem].insn->insn = null_str;
 
                mem[freemem].insn->op1 = null_str;
 
                mem[freemem].insn->op2 = null_str;
 
                mem[freemem].insn->op3 = null_str;
 
                mem[freemem].insn->op4 = null_str;
 
        } else {
 
                printf("internal error: reloading the same location\n");
 
                exit(1);
 
        }
 
        debug("addprogram 2\n");
 
 
 
        mem[freemem].insn->insn = malloc(strlen(insn)+1);
 
 
 
#ifdef  OR16
 
 
 
        strcpy(mem[freemem].insn->insn, insn);
 
        printf("half:%s:\n", insn);
        insn_first2_char[0]=insn[0];
        insn_first2_char[0]=insn[0];
        insn_first2_char[1]=insn[1];
        insn_first2_char[1]=insn[1];
        insn_first2_char[2]='\0';
        insn_first2_char[2]='\0';
 
        debug("addprogram 3\n");
 
 
        if(strcmp("h.", insn_first2_char) == 0) {
        if(strcmp("h.", insn_first2_char) == 0) {
                if(strcmp("h.load32u", insn) == 0 ||
                if(strcmp("h.load32u", insn) == 0 ||
                   strcmp("h.load16u", insn) == 0 ||
                   strcmp("h.load16u", insn) == 0 ||
                   strcmp("h.load8u", insn) == 0 ||
                   strcmp("h.load8u", insn) == 0 ||
Line 195... Line 224...
        }
        }
        else {
        else {
                        h_insn_is_word_flag = 0; /* not h.xxx insn */
                        h_insn_is_word_flag = 0; /* not h.xxx insn */
        }
        }
#else
#else
        strcpy(mem[freemem].insn, insn);
        debug("addprogram 4\n");
 
        strcpy(mem[freemem].insn->insn, insn);
 
        debug("addprogram 5\n");
#endif
#endif
 
 
        /* op1 */
        /* op1 */
        if (*operands)
        if (*operands) {
                strcpy(mem[freemem].op1, operands);
                mem[freemem].insn->op1 = malloc(strlen(operands)+1);
        if (strstr(mem[freemem].op1, OPERAND_DELIM)) {
                strcpy(mem[freemem].insn->op1, operands);
                operands = strstr(mem[freemem].op1, OPERAND_DELIM);
        }
 
 
 
        debug("addprogram 6\n");
 
        debug("operands:%s\n", operands);
 
        if (strstr(operands, OPERAND_DELIM)) {
 
                debug("addprogram 6a\n");
 
                operands = strstr(mem[freemem].insn->op1, OPERAND_DELIM);
                *operands = '\0';
                *operands = '\0';
                operands++;
                operands++;
        } else {
        } else {
#ifdef __HALF_WORD_INSN__
                debug("addprogram 6b\n");
 
#ifdef OR16
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
#else
#else
                freemem += 4;
                freemem += 4;
#endif
#endif
                return;
                return;
        }
        }
 
 
 
        debug("addprogram 7\n");
        /* op2 */
        /* op2 */
        if (*operands)
        if (*operands) {
                strcpy(mem[freemem].op2, operands);
                mem[freemem].insn->op2 = malloc(strlen(operands)+1);
        if (strstr(mem[freemem].op2, OPERAND_DELIM)) {
                strcpy(mem[freemem].insn->op2, operands);
                operands = strstr(mem[freemem].op2, OPERAND_DELIM);
        }
 
        if (strstr(operands, OPERAND_DELIM)) {
 
                operands = strstr(mem[freemem].insn->op2, OPERAND_DELIM);
                *operands = '\0';
                *operands = '\0';
                operands++;
                operands++;
        } else {
        } else {
#ifdef __HALF_WORD_INSN__
#ifdef OR16
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
#else
#else
                freemem += 4;
                freemem += 4;
#endif
#endif
                return;
                return;
        }
        }
 
 
 
        debug("addprogram 8\n");
        /* op3 */
        /* op3 */
        if (*operands)
        if (*operands) {
                strcpy(mem[freemem].op3, operands);
                mem[freemem].insn->op3 = malloc(strlen(operands)+1);
        if (strstr(mem[freemem].op3, OPERAND_DELIM)) {
                strcpy(mem[freemem].insn->op3, operands);
                operands = strstr(mem[freemem].op3, OPERAND_DELIM);
        }
 
        if (strstr(operands, OPERAND_DELIM)) {
 
                operands = strstr(mem[freemem].insn->op3, OPERAND_DELIM);
                *operands = '\0';
                *operands = '\0';
                operands++;
                operands++;
        } else {
        } else {
#ifdef __HALF_WORD_INSN__
#ifdef OR16
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
#else
#else
                freemem += 4;
                freemem += 4;
#endif
#endif
                return;
                return;
        }
        }
 
 
        /* op4 */
        /* op4 */
        if (*operands)
        if (*operands) {
                strcpy(mem[freemem].op4, operands);
                mem[freemem].insn->op4 = malloc(strlen(operands)+1);
        if (strstr(mem[freemem].op4, OPERAND_DELIM)) {
                strcpy(mem[freemem].insn->op4, operands);
                operands = strstr(mem[freemem].op4, OPERAND_DELIM);
        }
 
        if (strstr(operands, OPERAND_DELIM)) {
 
                operands = strstr(mem[freemem].insn->op4, OPERAND_DELIM);
                *operands = '\0';
                *operands = '\0';
                operands++;
                operands++;
        }
        }
 
 
#ifdef __HALF_WORD_INSN__
#ifdef OR16
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
#else
#else
                freemem += 4;
                freemem += 4;
#endif
#endif
        return;
        return;
Line 293... Line 339...
        if (strlen(item) == 0)
        if (strlen(item) == 0)
                return;
                return;
 
 
        /* Is this item a label? If yes, add it to the label table and return immediately. */
        /* Is this item a label? If yes, add it to the label table and return immediately. */
        if (strstr(item, LABELEND_CHAR)) {
        if (strstr(item, LABELEND_CHAR)) {
                addlabel(item);
                *strstr(item, LABELEND_CHAR) = '\0';
 
                addlabel(item, freemem);
                return;
                return;
        }
        }
 
 
        /* Is this item a .directive? If yes, check for some supported
        /* Is this item a .directive? If yes, check for some supported
           and then return (even if unsupported found). */
           and then return (even if unsupported found). */
        if (item[0] == DIRECTIVE_CHAR) {
        if (item[0] == DIRECTIVE_CHAR) {
                if ((strcmp(item, ".align") == 0) && (freemem % 4)) {
                if (strcmp(item, ".align") == 0) {
                        freemem &= -4;  /* e.g. 0xfffffffc */
                        int align = atoi(item2);
                        freemem += 4;   /* always align to word */
                        if (!(freemem % align))
 
                                return;
 
                        freemem &= -align;
 
                        freemem += align;
                        return;
                        return;
                } else
                } else
                if (strcmp(item, ".ascii") == 0) {
                if (strcmp(item, ".ascii") == 0) {
                        adddatastr(strstr(inputline, "\""));
                        adddatastr(strstr(inputline, "\""));
                        return;
                        return;
Line 330... Line 380...
                        return;
                        return;
        }
        }
 
 
        /* This item can only be an instruction. Get all operands
        /* This item can only be an instruction. Get all operands
           and add everything to mem array but as a program. */
           and add everything to mem array but as a program. */
 
        debug("%x: ", freemem);
        addprogram(item, item2);
        addprogram(item, item2);
 
 
        /* Also do static, single stats. */
        /* Also do static, single stats. */
        addsstats(item, 0, 1);
        addsstats(item, 0, 1);
 
 
        return;
        return;
 
 
}
}
 
 
 
/* Load big-endian COFF file. At the moment it doesn't load symbols yet. */
 
 
 
void readfile_coff(char *filename, short sections)
 
{
 
        FILE *inputfs;
 
        char inputbuf[4];
 
        unsigned long insn;
 
        signed long tstart, tsize, dstart, dsize;
 
        COFF_AOUTHDR coffaouthdr;
 
        struct COFF_scnhdr coffscnhdr;
 
        int  len;
 
        char item[MAXLINE_LEN];
 
        char item2[MAXLINE_LEN];
 
 
 
 
 
        if (!(inputfs = fopen(filename, "r"))) {
 
                perror("readfile_coff");
 
                exit(1);
 
        }
 
 
 
        if (fseek(inputfs, sizeof(struct COFF_filehdr), SEEK_SET) == -1) {
 
                fclose(inputfs);
 
                perror("readfile_coff");
 
                exit(1);
 
        }
 
 
 
        if (fread(&coffaouthdr, sizeof(coffaouthdr), 1, inputfs) != 1) {
 
                fclose(inputfs);
 
                perror("readfile_coff");
 
                exit(1);
 
        }
 
 
 
        tstart = COFF_LONG_H(coffaouthdr.text_start);
 
        dstart = COFF_LONG_H(coffaouthdr.data_start);
 
        tsize = COFF_LONG_H(coffaouthdr.tsize);
 
        dsize = COFF_LONG_H(coffaouthdr.dsize);
 
        printf("text_start: %x, ", tstart);
 
        printf("tsize: %x, ", tsize);
 
        printf("data_start: %x, ", dstart);
 
        printf("dsize: %x\n", dsize);
 
 
 
        while(sections--) {
 
                if (fread(&coffscnhdr, sizeof(struct COFF_scnhdr), 1, inputfs) != 1) {
 
                        fclose(inputfs);
 
                        perror("readfile_coff");
 
                        exit(1);
 
                }
 
                printf("Section: %s,", coffscnhdr.s_name);
 
                printf(" size: 0x%.4x,", COFF_LONG_H(coffscnhdr.s_size));
 
                printf(" scnptr: 0x%.4x\n", COFF_LONG_H(coffscnhdr.s_scnptr));
 
        }
 
 
 
        /* loading .text section */
 
        while ((len = fread(&inputbuf, sizeof(inputbuf), 1, inputfs))) {
 
                insn = COFF_LONG_H(inputbuf);
 
                len = disassemble_insn(insn);
 
                if (len == 2) {
 
                        fseek(inputfs, -2, SEEK_CUR);
 
                        printf("readfile_coff: %x 0x%x   ", tsize, insn >> 16);
 
                }
 
                else
 
                        printf("readfile_coff: %x 0x%x   ", tsize, insn);
 
                printf("%s\n", disassembled);
 
                strtoken(disassembled, item, 1); /* opcode */
 
                strtoken(disassembled, item2, 2); /* all the remaining one/two/three operands */
 
                addprogram(item, item2);
 
                tsize -= len;
 
                if (tsize <= 0)
 
                        break;
 
        }
 
        fclose(inputfs);
 
        printf("Finished loading COFF.\n");
 
        return;
 
}
 
 
 
/* Load symbols from big-endian COFF file. */
 
 
 
void readsyms_coff(char *filename, unsigned long symptr, long syms)
 
{
 
        FILE *inputfs;
 
        struct COFF_syment coffsymhdr;
 
 
 
 
 
        if (!(inputfs = fopen(filename, "r"))) {
 
                perror("readsyms_coff");
 
                exit(1);
 
        }
 
 
 
        if (fseek(inputfs, symptr, SEEK_SET) == -1) {
 
                fclose(inputfs);
 
                perror("readsyms_coff");
 
                exit(1);
 
        }
 
 
 
        while(syms--) {
 
                if (fread(&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1) {
 
                        fclose(inputfs);
 
                        perror("readsyms_coff");
 
                        exit(1);
 
                }
 
                printf("Symbol: %s,", coffsymhdr.e.e_name);
 
                printf(" val: 0x%.8x,", COFF_LONG_H(coffsymhdr.e_value));
 
                printf(" auxs: %c\n", coffsymhdr.e_numaux);
 
                if (strlen(coffsymhdr.e.e_name))
 
                        addlabel(coffsymhdr.e.e_name, COFF_LONG_H(coffsymhdr.e_value));
 
        }
 
 
 
        fclose(inputfs);
 
        printf("Finished loading symbols.\n");
 
        return;
 
}
 
 
/* Load file and hand over every line to parse routine. */
/* Load file and hand over every line to parse routine. */
 
 
void readfile(char *filename)
void readfile_assembly(char *filename)
{
{
        FILE *inputfs;
        FILE *inputfs;
        char  inputbuf[MAXLINE_LEN];
        char  inputbuf[MAXLINE_LEN];
        char  *status;
        char  *status;
 
 
        if ((inputfs = fopen(filename, "r"))) {
        if (!(inputfs = fopen(filename, "r"))) {
 
                perror("readfile_assembly");
 
                exit(1);
 
        }
 
 
                while ((status = fgets(inputbuf, sizeof(inputbuf), inputfs))) {
                while ((status = fgets(inputbuf, sizeof(inputbuf), inputfs))) {
                        if (nonempty(inputbuf))
                        if (nonempty(inputbuf))
                                parseline(inputbuf);
                                parseline(inputbuf);
                }
                }
                fclose(inputfs);
                fclose(inputfs);
 
 
 
        return;
        }
        }
        else
 
                perror("readfile");
 
 
 
 
/* Identify file type and call appropriate readfile_X routine. It only
 
handles orX-coff-big executables at the moment. */
 
 
 
void identifyfile(char *filename)
 
{
 
        FILE *inputfs;
 
        struct COFF_filehdr coffhdr;
 
        size_t len;
 
 
 
        if (!(inputfs = fopen(filename, "r"))) {
 
                perror("identifyfile");
 
                exit(1);
 
        }
 
 
 
        if (fread(&coffhdr, sizeof(coffhdr), 1, inputfs) == 1) {
 
                if (COFF_SHORT_H(coffhdr.f_magic) == 0x17a) {
 
                        unsigned long opthdr_size;
 
                        printf("COFF magic: 0x%.4x\n", COFF_SHORT_H(coffhdr.f_magic));
 
                        printf("COFF flags: 0x%.4x\n", COFF_SHORT_H(coffhdr.f_flags));
 
                        printf("COFF symptr: 0x%.8x\n", COFF_LONG_H(coffhdr.f_symptr));
 
                        if ((COFF_SHORT_H(coffhdr.f_flags) & COFF_F_EXEC) != COFF_F_EXEC) {
 
                                printf("This COFF is not an executable.\n");
 
                                exit(1);
 
                        }
 
                        opthdr_size = COFF_SHORT_H(coffhdr.f_opthdr);
 
                        if (opthdr_size != sizeof(COFF_AOUTHDR)) {
 
                                printf("COFF optional header is missing or not recognized.\n");
 
                                printf("COFF f_opthdr: 0x%.2x\n", opthdr_size);
 
                                exit(1);
 
                        }
 
                        fclose(inputfs);
 
                        readfile_coff(filename, COFF_SHORT_H(coffhdr.f_nscns));
 
                        readsyms_coff(filename, COFF_LONG_H(coffhdr.f_symptr), COFF_LONG_H(coffhdr.f_nsyms));
        return;
        return;
}
}
 
                else {
 
                        printf("Not COFF, trying to load as assembly.\n");
 
                        fclose(inputfs);
 
                        readfile_assembly(filename);
 
                        return;
 
                }
 
        }
 
        else
 
                perror("identifyfile");
 
 
 
        fclose(inputfs);
 
 
 
        return;
 
}
 
 
void loadcode(char *filename)
void loadcode(char *filename)
{
{
        freemem = 0;
        freemem = 0;
        memset(mem, 0, sizeof(mem));
        memset(mem, 0, sizeof(mem));
        readfile(filename);
        identifyfile(filename);
        return;
        return;
}
}
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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