Adding Hex2_linker test
This commit is contained in:
parent
faed59f88c
commit
dc32e7d4ba
|
@ -31,6 +31,8 @@ Added string_length function to string.c
|
||||||
Added function numerate_string for converting string to integer
|
Added function numerate_string for converting string to integer
|
||||||
Added supporting hex2char, char2hex, dec2char and char2dec functions
|
Added supporting hex2char, char2hex, dec2char and char2dec functions
|
||||||
Added support bitwise xor
|
Added support bitwise xor
|
||||||
|
Added Blood-elf test
|
||||||
|
Added Hex2_linker test
|
||||||
|
|
||||||
** Changed
|
** Changed
|
||||||
Improving Documentation to help new programmers get functional
|
Improving Documentation to help new programmers get functional
|
||||||
|
|
5
makefile
5
makefile
|
@ -53,6 +53,7 @@ clean:
|
||||||
./test/test19/cleanup.sh
|
./test/test19/cleanup.sh
|
||||||
./test/test20/cleanup.sh
|
./test/test20/cleanup.sh
|
||||||
./test/test21/cleanup.sh
|
./test/test21/cleanup.sh
|
||||||
|
./test/test22/cleanup.sh
|
||||||
./test/test99/cleanup.sh
|
./test/test99/cleanup.sh
|
||||||
./test/test100/cleanup.sh
|
./test/test100/cleanup.sh
|
||||||
|
|
||||||
|
@ -86,6 +87,7 @@ test: test00-binary \
|
||||||
test19-binary \
|
test19-binary \
|
||||||
test20-binary \
|
test20-binary \
|
||||||
test21-binary \
|
test21-binary \
|
||||||
|
test22-binary \
|
||||||
test99-binary \
|
test99-binary \
|
||||||
test100-binary | results
|
test100-binary | results
|
||||||
sha256sum -c test/test.answers
|
sha256sum -c test/test.answers
|
||||||
|
@ -156,6 +158,9 @@ test20-binary: M2-Planet | results
|
||||||
test21-binary: M2-Planet | results
|
test21-binary: M2-Planet | results
|
||||||
test/test21/hello.sh
|
test/test21/hello.sh
|
||||||
|
|
||||||
|
test22-binary: M2-Planet | results
|
||||||
|
test/test22/hello.sh
|
||||||
|
|
||||||
test99-binary: M2-Planet | results
|
test99-binary: M2-Planet | results
|
||||||
test/test99/hello.sh
|
test/test99/hello.sh
|
||||||
|
|
||||||
|
|
|
@ -21,4 +21,5 @@ ca2c1321cbcbf3f551860fc0857d0a816660ba541987f9ed7f92f8553cd6b06b test/results/t
|
||||||
33f7802c581d3b6382a1b63211564529419769a9788b5a5cac856e45b9eac57c test/results/test19-binary
|
33f7802c581d3b6382a1b63211564529419769a9788b5a5cac856e45b9eac57c test/results/test19-binary
|
||||||
6fa44153ee3f27f0df49b282c0bb3017dbfaea906073c8c02b8bf5ad4d4a7860 test/results/test20-binary
|
6fa44153ee3f27f0df49b282c0bb3017dbfaea906073c8c02b8bf5ad4d4a7860 test/results/test20-binary
|
||||||
927094465f6772eaf9cc7d388b351a7e178ea6798476f87776d7dd44e9cfc072 test/results/test21-binary
|
927094465f6772eaf9cc7d388b351a7e178ea6798476f87776d7dd44e9cfc072 test/results/test21-binary
|
||||||
|
49eaa0c479d2a327d968e78a56baae36f5f18193062e885232727edadc5b7a2d test/results/test22-binary
|
||||||
ba3d9623c6512bc327cf934d994e5327e5fad3f7500896e2d8458467fae9b9e9 test/results/test99-binary
|
ba3d9623c6512bc327cf934d994e5327e5fad3f7500896e2d8458467fae9b9e9 test/results/test99-binary
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# Ignore the files created by script
|
# Ignore the files created by script
|
||||||
*.M1
|
*.M1
|
||||||
*.hex2
|
*.hex2
|
||||||
|
proof
|
||||||
|
|
||||||
# A place to put a good run for comparison
|
# A place to put a good run for comparison
|
||||||
actual.M1
|
actual.M1
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Ignore the files created by script
|
||||||
|
*.M1
|
||||||
|
*.hex2
|
||||||
|
proof
|
||||||
|
|
||||||
|
# A place to put a good run for comparison
|
||||||
|
actual.M1
|
|
@ -0,0 +1,5 @@
|
||||||
|
#! /bin/sh
|
||||||
|
rm -f test/test22/hex2_linker.M1
|
||||||
|
rm -f test/test22/hex2_linker.hex2
|
||||||
|
rm -f test/test22/proof
|
||||||
|
exit 0
|
|
@ -0,0 +1,50 @@
|
||||||
|
#! /bin/sh
|
||||||
|
set -x
|
||||||
|
# Build the test
|
||||||
|
./bin/M2-Planet -f test/functions/exit.c \
|
||||||
|
-f test/functions/file.c \
|
||||||
|
-f test/functions/file_print.c \
|
||||||
|
-f test/functions/malloc.c \
|
||||||
|
-f test/functions/calloc.c \
|
||||||
|
-f test/functions/match.c \
|
||||||
|
-f test/functions/numerate_number.c \
|
||||||
|
-f test/functions/stat.c \
|
||||||
|
-f test/test22/hex2_linker.c \
|
||||||
|
-o test/test22/hex2_linker.M1 || exit 1
|
||||||
|
|
||||||
|
# Macro assemble with libc written in M1-Macro
|
||||||
|
M1 -f test/common_x86/x86_defs.M1 \
|
||||||
|
-f test/functions/libc-core.M1 \
|
||||||
|
-f test/test22/hex2_linker.M1 \
|
||||||
|
--LittleEndian \
|
||||||
|
--Architecture 1 \
|
||||||
|
-o test/test22/hex2_linker.hex2 || exit 2
|
||||||
|
|
||||||
|
# Resolve all linkages
|
||||||
|
hex2 -f test/common_x86/ELF-i386.hex2 \
|
||||||
|
-f test/test22/hex2_linker.hex2 \
|
||||||
|
--LittleEndian \
|
||||||
|
--Architecture 1 \
|
||||||
|
--BaseAddress 0x8048000 \
|
||||||
|
-o test/results/test22-binary \
|
||||||
|
--exec_enable || exit 3
|
||||||
|
|
||||||
|
# Ensure binary works if host machine supports test
|
||||||
|
if [ "$(get_machine)" = "x86_64" ]
|
||||||
|
then
|
||||||
|
# Verify that the compiled program returns the correct result
|
||||||
|
out=$(./test/results/test22-binary --version 2>&1 )
|
||||||
|
[ 0 = $? ] || exit 4
|
||||||
|
[ "$out" = "hex2 0.3" ] || exit 5
|
||||||
|
|
||||||
|
# Verify that the resulting file works
|
||||||
|
./test/results/test22-binary -f test/common_x86/ELF-i386.hex2 \
|
||||||
|
-f test/test22/hex2_linker.hex2 \
|
||||||
|
--LittleEndian \
|
||||||
|
--Architecture 1 \
|
||||||
|
--BaseAddress 0x8048000 \
|
||||||
|
-o test/test22/proof || exit 6
|
||||||
|
out=$(sha256sum -c test/test22/proof.answer)
|
||||||
|
[ "$out" = "test/test22/proof: OK" ] || exit 7
|
||||||
|
fi
|
||||||
|
exit 0
|
|
@ -0,0 +1,529 @@
|
||||||
|
/* -*- 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 MES
|
||||||
|
*
|
||||||
|
* MES 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.
|
||||||
|
*
|
||||||
|
* MES 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>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.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);
|
||||||
|
char* numerate_number(int a);
|
||||||
|
int numerate_string(char *a);
|
||||||
|
|
||||||
|
struct input_files
|
||||||
|
{
|
||||||
|
struct input_files* next;
|
||||||
|
char* filename;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct entry
|
||||||
|
{
|
||||||
|
struct entry* next;
|
||||||
|
unsigned target;
|
||||||
|
char* name;
|
||||||
|
};
|
||||||
|
|
||||||
|
FILE* output;
|
||||||
|
struct entry* jump_table;
|
||||||
|
int BigEndian;
|
||||||
|
int Base_Address;
|
||||||
|
int Architecture;
|
||||||
|
int ByteMode;
|
||||||
|
int exec_enable;
|
||||||
|
int ip;
|
||||||
|
char* scratch;
|
||||||
|
char* scratch2;
|
||||||
|
|
||||||
|
int consume_token(FILE* source_file, char* s)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
int c = fgetc(source_file);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if(NULL != s) s[i] = c;
|
||||||
|
i = i + 1;
|
||||||
|
c = fgetc(source_file);
|
||||||
|
} while((' ' != c) && ('\t' != c) && ('\n' != c) && '>' != c);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned GetTarget(char* c)
|
||||||
|
{
|
||||||
|
struct entry* i;
|
||||||
|
for(i = jump_table; NULL != i; i = i->next)
|
||||||
|
{
|
||||||
|
if(match(c, i->name))
|
||||||
|
{
|
||||||
|
return i->target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_print("Target label ", stderr);
|
||||||
|
file_print(c, stderr);
|
||||||
|
file_print(" is not valid\n", stderr);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int storeLabel(FILE* source_file, int ip)
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
int c = consume_token(source_file, entry->name);
|
||||||
|
|
||||||
|
/* Ensure we have target address */
|
||||||
|
entry->target = ip;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void range_check(int displacement, int number_of_bytes)
|
||||||
|
{
|
||||||
|
if(4 == number_of_bytes) return;
|
||||||
|
else if (3 == number_of_bytes)
|
||||||
|
{
|
||||||
|
if((8388607 < displacement) || (displacement < -8388608))
|
||||||
|
{
|
||||||
|
file_print("A displacement of ", stderr);
|
||||||
|
file_print(numerate_number(displacement), stderr);
|
||||||
|
file_print(" does not fit in 3 bytes\n", stderr);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (2 == number_of_bytes)
|
||||||
|
{
|
||||||
|
if((32767 < displacement) || (displacement < -32768))
|
||||||
|
{
|
||||||
|
file_print("A displacement of ", stderr);
|
||||||
|
file_print(numerate_number(displacement), stderr);
|
||||||
|
file_print(" does not fit in 2 bytes\n", stderr);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (1 == number_of_bytes)
|
||||||
|
{
|
||||||
|
if((127 < displacement) || (displacement < -128))
|
||||||
|
{
|
||||||
|
file_print("A displacement of ", stderr);
|
||||||
|
file_print(numerate_number(displacement), stderr);
|
||||||
|
file_print(" does not fit in 1 byte\n", stderr);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
file_print("Invalid number of bytes given\n", stderr);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void outputPointer(int displacement, int number_of_bytes)
|
||||||
|
{
|
||||||
|
unsigned value = displacement;
|
||||||
|
|
||||||
|
/* HALT HARD if we are going to do something BAD*/
|
||||||
|
range_check(displacement, number_of_bytes);
|
||||||
|
|
||||||
|
if(BigEndian)
|
||||||
|
{ /* Deal with BigEndian */
|
||||||
|
if(4 == number_of_bytes) fputc((value >> 24), output);
|
||||||
|
if(3 <= number_of_bytes) fputc(((value >> 16)%256), output);
|
||||||
|
if(2 <= number_of_bytes) fputc(((value >> 8)%256), output);
|
||||||
|
if(1 <= number_of_bytes) fputc((value % 256), output);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* Deal with LittleEndian */
|
||||||
|
while(number_of_bytes > 0)
|
||||||
|
{
|
||||||
|
unsigned byte = value % 256;
|
||||||
|
value = value / 256;
|
||||||
|
fputc(byte, output);
|
||||||
|
number_of_bytes = number_of_bytes - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Architectural_displacement(int target, int base)
|
||||||
|
{
|
||||||
|
if(0 == Architecture) return (target - base);
|
||||||
|
else if(1 == Architecture) return (target - base);
|
||||||
|
else if(2 == Architecture) return (target - base);
|
||||||
|
|
||||||
|
file_print("Unknown Architecture, aborting before harm is done\n", stderr);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ConsumePointer(char ch, FILE* source_file, char* s)
|
||||||
|
{
|
||||||
|
/* Calculate pointer size*/
|
||||||
|
if((37 == ch) || (38 == ch)) ip = ip + 4; /* Deal with % and & */
|
||||||
|
else if((64 == ch) || (36 == ch)) ip = ip + 2; /* Deal with @ and $ */
|
||||||
|
else if(33 == ch) ip = ip + 1; /* Deal with ! */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file_print("storePointer given unknown\n", stderr);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return consume_token(source_file, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void storePointer(char ch, FILE* source_file)
|
||||||
|
{
|
||||||
|
/* Get string of pointer */
|
||||||
|
memset (scratch, 0, max_string + 1);
|
||||||
|
int base_sep_p = (ConsumePointer(ch, source_file, scratch) == 62); /* '>' */
|
||||||
|
|
||||||
|
/* Lookup token */
|
||||||
|
int target = GetTarget(scratch);
|
||||||
|
int displacement;
|
||||||
|
|
||||||
|
int base = ip;
|
||||||
|
/* Change relative base address to :<base> */
|
||||||
|
if (base_sep_p)
|
||||||
|
{
|
||||||
|
memset (scratch2, 0, max_string + 1);
|
||||||
|
consume_token (source_file, scratch2);
|
||||||
|
base = GetTarget (scratch2);
|
||||||
|
}
|
||||||
|
|
||||||
|
displacement = Architectural_displacement(target, base);
|
||||||
|
|
||||||
|
/* output calculated difference */
|
||||||
|
if(33 == ch) outputPointer(displacement, 1); /* Deal with ! */
|
||||||
|
else if(36 == ch) outputPointer(target, 2); /* Deal with $ */
|
||||||
|
else if(64 == ch) outputPointer(displacement, 2); /* Deal with @ */
|
||||||
|
else if(38 == ch) outputPointer(target, 4); /* Deal with & */
|
||||||
|
else if(37 == ch) outputPointer(displacement, 4); /* Deal with % */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file_print("storePointer reached impossible case: ch=", stderr);
|
||||||
|
fputc(ch, stderr);
|
||||||
|
file_print("\n", stderr);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void line_Comment(FILE* source_file)
|
||||||
|
{
|
||||||
|
int c = fgetc(source_file);
|
||||||
|
while((10 != c) && (13 != c))
|
||||||
|
{
|
||||||
|
c = fgetc(source_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int hex(int c, FILE* source_file)
|
||||||
|
{
|
||||||
|
if (c >= '0' && c <= '9') return (c - 48);
|
||||||
|
else if (c >= 'a' && c <= 'z') return (c - 87);
|
||||||
|
else if (c >= 'A' && c <= 'Z') return (c - 55);
|
||||||
|
else if (c == '#' || c == ';') line_Comment(source_file);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int octal(int c, FILE* source_file)
|
||||||
|
{
|
||||||
|
if (c >= '0' && c <= '7') return (c - 48);
|
||||||
|
else if (c == '#' || c == ';') line_Comment(source_file);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int binary(int c, FILE* source_file)
|
||||||
|
{
|
||||||
|
if (c == '0' || c == '1') return (c - 48);
|
||||||
|
else if (c == '#' || c == ';') line_Comment(source_file);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int hold;
|
||||||
|
int toggle;
|
||||||
|
void process_byte(char c, FILE* source_file, int write)
|
||||||
|
{
|
||||||
|
if(16 == ByteMode)
|
||||||
|
{
|
||||||
|
if(0 <= hex(c, source_file))
|
||||||
|
{
|
||||||
|
if(toggle)
|
||||||
|
{
|
||||||
|
if(write) fputc(((hold * 16)) + hex(c, source_file), output);
|
||||||
|
ip = ip + 1;
|
||||||
|
hold = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hold = hex(c, source_file);
|
||||||
|
}
|
||||||
|
toggle = !toggle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(8 ==ByteMode)
|
||||||
|
{
|
||||||
|
if(0 <= octal(c, source_file))
|
||||||
|
{
|
||||||
|
if(2 == toggle)
|
||||||
|
{
|
||||||
|
if(write) fputc(((hold * 8)) + octal(c, source_file), output);
|
||||||
|
ip = ip + 1;
|
||||||
|
hold = 0;
|
||||||
|
toggle = 0;
|
||||||
|
}
|
||||||
|
else if(1 == toggle)
|
||||||
|
{
|
||||||
|
hold = ((hold * 8) + octal(c, source_file));
|
||||||
|
toggle = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hold = octal(c, source_file);
|
||||||
|
toggle = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(2 == ByteMode)
|
||||||
|
{
|
||||||
|
if(0 <= binary(c, source_file))
|
||||||
|
{
|
||||||
|
if(7 == toggle)
|
||||||
|
{
|
||||||
|
if(write) fputc((hold * 2) + binary(c, source_file), output);
|
||||||
|
ip = ip + 1;
|
||||||
|
hold = 0;
|
||||||
|
toggle = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hold = ((hold * 2) + binary(c, source_file));
|
||||||
|
toggle = toggle + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void first_pass(struct input_files* input)
|
||||||
|
{
|
||||||
|
if(NULL == input) return;
|
||||||
|
first_pass(input->next);
|
||||||
|
FILE* source_file = fopen(input->filename, "r");
|
||||||
|
|
||||||
|
if(NULL == source_file)
|
||||||
|
{
|
||||||
|
file_print("The file: ", stderr);
|
||||||
|
file_print(input->filename, stderr);
|
||||||
|
file_print(" can not be opened!\n", stderr);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggle = FALSE;
|
||||||
|
int c;
|
||||||
|
for(c = fgetc(source_file); EOF != c; c = fgetc(source_file))
|
||||||
|
{
|
||||||
|
/* Check for and deal with label */
|
||||||
|
if(58 == c)
|
||||||
|
{
|
||||||
|
c = storeLabel(source_file, ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for and deal with relative/absolute pointers to labels */
|
||||||
|
if((33 == c) || (64 == c) || (36 == c) || (37 == c) || (38 == c))
|
||||||
|
{ /* deal with 1byte pointer !; 2byte pointers (@ and $); 4byte pointers (% and &) */
|
||||||
|
c = ConsumePointer(c, source_file, NULL);
|
||||||
|
if (62 == c)
|
||||||
|
{ /* deal with label>base */
|
||||||
|
c = consume_token (source_file, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else process_byte(c, source_file, FALSE);
|
||||||
|
}
|
||||||
|
fclose(source_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
void second_pass(struct input_files* input)
|
||||||
|
{
|
||||||
|
if(NULL == input) return;
|
||||||
|
second_pass(input->next);
|
||||||
|
FILE* source_file = fopen(input->filename, "r");
|
||||||
|
|
||||||
|
/* Something that should never happen */
|
||||||
|
if(NULL == source_file)
|
||||||
|
{
|
||||||
|
file_print("The file: ", stderr);
|
||||||
|
file_print(input->filename, stderr);
|
||||||
|
file_print(" can not be opened!\nWTF-pass2\n", stderr);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggle = FALSE;
|
||||||
|
hold = 0;
|
||||||
|
|
||||||
|
int c;
|
||||||
|
for(c = fgetc(source_file); EOF != c; c = fgetc(source_file))
|
||||||
|
{
|
||||||
|
if(58 == c) c = consume_token(source_file, NULL); /* Deal with : */
|
||||||
|
else if((33 == c) || (64 == c) || (36 == c) || (37 == c) || (38 == c)) storePointer(c, source_file); /* Deal with !, @, $, % and & */
|
||||||
|
else process_byte(c, source_file, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(source_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Standard C main program */
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
BigEndian = TRUE;
|
||||||
|
jump_table = NULL;
|
||||||
|
Architecture = 0;
|
||||||
|
Base_Address = 0;
|
||||||
|
struct input_files* input = NULL;
|
||||||
|
output = stdout;
|
||||||
|
char* output_file = "";
|
||||||
|
exec_enable = FALSE;
|
||||||
|
ByteMode = 16;
|
||||||
|
scratch = calloc(max_string + 1, sizeof(char));
|
||||||
|
scratch2 = calloc(max_string + 1, sizeof(char));
|
||||||
|
|
||||||
|
int option_index = 1;
|
||||||
|
while(option_index <= argc)
|
||||||
|
{
|
||||||
|
if(NULL == argv[option_index])
|
||||||
|
{
|
||||||
|
option_index = option_index + 1;
|
||||||
|
}
|
||||||
|
else if(match(argv[option_index], "--BigEndian"))
|
||||||
|
{
|
||||||
|
BigEndian = TRUE;
|
||||||
|
option_index = option_index + 1;
|
||||||
|
}
|
||||||
|
else if(match(argv[option_index], "--LittleEndian"))
|
||||||
|
{
|
||||||
|
BigEndian = FALSE;
|
||||||
|
option_index = option_index + 1;
|
||||||
|
}
|
||||||
|
else if(match(argv[option_index], "--exec_enable"))
|
||||||
|
{
|
||||||
|
exec_enable = TRUE;
|
||||||
|
option_index = option_index + 1;
|
||||||
|
}
|
||||||
|
else if(match(argv[option_index], "-A") || match(argv[option_index], "--Architecture"))
|
||||||
|
{
|
||||||
|
Architecture = numerate_string(argv[option_index + 1]);
|
||||||
|
option_index = option_index + 2;
|
||||||
|
}
|
||||||
|
else if(match(argv[option_index], "-b") || match(argv[option_index], "--binary"))
|
||||||
|
{
|
||||||
|
ByteMode = 2;
|
||||||
|
option_index = option_index + 1;
|
||||||
|
}
|
||||||
|
else if(match(argv[option_index], "-B") || match(argv[option_index], "--BaseAddress"))
|
||||||
|
{
|
||||||
|
Base_Address = numerate_string(argv[option_index + 1]);
|
||||||
|
option_index = option_index + 2;
|
||||||
|
}
|
||||||
|
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} (--BigEndian|--LittleEndian)", stderr);
|
||||||
|
file_print(" [--BaseAddress 12345] [--Architecture 12345]\nArchitecture", stderr);
|
||||||
|
file_print(" 0: Knight; 1: x86; 2: AMD64\nTo leverage octal or binary", stderr);
|
||||||
|
file_print(" input: --octal, --binary\n", stderr);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
else if(match(argv[option_index], "-f") || match(argv[option_index], "--file"))
|
||||||
|
{
|
||||||
|
struct input_files* temp = calloc(1, sizeof(struct input_files));
|
||||||
|
temp->filename = 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(argv[option_index + 1], stderr);
|
||||||
|
file_print(" can not be opened!\n", stderr);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
option_index = option_index + 2;
|
||||||
|
}
|
||||||
|
else if(match(argv[option_index], "-O") || match(argv[option_index], "--octal"))
|
||||||
|
{
|
||||||
|
ByteMode = 8;
|
||||||
|
option_index = option_index + 1;
|
||||||
|
}
|
||||||
|
else if(match(argv[option_index], "-V") || match(argv[option_index], "--version"))
|
||||||
|
{
|
||||||
|
file_print("hex2 0.3\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 */
|
||||||
|
ip = Base_Address;
|
||||||
|
first_pass(input);
|
||||||
|
|
||||||
|
/* Fix all the references*/
|
||||||
|
ip = Base_Address;
|
||||||
|
second_pass(input);
|
||||||
|
|
||||||
|
/* Set file as executable */
|
||||||
|
if(exec_enable)
|
||||||
|
{
|
||||||
|
/* 488 = 750 in octal */
|
||||||
|
if(0 != chmod(output_file, 488))
|
||||||
|
{
|
||||||
|
file_print("Unable to change permissions\n", stderr);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
49eaa0c479d2a327d968e78a56baae36f5f18193062e885232727edadc5b7a2d test/test22/proof
|
Loading…
Reference in New Issue