516 lines
12 KiB
C
516 lines
12 KiB
C
## This file was generated by running:
|
|
## cat functions/exit.c functions/file.c functions/file_print.c functions/malloc.c functions/calloc.c functions/match.c test/test21/blood-elf.c >| ../stage0/stage3/blood-elf_x86.c
|
|
## inside of M2-Planet's source repo
|
|
|
|
## Copyright (C) 2016 Jeremiah Orians
|
|
## This file is part of stage0.
|
|
##
|
|
## stage0 is free software: you can redistribute it and/or modify
|
|
## it under the terms of the GNU General Public License as published by
|
|
## the Free Software Foundation, either version 3 of the License, or
|
|
## (at your option) any later version.
|
|
##
|
|
## stage0 is distributed in the hope that it will be useful,
|
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
## GNU General Public License for more details.
|
|
##
|
|
## You should have received a copy of the GNU General Public License
|
|
## along with stage0. If not, see <http://www.gnu.org/licenses/>.
|
|
// CONSTANT EXIT_FAILURE 1
|
|
// CONSTANT EXIT_SUCCESS 0
|
|
|
|
void exit(int value)
|
|
{
|
|
asm("POP_ebx"
|
|
"POP_ebx"
|
|
"LOAD_IMMEDIATE_eax %1"
|
|
"INT_80");
|
|
}
|
|
/* Copyright (C) 2016 Jeremiah Orians
|
|
* This file is part of stage0.
|
|
*
|
|
* stage0 is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* stage0 is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with stage0. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
// CONSTANT stdin 0
|
|
// CONSTANT stdout 1
|
|
// CONSTANT stderr 2
|
|
// CONSTANT EOF 0xFFFFFFFF
|
|
|
|
int fgetc(FILE* f)
|
|
{
|
|
asm("LOAD_IMMEDIATE_eax %3"
|
|
"LOAD_EFFECTIVE_ADDRESS_ebx %4"
|
|
"LOAD_INTEGER_ebx"
|
|
"PUSH_ebx"
|
|
"COPY_esp_to_ecx"
|
|
"LOAD_IMMEDIATE_edx %1"
|
|
"INT_80"
|
|
"TEST"
|
|
"POP_eax"
|
|
"JUMP_NE8 !FUNCTION_fgetc_Done"
|
|
"LOAD_IMMEDIATE_eax %-1"
|
|
":FUNCTION_fgetc_Done");
|
|
}
|
|
|
|
void fputc(char s, FILE* f)
|
|
{
|
|
asm("LOAD_IMMEDIATE_eax %4"
|
|
"LOAD_EFFECTIVE_ADDRESS_ebx %4"
|
|
"LOAD_INTEGER_ebx"
|
|
"LOAD_EFFECTIVE_ADDRESS_ecx %8"
|
|
"LOAD_IMMEDIATE_edx %1"
|
|
"INT_80");
|
|
}
|
|
|
|
/* Important values needed for open
|
|
* O_RDONLY => 0
|
|
* O_WRONLY => 1
|
|
* O_RDWR => 2
|
|
* O_CREAT => 64
|
|
* O_TRUNC => 512
|
|
* S_IRWXU => 00700
|
|
* S_IXUSR => 00100
|
|
* S_IWUSR => 00200
|
|
* S_IRUSR => 00400
|
|
*/
|
|
|
|
FILE* open(char* name, int flag, int mode)
|
|
{
|
|
asm("LOAD_EFFECTIVE_ADDRESS_ebx %12"
|
|
"LOAD_INTEGER_ebx"
|
|
"LOAD_EFFECTIVE_ADDRESS_ecx %8"
|
|
"LOAD_INTEGER_ecx"
|
|
"LOAD_EFFECTIVE_ADDRESS_edx %4"
|
|
"LOAD_INTEGER_edx"
|
|
"LOAD_IMMEDIATE_eax %5"
|
|
"INT_80");
|
|
}
|
|
|
|
FILE* fopen(char* filename, char* mode)
|
|
{
|
|
FILE* f;
|
|
if('w' == mode[0])
|
|
{ /* 577 is O_WRONLY|O_CREAT|O_TRUNC, 384 is 600 in octal */
|
|
f = open(filename, 577 , 384);
|
|
}
|
|
else
|
|
{ /* Everything else is a read */
|
|
f = open(filename, 0, 0);
|
|
}
|
|
|
|
/* Negative numbers are error codes */
|
|
if(0 > f)
|
|
{
|
|
return 0;
|
|
}
|
|
return f;
|
|
}
|
|
|
|
int close(int fd)
|
|
{
|
|
asm("LOAD_EFFECTIVE_ADDRESS_ebx %4"
|
|
"LOAD_IMMEDIATE_eax %6"
|
|
"INT_80");
|
|
}
|
|
int fclose(FILE* stream)
|
|
{
|
|
int error = close(stream);
|
|
return error;
|
|
}
|
|
/* Copyright (C) 2016 Jeremiah Orians
|
|
* This file is part of stage0.
|
|
*
|
|
* stage0 is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* stage0 is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with stage0. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#include<stdio.h>
|
|
// void fputc(char s, FILE* f);
|
|
|
|
void file_print(char* s, FILE* f)
|
|
{
|
|
while(0 != s[0])
|
|
{
|
|
fputc(s[0], f);
|
|
s = s + 1;
|
|
}
|
|
}
|
|
## Copyright (C) 2016 Jeremiah Orians
|
|
## This file is part of stage0.
|
|
##
|
|
## stage0 is free software: you can redistribute it and/or modify
|
|
## it under the terms of the GNU General Public License as published by
|
|
## the Free Software Foundation, either version 3 of the License, or
|
|
## (at your option) any later version.
|
|
##
|
|
## stage0 is distributed in the hope that it will be useful,
|
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
## GNU General Public License for more details.
|
|
##
|
|
## You should have received a copy of the GNU General Public License
|
|
## along with stage0. If not, see <http://www.gnu.org/licenses/>.
|
|
// CONSTANT NULL 0
|
|
|
|
void* malloc(int size)
|
|
{
|
|
asm("STORE_eax_into_ESP_IMMEDIATE8 !4"
|
|
"PUSH_eax"
|
|
"LOAD_IMMEDIATE_eax %45"
|
|
"LOAD_IMMEDIATE_ebx %0"
|
|
"INT_80"
|
|
"POP_ebx"
|
|
"ADD_eax_to_ebx"
|
|
"PUSH_eax"
|
|
"PUSH_ebx"
|
|
"LOAD_IMMEDIATE_eax %45"
|
|
"INT_80"
|
|
"POP_ebx"
|
|
"CMP"
|
|
"POP_eax"
|
|
"JUMP_EQ8 !FUNCTION_malloc_Done"
|
|
"LOAD_IMMEDIATE_eax %-1"
|
|
":FUNCTION_malloc_Done");
|
|
}
|
|
/* Copyright (C) 2016 Jeremiah Orians
|
|
* This file is part of stage0.
|
|
*
|
|
* stage0 is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* stage0 is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with stage0. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
// void* malloc(int size);
|
|
|
|
void* memset(void* ptr, int value, int num)
|
|
{
|
|
char* s;
|
|
for(s = ptr; 0 < num; num = num - 1)
|
|
{
|
|
s[0] = value;
|
|
s = s + 1;
|
|
}
|
|
}
|
|
|
|
void* calloc(int count, int size)
|
|
{
|
|
void* ret = malloc(count * size);
|
|
memset(ret, 0, (count * size));
|
|
return ret;
|
|
}
|
|
|
|
void free(void* l)
|
|
{
|
|
return;
|
|
}
|
|
/* Copyright (C) 2016 Jeremiah Orians
|
|
* This file is part of stage0.
|
|
*
|
|
* stage0 is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* stage0 is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with stage0. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#define FALSE 0
|
|
// CONSTANT FALSE 0
|
|
#define TRUE 1
|
|
// CONSTANT TRUE 1
|
|
|
|
int match(char* a, char* b)
|
|
{
|
|
int i = -1;
|
|
do
|
|
{
|
|
i = i + 1;
|
|
if(a[i] != b[i])
|
|
{
|
|
return FALSE;
|
|
}
|
|
} while((0 != a[i]) && (0 !=b[i]));
|
|
return TRUE;
|
|
}
|
|
/* -*- c-file-style: "linux";indent-tabs-mode:t -*- */
|
|
/* Copyright (C) 2017 Jeremiah Orians
|
|
* Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
|
|
* This file is part of mescc-tools
|
|
*
|
|
* mescc-tools is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* mescc-tools is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with mescc-tools. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <getopt.h>
|
|
#include <unistd.h>
|
|
#include <sys/stat.h>
|
|
|
|
|
|
#define max_string 4096
|
|
//CONSTANT max_string 4096
|
|
#define TRUE 1
|
|
//CONSTANT TRUE 1
|
|
#define FALSE 0
|
|
//CONSTANT FALSE 0
|
|
|
|
void file_print(char* s, FILE* f);
|
|
int match(char* a, char* b);
|
|
|
|
struct entry
|
|
{
|
|
struct entry* next;
|
|
char* name;
|
|
};
|
|
|
|
FILE* output;
|
|
struct entry* jump_table;
|
|
|
|
void consume_token(FILE* source_file, char* s)
|
|
{
|
|
int i = 0;
|
|
int c = fgetc(source_file);
|
|
do
|
|
{
|
|
s[i] = c;
|
|
i = i + 1;
|
|
c = fgetc(source_file);
|
|
} while((' ' != c) && ('\t' != c) && ('\n' != c) && '>' != c);
|
|
}
|
|
|
|
void storeLabel(FILE* source_file)
|
|
{
|
|
struct entry* entry = calloc(1, sizeof(struct entry));
|
|
|
|
/* Prepend to list */
|
|
entry->next = jump_table;
|
|
jump_table = entry;
|
|
|
|
/* Store string */
|
|
entry->name = calloc((max_string + 1), sizeof(char));
|
|
consume_token(source_file, entry->name);
|
|
|
|
/* Remove all entries that start with the forbidden char pattern :_ */
|
|
if('_' == entry->name[0])
|
|
{
|
|
jump_table = jump_table->next;
|
|
}
|
|
}
|
|
|
|
void line_Comment(FILE* source_file)
|
|
{
|
|
int c = fgetc(source_file);
|
|
while((10 != c) && (13 != c))
|
|
{
|
|
c = fgetc(source_file);
|
|
}
|
|
}
|
|
|
|
void purge_string(FILE* source_file)
|
|
{
|
|
int c = fgetc(source_file);
|
|
while((EOF != c) && (34 != c))
|
|
{
|
|
c = fgetc(source_file);
|
|
}
|
|
}
|
|
|
|
void first_pass(struct entry* input)
|
|
{
|
|
if(NULL == input) return;
|
|
first_pass(input->next);
|
|
|
|
FILE* source_file = fopen(input->name, "r");
|
|
|
|
if(NULL == source_file)
|
|
{
|
|
file_print("The file: ", stderr);
|
|
file_print(input->name, stderr);
|
|
file_print(" can not be opened!\n", stderr);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
int c;
|
|
for(c = fgetc(source_file); EOF != c; c = fgetc(source_file))
|
|
{
|
|
/* Check for and deal with label */
|
|
if(58 == c)
|
|
{
|
|
storeLabel(source_file);
|
|
}
|
|
/* Check for and deal with line comments */
|
|
else if (c == '#' || c == ';')
|
|
{
|
|
line_Comment(source_file);
|
|
}
|
|
else if (34 == c)
|
|
{
|
|
purge_string(source_file);
|
|
}
|
|
}
|
|
fclose(source_file);
|
|
}
|
|
|
|
void output_debug(struct entry* node, int stage)
|
|
{
|
|
struct entry* i;
|
|
for(i = node; NULL != i; i = i->next)
|
|
{
|
|
if(stage)
|
|
{
|
|
file_print(":ELF_str_", output);
|
|
file_print(i->name, output);
|
|
file_print("\n\x22", output);
|
|
file_print(i->name, output);
|
|
file_print("\x22\n", output);
|
|
}
|
|
else
|
|
{
|
|
file_print("%ELF_str_", output);
|
|
file_print(i->name, output);
|
|
file_print(">ELF_str\n&", output);
|
|
file_print(i->name, output);
|
|
file_print("\n%10000\n!2\n!0\n@1\n", output);
|
|
}
|
|
}
|
|
}
|
|
|
|
struct entry* reverse_list(struct entry* head)
|
|
{
|
|
struct entry* root = NULL;
|
|
struct entry* next;
|
|
while(NULL != head)
|
|
{
|
|
next = head->next;
|
|
head->next = root;
|
|
root = head;
|
|
head = next;
|
|
}
|
|
return root;
|
|
}
|
|
|
|
/* Standard C main program */
|
|
int main(int argc, char **argv)
|
|
{
|
|
jump_table = NULL;
|
|
struct entry* input = NULL;
|
|
output = stdout;
|
|
char* output_file = "";
|
|
|
|
int option_index = 1;
|
|
while(option_index <= argc)
|
|
{
|
|
if(NULL == argv[option_index])
|
|
{
|
|
option_index = option_index + 1;
|
|
}
|
|
else if(match(argv[option_index], "-h") || match(argv[option_index], "--help"))
|
|
{
|
|
file_print("Usage: ", stderr);
|
|
file_print(argv[0], stderr);
|
|
file_print(" -f FILENAME1 {-f FILENAME2}\n", stderr);
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
else if(match(argv[option_index], "-f") || match(argv[option_index], "--file"))
|
|
{
|
|
struct entry* temp = calloc(1, sizeof(struct entry));
|
|
temp->name = argv[option_index + 1];
|
|
temp->next = input;
|
|
input = temp;
|
|
option_index = option_index + 2;
|
|
}
|
|
else if(match(argv[option_index], "-o") || match(argv[option_index], "--output"))
|
|
{
|
|
output_file = argv[option_index + 1];
|
|
output = fopen(output_file, "w");
|
|
|
|
if(NULL == output)
|
|
{
|
|
file_print("The file: ", stderr);
|
|
file_print(input->name, stderr);
|
|
file_print(" can not be opened!\n", stderr);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
option_index = option_index + 2;
|
|
}
|
|
else if(match(argv[option_index], "-V") || match(argv[option_index], "--version"))
|
|
{
|
|
file_print("blood-elf 0.1\n(Basically Launches Odd Object Dump ExecutabLe Files\n", stdout);
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
else
|
|
{
|
|
file_print("Unknown option\n", stderr);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
/* Make sure we have a program tape to run */
|
|
if (NULL == input)
|
|
{
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
/* Get all of the labels */
|
|
first_pass(input);
|
|
|
|
/* Reverse their order */
|
|
jump_table = reverse_list(jump_table);
|
|
|
|
file_print(":ELF_str\n!0\n", output);
|
|
output_debug(jump_table, TRUE);
|
|
file_print("%0\n:ELF_sym\n%0\n%0\n%0\n!0\n!0\n@1\n", output);
|
|
output_debug(jump_table, FALSE);
|
|
file_print("\n:ELF_end\n", output);
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|