Implement enough libb to make 'Hello, world!' work.
authorDavid Given <dg@cowlark.com>
Sun, 27 Nov 2016 21:05:15 +0000 (22:05 +0100)
committerDavid Given <dg@cowlark.com>
Sun, 27 Nov 2016 21:05:15 +0000 (22:05 +0100)
lang/b/lib/b.h [new file with mode: 0644]
lang/b/lib/build.lua [new file with mode: 0644]
lang/b/lib/main.c [new file with mode: 0644]
plat/build.lua

diff --git a/lang/b/lib/b.h b/lang/b/lib/b.h
new file mode 100644 (file)
index 0000000..123eabc
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef B_H
+#define B_H
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#if EM_PSIZE == 2
+#define SHIFT 1
+#elif EM_PSIZE == 4
+#define SHIFT 2
+#elif EM_PSIZE == 8
+#define SHIFT 3
+#else
+#error Unsupported EM_PSIZE
+#endif
+
+extern FILE* output_unit;
+
+#endif
diff --git a/lang/b/lib/build.lua b/lang/b/lib/build.lua
new file mode 100644 (file)
index 0000000..a45ab78
--- /dev/null
@@ -0,0 +1,27 @@
+include("plat/build.lua")
+
+for _, plat in ipairs(vars.plats) do
+    acklibrary {
+        name = "lib_"..plat,
+        srcs = {
+                       "./*.c",
+                       "./*.e",
+        },
+               hdrs = {}, -- must be empty
+               deps = {
+                       "./*.h",
+                       "h+emheaders",
+                       "lang/cem/libcc.ansi/headers+headers",
+                       "plat/"..plat.."/include+headers",
+               },
+        vars = { plat = plat }
+    }
+
+       installable {
+               name = "pkg_"..plat,
+               map = {
+                       ["$(PLATIND)/"..plat.."/libb.a"] = "+lib_"..plat,
+               }
+       }
+end
+
diff --git a/lang/b/lib/main.c b/lang/b/lib/main.c
new file mode 100644 (file)
index 0000000..1d18a80
--- /dev/null
@@ -0,0 +1,59 @@
+#include "b.h"
+
+extern uintptr_t* bsymb_patch_table[];
+extern intptr_t i_main(intptr_t argc, const char* argv[]);
+
+FILE* output_unit;
+
+static intptr_t i_char(intptr_t s, intptr_t n)
+{
+    const char* p = (const char*)(s<<SHIFT);
+    return p[n];
+}
+
+static void i_lchar(intptr_t s, intptr_t n, intptr_t c)
+{
+    char* p = (char*)(s<<SHIFT);
+    p[n] = c;
+}
+
+static intptr_t i_getchar(void)
+{
+    return fgetc(output_unit);
+}
+
+static void i_putchar(intptr_t c)
+{
+    fputc(c, output_unit);
+}
+
+uintptr_t b_char = (uintptr_t)i_char;
+uintptr_t b_lchar = (uintptr_t)i_lchar;
+uintptr_t b_getchar = (uintptr_t)i_getchar;
+uintptr_t b_putchar = (uintptr_t)i_putchar;
+
+static uintptr_t* lib_patch_table[] =
+{
+    &b_char,
+    &b_lchar,
+    &b_getchar,
+    &b_putchar,
+    0
+};
+
+static void patch_addresses(uintptr_t** p)
+{
+    while (*p)
+    {
+        uintptr_t* q = *p++;
+        *q >>= SHIFT;
+    }
+}
+
+int main(int argc, const char* argv[])
+{
+    patch_addresses(bsymb_patch_table);
+    patch_addresses(lib_patch_table);
+    output_unit = stdout;
+    return i_main(argc, NULL);
+}
\ No newline at end of file
index 85ba61b..a8d1684 100644 (file)
@@ -104,6 +104,7 @@ definerule("build_plat_libs",
                                "lang/cem/libcc.ansi+pkg_"..e.plat,
                                "lang/m2/libm2+pkg_"..e.plat,
                                "lang/pc/libpc+pkg_"..e.plat,
+                               "lang/b/lib+pkg_"..e.plat,
                                ["$(PLATIND)/"..e.plat.."/libem.a"] = "mach/"..e.arch.."/libem+lib_"..e.plat,
                                ["$(PLATIND)/"..e.plat.."/libend.a"] = "mach/"..e.arch.."/libend+lib_"..e.plat,
                        }