12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004 |
- ## 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 functions/numerate_number.c functions/stat.c test/test22/hex2_linker.c >| ../stage0/stage3/hex2_linker_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;
- }
- /* 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<stdlib.h>
- #include<string.h>
- // void* calloc(int count, int size);
- #define TRUE 1
- //CONSTANT TRUE 1
- #define FALSE 0
- //CONSTANT FALSE 0
- char* numerate_number(int a)
- {
- char* result = calloc(16, sizeof(char));
- int i = 0;
- /* Deal with Zero case */
- if(0 == a)
- {
- result[0] = '0';
- return result;
- }
- /* Deal with negatives */
- if(0 > a)
- {
- result[0] = '-';
- i = 1;
- a = a * -1;
- }
- /* Using the largest 10^n number possible in 32bits */
- int divisor = 0x3B9ACA00;
- /* Skip leading Zeros */
- while(0 == (a / divisor)) divisor = divisor / 10;
- /* Now simply collect numbers until divisor is gone */
- while(0 < divisor)
- {
- result[i] = ((a / divisor) + 48);
- a = a % divisor;
- divisor = divisor / 10;
- i = i + 1;
- }
- return result;
- }
- int char2hex(int c)
- {
- if (c >= '0' && c <= '9') return (c - 48);
- else if (c >= 'a' && c <= 'f') return (c - 87);
- else if (c >= 'A' && c <= 'F') return (c - 55);
- else return -1;
- }
- int hex2char(int c)
- {
- if((c >= 0) && (c <= 9)) return (c + 48);
- else if((c >= 10) && (c <= 15)) return (c + 55);
- else return -1;
- }
- int char2dec(int c)
- {
- if (c >= '0' && c <= '9') return (c - 48);
- else return -1;
- }
- int dec2char(int c)
- {
- if((c >= 0) && (c <= 9)) return (c + 48);
- else return -1;
- }
- int numerate_string(char *a)
- {
- int count = 0;
- int index;
- int negative;
- /* If NULL string */
- if(0 == a[0])
- {
- return 0;
- }
- /* Deal with hex */
- else if (a[0] == '0' && a[1] == 'x')
- {
- if('-' == a[2])
- {
- negative = TRUE;
- index = 3;
- }
- else
- {
- negative = FALSE;
- index = 2;
- }
- while(0 != a[index])
- {
- if(-1 == char2hex(a[index])) return 0;
- count = (16 * count) + char2hex(a[index]);
- index = index + 1;
- }
- }
- /* Deal with decimal */
- else
- {
- if('-' == a[0])
- {
- negative = TRUE;
- index = 1;
- }
- else
- {
- negative = FALSE;
- index = 0;
- }
- while(0 != a[index])
- {
- if(-1 == char2dec(a[index])) return 0;
- count = (10 * count) + char2dec(a[index]);
- index = index + 1;
- }
- }
- if(negative)
- {
- count = count * -1;
- }
- return count;
- }
- ## 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/>.
- /*
- * chmod() changes the mode of the file specified whose pathname is given in
- * pathname, which is dereferenced if it is a symbolic link.
- * fchmod() changes the mode of the file referred to by the open file
- * descriptor fd.
- * The new file mode is specified in mode, which is a bit mask created by
- * ORing together zero or more of the following:
- * S_ISUID (04000) set-user-ID (set process effective user ID on execve(2))
- * S_ISGID (02000) set-group-ID (set process effective group ID on execve(2)
- * mandatory locking, as described in fcntl(2); take a new file's group from
- * parent directory, as described in chown(2) and mkdir(2))
- * S_ISVTX (01000) sticky bit (restricted deletion flag, as described in
- * unlink(2))
- * S_IRUSR (00400) read by owner
- * S_IWUSR (00200) write by owner
- * S_IXUSR (00100) execute/search by owner ("search" applies for directories
- * , and means that entries within the directory can be accessed)
- * S_IRGRP (00040) read by group
- * S_IWGRP (00020) write by group
- * S_IXGRP (00010) execute/search by group
- * S_IROTH (00004) read by others
- * S_IWOTH (00002) write by others
- * S_IXOTH (00001) execute/search by others
- */
- int chmod(char *pathname, int mode)
- {
- asm("LOAD_EFFECTIVE_ADDRESS_ebx %8"
- "LOAD_INTEGER_ebx"
- "LOAD_EFFECTIVE_ADDRESS_ecx %4"
- "LOAD_INTEGER_ecx"
- "LOAD_IMMEDIATE_eax %15"
- "INT_80");
- }
- /* -*- 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 <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);
- else if(40 == 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)
- {
- if(40 == Architecture) outputPointer(displacement - 7, 1); /* Deal with ! */
- else 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; 40: armv7", stderr);
- file_print("\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;
- }
|