├── Makefile ├── README.md ├── linuxapi.nim ├── nimbase.h ├── nimcache └── .nimhello.nim.c.swp ├── nimhello.nim └── stubs ├── limits.h ├── signal.h ├── stdio.h ├── stdlib.h ├── string.h └── stubs.c /Makefile: -------------------------------------------------------------------------------- 1 | V = 1 2 | 3 | VER = $(shell uname -r) 4 | KDIR ?= /lib/modules/$(VER)/build 5 | 6 | obj-m += hello.o 7 | 8 | hello-objs += nimcache/nimhello.nim.o 9 | hello-objs += nimcache/stdlib_allocators.nim.o 10 | hello-objs += nimcache/stdlib_system.nim.o 11 | hello-objs += nimcache/stdlib_io.nim.o 12 | hello-objs += nimcache/stdlib_strutils.nim.o 13 | hello-objs += nimcache/stdlib_parseutils.nim.o 14 | hello-objs += nimcache/stdlib_dollars.nim.o 15 | hello-objs += stubs/stubs.o 16 | hello-objs += ../../../../../../opt/toolchains/i686-buildroot-linux-uclibc-gcc/usr/lib/gcc/i686-buildroot-linux-uclibc/4.6.4/libgcc.a 17 | 18 | hello-lobs := lgcc 19 | 20 | ccflags-y := -I$(src) -I$(src)/stubs 21 | 22 | 23 | all: info nimcache/nimhello.nim.c modules 24 | 25 | info: 26 | echo $(PWD) 27 | echo $(hello-src) 28 | echo $(hello-objs) 29 | 30 | nimcache/nimhello.nim.c: nimhello.nim 31 | nim c -c \ 32 | --nimcache:./nimcache \ 33 | --os:kernel \ 34 | --newruntime \ 35 | --noMain:on \ 36 | -d:noSignalHandler \ 37 | -d:release \ 38 | -d:nimquirky \ 39 | nimhello.nim 40 | 41 | 42 | modules: 43 | $(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd) modules 44 | 45 | clean: 46 | $(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd) clean 47 | $(RM) nimcache/* *.json 48 | 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | Experiment to create a Linux kernel module in nim 3 | 4 | Requires a slightly changed Nim compiler with support for the `kernel` os: 5 | https://github.com/zevv/Nim/tree/linux-kernel 6 | 7 | 8 | ``` 9 | make 10 | sudo insmod nimhello.ko 11 | sudo rmmod nimhello 12 | ``` 13 | 14 | -------------------------------------------------------------------------------- /linuxapi.nim: -------------------------------------------------------------------------------- 1 | 2 | proc printk*(str: cstring) {.header: "linux/module.h", varargs, importc: "printk"} 3 | 4 | proc print_modules*() {.header: "linux/module.h", importc: "print_modules"} 5 | -------------------------------------------------------------------------------- /nimbase.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Nim's Runtime Library 4 | (c) Copyright 2015 Andreas Rumpf 5 | 6 | See the file "copying.txt", included in this 7 | distribution, for details about the copyright. 8 | */ 9 | 10 | /* compiler symbols: 11 | __BORLANDC__ 12 | _MSC_VER 13 | __WATCOMC__ 14 | __LCC__ 15 | __GNUC__ 16 | __DMC__ 17 | __POCC__ 18 | __TINYC__ 19 | __clang__ 20 | */ 21 | 22 | 23 | #ifndef NIMBASE_H 24 | #define NIMBASE_H 25 | 26 | /*------------ declaring a custom attribute to support using LLVM's Address Sanitizer ------------ */ 27 | 28 | /* 29 | This definition exists to provide support for using the LLVM ASAN (Address SANitizer) tooling with Nim. This 30 | should only be used to mark implementations of the GC system that raise false flags with the ASAN tooling, or 31 | for functions that are hot and need to be disabled for performance reasons. Based on the official ASAN 32 | documentation, both the clang and gcc compilers are supported. In addition to that, a check is performed to 33 | verify that the necessary attribute is supported by the compiler. 34 | 35 | To flag a proc as ignored, append the following code pragma to the proc declaration: 36 | {.codegenDecl: "CLANG_NO_SANITIZE_ADDRESS $# $#$#".} 37 | 38 | For further information, please refer to the official documentation: 39 | https://github.com/google/sanitizers/wiki/AddressSanitizer 40 | */ 41 | #define CLANG_NO_SANITIZE_ADDRESS 42 | #if defined(__clang__) 43 | # if __has_attribute(no_sanitize_address) 44 | # undef CLANG_NO_SANITIZE_ADDRESS 45 | # define CLANG_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) 46 | # endif 47 | #endif 48 | 49 | 50 | /* ------------ ignore typical warnings in Nim-generated files ------------- */ 51 | #if defined(__GNUC__) || defined(__clang__) 52 | # pragma GCC diagnostic ignored "-Wpragmas" 53 | # pragma GCC diagnostic ignored "-Wwritable-strings" 54 | # pragma GCC diagnostic ignored "-Winvalid-noreturn" 55 | # pragma GCC diagnostic ignored "-Wformat" 56 | # pragma GCC diagnostic ignored "-Wlogical-not-parentheses" 57 | # pragma GCC diagnostic ignored "-Wlogical-op-parentheses" 58 | # pragma GCC diagnostic ignored "-Wshadow" 59 | # pragma GCC diagnostic ignored "-Wunused-function" 60 | # pragma GCC diagnostic ignored "-Wunused-variable" 61 | # pragma GCC diagnostic ignored "-Winvalid-offsetof" 62 | # pragma GCC diagnostic ignored "-Wtautological-compare" 63 | # pragma GCC diagnostic ignored "-Wswitch-bool" 64 | # pragma GCC diagnostic ignored "-Wmacro-redefined" 65 | # pragma GCC diagnostic ignored "-Wincompatible-pointer-types-discards-qualifiers" 66 | # pragma GCC diagnostic ignored "-Wpointer-bool-conversion" 67 | # pragma GCC diagnostic ignored "-Wconstant-conversion" 68 | #endif 69 | 70 | #if defined(_MSC_VER) 71 | # pragma warning(disable: 4005 4100 4101 4189 4191 4200 4244 4293 4296 4309) 72 | # pragma warning(disable: 4310 4365 4456 4477 4514 4574 4611 4668 4702 4706) 73 | # pragma warning(disable: 4710 4711 4774 4800 4809 4820 4996 4090 4297) 74 | #endif 75 | /* ------------------------------------------------------------------------- */ 76 | 77 | #if defined(__GNUC__) 78 | # define _GNU_SOURCE 1 79 | #endif 80 | 81 | #if defined(__TINYC__) 82 | /*# define __GNUC__ 3 83 | # define GCC_MAJOR 4 84 | # define __GNUC_MINOR__ 4 85 | # define __GNUC_PATCHLEVEL__ 5 */ 86 | # define __DECLSPEC_SUPPORTED 1 87 | #endif 88 | 89 | /* calling convention mess ----------------------------------------------- */ 90 | #if defined(__GNUC__) || defined(__LCC__) || defined(__POCC__) \ 91 | || defined(__TINYC__) 92 | /* these should support C99's inline */ 93 | /* the test for __POCC__ has to come before the test for _MSC_VER, 94 | because PellesC defines _MSC_VER too. This is brain-dead. */ 95 | # define N_INLINE(rettype, name) inline rettype name 96 | #elif defined(__BORLANDC__) || defined(_MSC_VER) 97 | /* Borland's compiler is really STRANGE here; note that the __fastcall 98 | keyword cannot be before the return type, but __inline cannot be after 99 | the return type, so we do not handle this mess in the code generator 100 | but rather here. */ 101 | # define N_INLINE(rettype, name) __inline rettype name 102 | #elif defined(__DMC__) 103 | # define N_INLINE(rettype, name) inline rettype name 104 | #elif defined(__WATCOMC__) 105 | # define N_INLINE(rettype, name) __inline rettype name 106 | #else /* others are less picky: */ 107 | # define N_INLINE(rettype, name) rettype __inline name 108 | #endif 109 | 110 | #define N_INLINE_PTR(rettype, name) rettype (*name) 111 | 112 | #if defined(__POCC__) 113 | # define NIM_CONST /* PCC is really picky with const modifiers */ 114 | # undef _MSC_VER /* Yeah, right PCC defines _MSC_VER even if it is 115 | not that compatible. Well done. */ 116 | #elif defined(__cplusplus) 117 | # define NIM_CONST /* C++ is picky with const modifiers */ 118 | #else 119 | # define NIM_CONST const 120 | #endif 121 | 122 | /* 123 | NIM_THREADVAR declaration based on 124 | http://stackoverflow.com/questions/18298280/how-to-declare-a-variable-as-thread-local-portably 125 | */ 126 | #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112 && !defined __STDC_NO_THREADS__ 127 | # define NIM_THREADVAR _Thread_local 128 | #elif defined _WIN32 && ( \ 129 | defined _MSC_VER || \ 130 | defined __ICL || \ 131 | defined __DMC__ || \ 132 | defined __BORLANDC__ ) 133 | # define NIM_THREADVAR __declspec(thread) 134 | #elif defined(__TINYC__) || defined(__GENODE__) 135 | # define NIM_THREADVAR 136 | /* note that ICC (linux) and Clang are covered by __GNUC__ */ 137 | #elif defined __GNUC__ || \ 138 | defined __SUNPRO_C || \ 139 | defined __xlC__ 140 | # define NIM_THREADVAR __thread 141 | #else 142 | # error "Cannot define NIM_THREADVAR" 143 | #endif 144 | 145 | /* --------------- how int64 constants should be declared: ----------- */ 146 | #if defined(__GNUC__) || defined(__LCC__) || \ 147 | defined(__POCC__) || defined(__DMC__) || defined(_MSC_VER) 148 | # define IL64(x) x##LL 149 | #else /* works only without LL */ 150 | # define IL64(x) ((NI64)x) 151 | #endif 152 | 153 | /* ---------------- casting without correct aliasing rules ----------- */ 154 | 155 | #if defined(__GNUC__) 156 | # define NIM_CAST(type, ptr) (((union{type __x__;}*)(ptr))->__x__) 157 | #else 158 | # define NIM_CAST(type, ptr) ((type)(ptr)) 159 | #endif 160 | 161 | /* ------------------------------------------------------------------- */ 162 | 163 | #if defined(WIN32) || defined(_WIN32) /* only Windows has this mess... */ 164 | # define N_LIB_PRIVATE 165 | # define N_CDECL(rettype, name) rettype __cdecl name 166 | # define N_STDCALL(rettype, name) rettype __stdcall name 167 | # define N_SYSCALL(rettype, name) rettype __syscall name 168 | # define N_FASTCALL(rettype, name) rettype __fastcall name 169 | # define N_SAFECALL(rettype, name) rettype __stdcall name 170 | /* function pointers with calling convention: */ 171 | # define N_CDECL_PTR(rettype, name) rettype (__cdecl *name) 172 | # define N_STDCALL_PTR(rettype, name) rettype (__stdcall *name) 173 | # define N_SYSCALL_PTR(rettype, name) rettype (__syscall *name) 174 | # define N_FASTCALL_PTR(rettype, name) rettype (__fastcall *name) 175 | # define N_SAFECALL_PTR(rettype, name) rettype (__stdcall *name) 176 | 177 | # ifdef __cplusplus 178 | # define N_LIB_EXPORT extern "C" __declspec(dllexport) 179 | # else 180 | # define N_LIB_EXPORT extern __declspec(dllexport) 181 | # endif 182 | # define N_LIB_IMPORT extern __declspec(dllimport) 183 | #else 184 | # define N_LIB_PRIVATE __attribute__((visibility("hidden"))) 185 | # if defined(__GNUC__) 186 | # define N_CDECL(rettype, name) rettype name 187 | # define N_STDCALL(rettype, name) rettype name 188 | # define N_SYSCALL(rettype, name) rettype name 189 | # define N_FASTCALL(rettype, name) __attribute__((fastcall)) rettype name 190 | # define N_SAFECALL(rettype, name) rettype name 191 | /* function pointers with calling convention: */ 192 | # define N_CDECL_PTR(rettype, name) rettype (*name) 193 | # define N_STDCALL_PTR(rettype, name) rettype (*name) 194 | # define N_SYSCALL_PTR(rettype, name) rettype (*name) 195 | # define N_FASTCALL_PTR(rettype, name) __attribute__((fastcall)) rettype (*name) 196 | # define N_SAFECALL_PTR(rettype, name) rettype (*name) 197 | # else 198 | # define N_CDECL(rettype, name) rettype name 199 | # define N_STDCALL(rettype, name) rettype name 200 | # define N_SYSCALL(rettype, name) rettype name 201 | # define N_FASTCALL(rettype, name) rettype name 202 | # define N_SAFECALL(rettype, name) rettype name 203 | /* function pointers with calling convention: */ 204 | # define N_CDECL_PTR(rettype, name) rettype (*name) 205 | # define N_STDCALL_PTR(rettype, name) rettype (*name) 206 | # define N_SYSCALL_PTR(rettype, name) rettype (*name) 207 | # define N_FASTCALL_PTR(rettype, name) rettype (*name) 208 | # define N_SAFECALL_PTR(rettype, name) rettype (*name) 209 | # endif 210 | # ifdef __cplusplus 211 | # define N_LIB_EXPORT extern "C" 212 | # else 213 | # define N_LIB_EXPORT extern 214 | # endif 215 | # define N_LIB_IMPORT extern 216 | #endif 217 | 218 | #define N_NOCONV(rettype, name) rettype name 219 | /* specify no calling convention */ 220 | #define N_NOCONV_PTR(rettype, name) rettype (*name) 221 | 222 | # define N_NOINLINE(rettype, name) rettype name 223 | 224 | #define N_NOINLINE_PTR(rettype, name) rettype (*name) 225 | 226 | #if defined(__BORLANDC__) || defined(__WATCOMC__) || \ 227 | defined(__POCC__) || defined(_MSC_VER) || defined(WIN32) || defined(_WIN32) 228 | /* these compilers have a fastcall so use it: */ 229 | # ifdef __TINYC__ 230 | # define N_NIMCALL(rettype, name) rettype __attribute((__fastcall)) name 231 | # define N_NIMCALL_PTR(rettype, name) rettype (__attribute((__fastcall)) *name) 232 | # define N_RAW_NIMCALL __attribute((__fastcall)) 233 | # else 234 | # define N_NIMCALL(rettype, name) rettype __fastcall name 235 | # define N_NIMCALL_PTR(rettype, name) rettype (__fastcall *name) 236 | # define N_RAW_NIMCALL __fastcall 237 | # endif 238 | #else 239 | # define N_NIMCALL(rettype, name) rettype name /* no modifier */ 240 | # define N_NIMCALL_PTR(rettype, name) rettype (*name) 241 | # define N_RAW_NIMCALL 242 | #endif 243 | 244 | #define N_CLOSURE(rettype, name) N_NIMCALL(rettype, name) 245 | #define N_CLOSURE_PTR(rettype, name) N_NIMCALL_PTR(rettype, name) 246 | 247 | /* ----------------------------------------------------------------------- */ 248 | 249 | #define COMMA , 250 | 251 | #include 252 | #include 253 | 254 | /* C99 compiler? */ 255 | #if (defined(__STD_VERSION__) && (__STD_VERSION__ >= 199901)) 256 | # define HAVE_STDINT_H 257 | #endif 258 | 259 | #if defined(__LCC__) || defined(__DMC__) || defined(__POCC__) 260 | # define HAVE_STDINT_H 261 | #endif 262 | 263 | /* wrap all Nim typedefs into namespace Nim */ 264 | #ifdef USE_NIM_NAMESPACE 265 | namespace USE_NIM_NAMESPACE { 266 | #endif 267 | 268 | /* bool types (C++ has it): */ 269 | #ifdef __cplusplus 270 | # ifndef NIM_TRUE 271 | # define NIM_TRUE true 272 | # endif 273 | # ifndef NIM_FALSE 274 | # define NIM_FALSE false 275 | # endif 276 | # define NIM_BOOL bool 277 | # if __cplusplus >= 201103L 278 | # /* nullptr is more type safe (less implicit conversions than 0) */ 279 | # define NIM_NIL nullptr 280 | # else 281 | # /* consider using NULL if comment below for NIM_NIL doesn't apply to C++ */ 282 | # define NIM_NIL 0 283 | # endif 284 | #else 285 | # ifdef bool 286 | # define NIM_BOOL bool 287 | # else 288 | typedef unsigned char NIM_BOOL; 289 | # endif 290 | # ifndef NIM_TRUE 291 | # define NIM_TRUE ((NIM_BOOL) 1) 292 | # endif 293 | # ifndef NIM_FALSE 294 | # define NIM_FALSE ((NIM_BOOL) 0) 295 | # endif 296 | # define NIM_NIL ((void*)0) /* C's NULL is fucked up in some C compilers, so 297 | the generated code does not rely on it anymore */ 298 | #endif 299 | 300 | #if defined(__BORLANDC__) || defined(__DMC__) \ 301 | || defined(__WATCOMC__) || defined(_MSC_VER) 302 | typedef signed char NI8; 303 | typedef signed short int NI16; 304 | typedef signed int NI32; 305 | /* XXX: Float128? */ 306 | typedef unsigned char NU8; 307 | typedef unsigned short int NU16; 308 | typedef unsigned __int64 NU64; 309 | typedef __int64 NI64; 310 | typedef unsigned int NU32; 311 | #elif defined(HAVE_STDINT_H) 312 | # include 313 | typedef int8_t NI8; 314 | typedef int16_t NI16; 315 | typedef int32_t NI32; 316 | typedef int64_t NI64; 317 | typedef uint64_t NU64; 318 | typedef uint8_t NU8; 319 | typedef uint16_t NU16; 320 | typedef uint32_t NU32; 321 | #else 322 | typedef signed char NI8; 323 | typedef signed short int NI16; 324 | typedef signed int NI32; 325 | /* XXX: Float128? */ 326 | typedef unsigned char NU8; 327 | typedef unsigned short int NU16; 328 | typedef unsigned long long int NU64; 329 | typedef long long int NI64; 330 | typedef unsigned int NU32; 331 | #endif 332 | 333 | #ifdef NIM_INTBITS 334 | # if NIM_INTBITS == 64 335 | typedef NI64 NI; 336 | typedef NU64 NU; 337 | # elif NIM_INTBITS == 32 338 | typedef NI32 NI; 339 | typedef NU32 NU; 340 | # elif NIM_INTBITS == 16 341 | typedef NI16 NI; 342 | typedef NU16 NU; 343 | # elif NIM_INTBITS == 8 344 | typedef NI8 NI; 345 | typedef NU8 NU; 346 | # else 347 | # error "invalid bit width for int" 348 | # endif 349 | #endif 350 | 351 | // for now there isn't an easy way for C code to reach the program result 352 | // when hot code reloading is ON - users will have to: 353 | // load the nimhcr.dll, get the hcrGetGlobal proc from there and use it 354 | #ifndef NIM_HOT_CODE_RELOADING 355 | extern NI nim_program_result; 356 | #endif 357 | 358 | typedef float NF32; 359 | typedef double NF64; 360 | typedef double NF; 361 | 362 | typedef char NIM_CHAR; 363 | typedef char* NCSTRING; 364 | 365 | #ifdef NIM_BIG_ENDIAN 366 | # define NIM_IMAN 1 367 | #else 368 | # define NIM_IMAN 0 369 | #endif 370 | 371 | static N_INLINE(NI, float64ToInt32)(double x) { 372 | /* nowadays no hack necessary anymore */ 373 | return x >= 0 ? (NI)(x+0.5) : (NI)(x-0.5); 374 | } 375 | 376 | static N_INLINE(NI32, float32ToInt32)(float x) { 377 | /* nowadays no hack necessary anymore */ 378 | return x >= 0 ? (NI32)(x+0.5) : (NI32)(x-0.5); 379 | } 380 | 381 | #define float64ToInt64(x) ((NI64) (x)) 382 | 383 | #define NIM_STRLIT_FLAG ((NU)(1) << ((NIM_INTBITS) - 2)) /* This has to be the same as system.strlitFlag! */ 384 | 385 | #define STRING_LITERAL(name, str, length) \ 386 | static const struct { \ 387 | TGenericSeq Sup; \ 388 | NIM_CHAR data[(length) + 1]; \ 389 | } name = {{length, (NI) ((NU)length | NIM_STRLIT_FLAG)}, str} 390 | 391 | /* declared size of a sequence/variable length array: */ 392 | #if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER) 393 | # define SEQ_DECL_SIZE /* empty is correct! */ 394 | #else 395 | # define SEQ_DECL_SIZE 1000000 396 | #endif 397 | 398 | #define ALLOC_0(size) calloc(1, size) 399 | #define DL_ALLOC_0(size) dlcalloc(1, size) 400 | 401 | #define GenericSeqSize sizeof(TGenericSeq) 402 | #define paramCount() cmdCount 403 | 404 | // NAN definition copied from math.h included in the Windows SDK version 10.0.14393.0 405 | #ifndef NAN 406 | # ifndef _HUGE_ENUF 407 | # define _HUGE_ENUF 1e+300 // _HUGE_ENUF*_HUGE_ENUF must overflow 408 | # endif 409 | # define NAN_INFINITY ((float)(_HUGE_ENUF * _HUGE_ENUF)) 410 | # define NAN ((float)(NAN_INFINITY * 0.0F)) 411 | #endif 412 | 413 | #ifndef INF 414 | # ifdef INFINITY 415 | # define INF INFINITY 416 | # elif defined(HUGE_VAL) 417 | # define INF HUGE_VAL 418 | # elif defined(_MSC_VER) 419 | # include 420 | # define INF (DBL_MAX+DBL_MAX) 421 | # else 422 | # define INF (1.0 / 0.0) 423 | # endif 424 | #endif 425 | 426 | typedef struct TFrame_ TFrame; 427 | struct TFrame_ { 428 | TFrame* prev; 429 | NCSTRING procname; 430 | NI line; 431 | NCSTRING filename; 432 | NI16 len; 433 | NI16 calldepth; 434 | }; 435 | 436 | #ifdef NIM_NEW_MANGLING_RULES 437 | #define nimfr_(proc, file) \ 438 | TFrame FR_; \ 439 | FR_.procname = proc; FR_.filename = file; FR_.line = 0; FR_.len = 0; nimFrame(&FR_); 440 | 441 | #define nimfrs_(proc, file, slots, length) \ 442 | struct {TFrame* prev;NCSTRING procname;NI line;NCSTRING filename; NI len; VarSlot s[slots];} FR_; \ 443 | FR_.procname = proc; FR_.filename = file; FR_.line = 0; FR_.len = length; nimFrame((TFrame*)&FR_); 444 | 445 | #define nimln_(n, file) \ 446 | FR_.line = n; FR_.filename = file; 447 | #else 448 | #define nimfr(proc, file) \ 449 | TFrame FR; \ 450 | FR.procname = proc; FR.filename = file; FR.line = 0; FR.len = 0; nimFrame(&FR); 451 | 452 | #define nimfrs(proc, file, slots, length) \ 453 | struct {TFrame* prev;NCSTRING procname;NI line;NCSTRING filename; NI len; VarSlot s[slots];} FR; \ 454 | FR.procname = proc; FR.filename = file; FR.line = 0; FR.len = length; nimFrame((TFrame*)&FR); 455 | 456 | #define nimln(n, file) \ 457 | FR.line = n; FR.filename = file; 458 | #endif 459 | 460 | #define NIM_POSIX_INIT __attribute__((constructor)) 461 | 462 | #if 0 463 | #ifdef __GNUC__ 464 | # define likely(x) __builtin_expect(x, 1) 465 | # define unlikely(x) __builtin_expect(x, 0) 466 | /* We need the following for the posix wrapper. In particular it will give us 467 | POSIX_SPAWN_USEVFORK: */ 468 | # ifndef _GNU_SOURCE 469 | # define _GNU_SOURCE 470 | # endif 471 | #else 472 | # define likely(x) (x) 473 | # define unlikely(x) (x) 474 | #endif 475 | #endif 476 | 477 | #if 0 // defined(__GNUC__) || defined(__clang__) 478 | // not needed anymore because the stack marking cares about 479 | // interior pointers now 480 | static inline void GCGuard (void *ptr) { asm volatile ("" :: "X" (ptr)); } 481 | # define GC_GUARD __attribute__ ((cleanup(GCGuard))) 482 | #else 483 | # define GC_GUARD 484 | #endif 485 | 486 | /* Test to see if Nim and the C compiler agree on the size of a pointer. 487 | On disagreement, your C compiler will say something like: 488 | "error: 'Nim_and_C_compiler_disagree_on_target_architecture' declared as an array with a negative size" */ 489 | typedef int Nim_and_C_compiler_disagree_on_target_architecture[sizeof(NI) == sizeof(void*) && NIM_INTBITS == sizeof(NI)*8 ? 1 : -1]; 490 | 491 | #ifdef USE_NIM_NAMESPACE 492 | } 493 | #endif 494 | 495 | #ifdef __cplusplus 496 | # define NIM_EXTERNC extern "C" 497 | #else 498 | # define NIM_EXTERNC 499 | #endif 500 | 501 | /* ---------------- platform specific includes ----------------------- */ 502 | 503 | /* VxWorks related includes */ 504 | #if defined(__VXWORKS__) 505 | # include 506 | # include 507 | # include 508 | #elif defined(__FreeBSD__) 509 | # include 510 | #endif 511 | 512 | /* Compile with -d:checkAbi and a sufficiently C11:ish compiler to enable */ 513 | #define NIM_CHECK_SIZE(typ, sz) \ 514 | _Static_assert(sizeof(typ) == sz, "Nim & C disagree on type size") 515 | 516 | #endif /* NIMBASE_H */ 517 | -------------------------------------------------------------------------------- /nimcache/.nimhello.nim.c.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zevv/nim-kernel-module/80c0159c560ff8d3aa76305630c10a0f79d9402d/nimcache/.nimhello.nim.c.swp -------------------------------------------------------------------------------- /nimhello.nim: -------------------------------------------------------------------------------- 1 | 2 | import linuxapi 3 | import strutils 4 | 5 | type 6 | Pig = object 7 | front: string 8 | back: int 9 | 10 | proc test_strings() = 11 | echo repeat("Cat", 3) 12 | echo parseInt("1234") 13 | echo toHex("abcdefg") 14 | 15 | proc test_dollars() = 16 | let a = [ 1, 2, 3 ] 17 | let b = @[ 1, 2, 3 ] 18 | let c = 12345 19 | let d = Pig(front: "pink", back: 40) 20 | echo $a 21 | echo $b 22 | echo $c 23 | echo $d 24 | echo 3.1415 25 | 26 | proc nim_init(): cint {.cdecl, exportc.} = 27 | echo "Hello" 28 | test_strings() 29 | test_dollars() 30 | 31 | 32 | proc nim_exit() {.cdecl, exportc.} = 33 | echo "Bye" 34 | 35 | 36 | {.emit:""" 37 | #include 38 | module_init(nim_init) 39 | module_exit(nim_exit) 40 | MODULE_AUTHOR("Zevv"); 41 | MODULE_DESCRIPTION("Linux kernel module in Nim"); 42 | MODULE_LICENSE("MIT"); 43 | """} 44 | 45 | -------------------------------------------------------------------------------- /stubs/limits.h: -------------------------------------------------------------------------------- 1 | 2 | // stub to make nimbase.h happy 3 | -------------------------------------------------------------------------------- /stubs/signal.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zevv/nim-kernel-module/80c0159c560ff8d3aa76305630c10a0f79d9402d/stubs/signal.h -------------------------------------------------------------------------------- /stubs/stdio.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef void *FILE; 4 | extern FILE *stdout; 5 | extern FILE *stderr; 6 | 7 | size_t fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream); 8 | int fflush(FILE *stream); 9 | void exit(int status); 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /stubs/stdlib.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zevv/nim-kernel-module/80c0159c560ff8d3aa76305630c10a0f79d9402d/stubs/stdlib.h -------------------------------------------------------------------------------- /stubs/string.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | -------------------------------------------------------------------------------- /stubs/stubs.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | FILE *stdout; 5 | FILE *stderr; 6 | 7 | size_t fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream) 8 | { 9 | printk(ptr); 10 | return 0; 11 | } 12 | 13 | int fflush(FILE *stream) 14 | { 15 | return 0; 16 | } 17 | 18 | void exit(int status) 19 | { 20 | } 21 | --------------------------------------------------------------------------------