blood-elf_x86.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. ## This file was generated by running:
  2. ## 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
  3. ## inside of M2-Planet's source repo
  4. ## Copyright (C) 2016 Jeremiah Orians
  5. ## This file is part of stage0.
  6. ##
  7. ## stage0 is free software: you can redistribute it and/or modify
  8. ## it under the terms of the GNU General Public License as published by
  9. ## the Free Software Foundation, either version 3 of the License, or
  10. ## (at your option) any later version.
  11. ##
  12. ## stage0 is distributed in the hope that it will be useful,
  13. ## but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. ## GNU General Public License for more details.
  16. ##
  17. ## You should have received a copy of the GNU General Public License
  18. ## along with stage0. If not, see <http://www.gnu.org/licenses/>.
  19. // CONSTANT EXIT_FAILURE 1
  20. // CONSTANT EXIT_SUCCESS 0
  21. void exit(int value)
  22. {
  23. asm("POP_ebx"
  24. "POP_ebx"
  25. "LOAD_IMMEDIATE_eax %1"
  26. "INT_80");
  27. }
  28. /* Copyright (C) 2016 Jeremiah Orians
  29. * This file is part of stage0.
  30. *
  31. * stage0 is free software: you can redistribute it and/or modify
  32. * it under the terms of the GNU General Public License as published by
  33. * the Free Software Foundation, either version 3 of the License, or
  34. * (at your option) any later version.
  35. *
  36. * stage0 is distributed in the hope that it will be useful,
  37. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  38. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  39. * GNU General Public License for more details.
  40. *
  41. * You should have received a copy of the GNU General Public License
  42. * along with stage0. If not, see <http://www.gnu.org/licenses/>.
  43. */
  44. // CONSTANT stdin 0
  45. // CONSTANT stdout 1
  46. // CONSTANT stderr 2
  47. // CONSTANT EOF 0xFFFFFFFF
  48. int fgetc(FILE* f)
  49. {
  50. asm("LOAD_IMMEDIATE_eax %3"
  51. "LOAD_EFFECTIVE_ADDRESS_ebx %4"
  52. "LOAD_INTEGER_ebx"
  53. "PUSH_ebx"
  54. "COPY_esp_to_ecx"
  55. "LOAD_IMMEDIATE_edx %1"
  56. "INT_80"
  57. "TEST"
  58. "POP_eax"
  59. "JUMP_NE8 !FUNCTION_fgetc_Done"
  60. "LOAD_IMMEDIATE_eax %-1"
  61. ":FUNCTION_fgetc_Done");
  62. }
  63. void fputc(char s, FILE* f)
  64. {
  65. asm("LOAD_IMMEDIATE_eax %4"
  66. "LOAD_EFFECTIVE_ADDRESS_ebx %4"
  67. "LOAD_INTEGER_ebx"
  68. "LOAD_EFFECTIVE_ADDRESS_ecx %8"
  69. "LOAD_IMMEDIATE_edx %1"
  70. "INT_80");
  71. }
  72. /* Important values needed for open
  73. * O_RDONLY => 0
  74. * O_WRONLY => 1
  75. * O_RDWR => 2
  76. * O_CREAT => 64
  77. * O_TRUNC => 512
  78. * S_IRWXU => 00700
  79. * S_IXUSR => 00100
  80. * S_IWUSR => 00200
  81. * S_IRUSR => 00400
  82. */
  83. FILE* open(char* name, int flag, int mode)
  84. {
  85. asm("LOAD_EFFECTIVE_ADDRESS_ebx %12"
  86. "LOAD_INTEGER_ebx"
  87. "LOAD_EFFECTIVE_ADDRESS_ecx %8"
  88. "LOAD_INTEGER_ecx"
  89. "LOAD_EFFECTIVE_ADDRESS_edx %4"
  90. "LOAD_INTEGER_edx"
  91. "LOAD_IMMEDIATE_eax %5"
  92. "INT_80");
  93. }
  94. FILE* fopen(char* filename, char* mode)
  95. {
  96. FILE* f;
  97. if('w' == mode[0])
  98. { /* 577 is O_WRONLY|O_CREAT|O_TRUNC, 384 is 600 in octal */
  99. f = open(filename, 577 , 384);
  100. }
  101. else
  102. { /* Everything else is a read */
  103. f = open(filename, 0, 0);
  104. }
  105. /* Negative numbers are error codes */
  106. if(0 > f)
  107. {
  108. return 0;
  109. }
  110. return f;
  111. }
  112. int close(int fd)
  113. {
  114. asm("LOAD_EFFECTIVE_ADDRESS_ebx %4"
  115. "LOAD_IMMEDIATE_eax %6"
  116. "INT_80");
  117. }
  118. int fclose(FILE* stream)
  119. {
  120. int error = close(stream);
  121. return error;
  122. }
  123. /* Copyright (C) 2016 Jeremiah Orians
  124. * This file is part of stage0.
  125. *
  126. * stage0 is free software: you can redistribute it and/or modify
  127. * it under the terms of the GNU General Public License as published by
  128. * the Free Software Foundation, either version 3 of the License, or
  129. * (at your option) any later version.
  130. *
  131. * stage0 is distributed in the hope that it will be useful,
  132. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  133. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  134. * GNU General Public License for more details.
  135. *
  136. * You should have received a copy of the GNU General Public License
  137. * along with stage0. If not, see <http://www.gnu.org/licenses/>.
  138. */
  139. #include<stdio.h>
  140. // void fputc(char s, FILE* f);
  141. void file_print(char* s, FILE* f)
  142. {
  143. while(0 != s[0])
  144. {
  145. fputc(s[0], f);
  146. s = s + 1;
  147. }
  148. }
  149. ## Copyright (C) 2016 Jeremiah Orians
  150. ## This file is part of stage0.
  151. ##
  152. ## stage0 is free software: you can redistribute it and/or modify
  153. ## it under the terms of the GNU General Public License as published by
  154. ## the Free Software Foundation, either version 3 of the License, or
  155. ## (at your option) any later version.
  156. ##
  157. ## stage0 is distributed in the hope that it will be useful,
  158. ## but WITHOUT ANY WARRANTY; without even the implied warranty of
  159. ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  160. ## GNU General Public License for more details.
  161. ##
  162. ## You should have received a copy of the GNU General Public License
  163. ## along with stage0. If not, see <http://www.gnu.org/licenses/>.
  164. // CONSTANT NULL 0
  165. void* malloc(int size)
  166. {
  167. asm("STORE_eax_into_ESP_IMMEDIATE8 !4"
  168. "PUSH_eax"
  169. "LOAD_IMMEDIATE_eax %45"
  170. "LOAD_IMMEDIATE_ebx %0"
  171. "INT_80"
  172. "POP_ebx"
  173. "ADD_eax_to_ebx"
  174. "PUSH_eax"
  175. "PUSH_ebx"
  176. "LOAD_IMMEDIATE_eax %45"
  177. "INT_80"
  178. "POP_ebx"
  179. "CMP"
  180. "POP_eax"
  181. "JUMP_EQ8 !FUNCTION_malloc_Done"
  182. "LOAD_IMMEDIATE_eax %-1"
  183. ":FUNCTION_malloc_Done");
  184. }
  185. /* Copyright (C) 2016 Jeremiah Orians
  186. * This file is part of stage0.
  187. *
  188. * stage0 is free software: you can redistribute it and/or modify
  189. * it under the terms of the GNU General Public License as published by
  190. * the Free Software Foundation, either version 3 of the License, or
  191. * (at your option) any later version.
  192. *
  193. * stage0 is distributed in the hope that it will be useful,
  194. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  195. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  196. * GNU General Public License for more details.
  197. *
  198. * You should have received a copy of the GNU General Public License
  199. * along with stage0. If not, see <http://www.gnu.org/licenses/>.
  200. */
  201. // void* malloc(int size);
  202. void* memset(void* ptr, int value, int num)
  203. {
  204. char* s;
  205. for(s = ptr; 0 < num; num = num - 1)
  206. {
  207. s[0] = value;
  208. s = s + 1;
  209. }
  210. }
  211. void* calloc(int count, int size)
  212. {
  213. void* ret = malloc(count * size);
  214. memset(ret, 0, (count * size));
  215. return ret;
  216. }
  217. void free(void* l)
  218. {
  219. return;
  220. }
  221. /* Copyright (C) 2016 Jeremiah Orians
  222. * This file is part of stage0.
  223. *
  224. * stage0 is free software: you can redistribute it and/or modify
  225. * it under the terms of the GNU General Public License as published by
  226. * the Free Software Foundation, either version 3 of the License, or
  227. * (at your option) any later version.
  228. *
  229. * stage0 is distributed in the hope that it will be useful,
  230. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  231. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  232. * GNU General Public License for more details.
  233. *
  234. * You should have received a copy of the GNU General Public License
  235. * along with stage0. If not, see <http://www.gnu.org/licenses/>.
  236. */
  237. #define FALSE 0
  238. // CONSTANT FALSE 0
  239. #define TRUE 1
  240. // CONSTANT TRUE 1
  241. int match(char* a, char* b)
  242. {
  243. int i = -1;
  244. do
  245. {
  246. i = i + 1;
  247. if(a[i] != b[i])
  248. {
  249. return FALSE;
  250. }
  251. } while((0 != a[i]) && (0 !=b[i]));
  252. return TRUE;
  253. }
  254. /* -*- c-file-style: "linux";indent-tabs-mode:t -*- */
  255. /* Copyright (C) 2017 Jeremiah Orians
  256. * Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
  257. * This file is part of mescc-tools
  258. *
  259. * mescc-tools is free software: you can redistribute it and/or modify
  260. * it under the terms of the GNU General Public License as published by
  261. * the Free Software Foundation, either version 3 of the License, or
  262. * (at your option) any later version.
  263. *
  264. * mescc-tools is distributed in the hope that it will be useful,
  265. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  266. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  267. * GNU General Public License for more details.
  268. *
  269. * You should have received a copy of the GNU General Public License
  270. * along with mescc-tools. If not, see <http://www.gnu.org/licenses/>.
  271. */
  272. #include <stdio.h>
  273. #include <stdlib.h>
  274. #include <string.h>
  275. #include <getopt.h>
  276. #include <unistd.h>
  277. #include <sys/stat.h>
  278. #define max_string 4096
  279. //CONSTANT max_string 4096
  280. #define TRUE 1
  281. //CONSTANT TRUE 1
  282. #define FALSE 0
  283. //CONSTANT FALSE 0
  284. void file_print(char* s, FILE* f);
  285. int match(char* a, char* b);
  286. struct entry
  287. {
  288. struct entry* next;
  289. char* name;
  290. };
  291. FILE* output;
  292. struct entry* jump_table;
  293. void consume_token(FILE* source_file, char* s)
  294. {
  295. int i = 0;
  296. int c = fgetc(source_file);
  297. do
  298. {
  299. s[i] = c;
  300. i = i + 1;
  301. c = fgetc(source_file);
  302. } while((' ' != c) && ('\t' != c) && ('\n' != c) && '>' != c);
  303. }
  304. void storeLabel(FILE* source_file)
  305. {
  306. struct entry* entry = calloc(1, sizeof(struct entry));
  307. /* Prepend to list */
  308. entry->next = jump_table;
  309. jump_table = entry;
  310. /* Store string */
  311. entry->name = calloc((max_string + 1), sizeof(char));
  312. consume_token(source_file, entry->name);
  313. /* Remove all entries that start with the forbidden char pattern :_ */
  314. if('_' == entry->name[0])
  315. {
  316. jump_table = jump_table->next;
  317. }
  318. }
  319. void line_Comment(FILE* source_file)
  320. {
  321. int c = fgetc(source_file);
  322. while((10 != c) && (13 != c))
  323. {
  324. c = fgetc(source_file);
  325. }
  326. }
  327. void purge_string(FILE* source_file)
  328. {
  329. int c = fgetc(source_file);
  330. while((EOF != c) && (34 != c))
  331. {
  332. c = fgetc(source_file);
  333. }
  334. }
  335. void first_pass(struct entry* input)
  336. {
  337. if(NULL == input) return;
  338. first_pass(input->next);
  339. FILE* source_file = fopen(input->name, "r");
  340. if(NULL == source_file)
  341. {
  342. file_print("The file: ", stderr);
  343. file_print(input->name, stderr);
  344. file_print(" can not be opened!\n", stderr);
  345. exit(EXIT_FAILURE);
  346. }
  347. int c;
  348. for(c = fgetc(source_file); EOF != c; c = fgetc(source_file))
  349. {
  350. /* Check for and deal with label */
  351. if(58 == c)
  352. {
  353. storeLabel(source_file);
  354. }
  355. /* Check for and deal with line comments */
  356. else if (c == '#' || c == ';')
  357. {
  358. line_Comment(source_file);
  359. }
  360. else if (34 == c)
  361. {
  362. purge_string(source_file);
  363. }
  364. }
  365. fclose(source_file);
  366. }
  367. void output_debug(struct entry* node, int stage)
  368. {
  369. struct entry* i;
  370. for(i = node; NULL != i; i = i->next)
  371. {
  372. if(stage)
  373. {
  374. file_print(":ELF_str_", output);
  375. file_print(i->name, output);
  376. file_print("\n\x22", output);
  377. file_print(i->name, output);
  378. file_print("\x22\n", output);
  379. }
  380. else
  381. {
  382. file_print("%ELF_str_", output);
  383. file_print(i->name, output);
  384. file_print(">ELF_str\n&", output);
  385. file_print(i->name, output);
  386. file_print("\n%10000\n!2\n!0\n@1\n", output);
  387. }
  388. }
  389. }
  390. struct entry* reverse_list(struct entry* head)
  391. {
  392. struct entry* root = NULL;
  393. struct entry* next;
  394. while(NULL != head)
  395. {
  396. next = head->next;
  397. head->next = root;
  398. root = head;
  399. head = next;
  400. }
  401. return root;
  402. }
  403. /* Standard C main program */
  404. int main(int argc, char **argv)
  405. {
  406. jump_table = NULL;
  407. struct entry* input = NULL;
  408. output = stdout;
  409. char* output_file = "";
  410. int option_index = 1;
  411. while(option_index <= argc)
  412. {
  413. if(NULL == argv[option_index])
  414. {
  415. option_index = option_index + 1;
  416. }
  417. else if(match(argv[option_index], "-h") || match(argv[option_index], "--help"))
  418. {
  419. file_print("Usage: ", stderr);
  420. file_print(argv[0], stderr);
  421. file_print(" -f FILENAME1 {-f FILENAME2}\n", stderr);
  422. exit(EXIT_SUCCESS);
  423. }
  424. else if(match(argv[option_index], "-f") || match(argv[option_index], "--file"))
  425. {
  426. struct entry* temp = calloc(1, sizeof(struct entry));
  427. temp->name = argv[option_index + 1];
  428. temp->next = input;
  429. input = temp;
  430. option_index = option_index + 2;
  431. }
  432. else if(match(argv[option_index], "-o") || match(argv[option_index], "--output"))
  433. {
  434. output_file = argv[option_index + 1];
  435. output = fopen(output_file, "w");
  436. if(NULL == output)
  437. {
  438. file_print("The file: ", stderr);
  439. file_print(input->name, stderr);
  440. file_print(" can not be opened!\n", stderr);
  441. exit(EXIT_FAILURE);
  442. }
  443. option_index = option_index + 2;
  444. }
  445. else if(match(argv[option_index], "-V") || match(argv[option_index], "--version"))
  446. {
  447. file_print("blood-elf 0.1\n(Basically Launches Odd Object Dump ExecutabLe Files\n", stdout);
  448. exit(EXIT_SUCCESS);
  449. }
  450. else
  451. {
  452. file_print("Unknown option\n", stderr);
  453. exit(EXIT_FAILURE);
  454. }
  455. }
  456. /* Make sure we have a program tape to run */
  457. if (NULL == input)
  458. {
  459. return EXIT_FAILURE;
  460. }
  461. /* Get all of the labels */
  462. first_pass(input);
  463. /* Reverse their order */
  464. jump_table = reverse_list(jump_table);
  465. file_print(":ELF_str\n!0\n", output);
  466. output_debug(jump_table, TRUE);
  467. file_print("%0\n:ELF_sym\n%0\n%0\n%0\n!0\n!0\n@1\n", output);
  468. output_debug(jump_table, FALSE);
  469. file_print("\n:ELF_end\n", output);
  470. return EXIT_SUCCESS;
  471. }