diff --git a/20140413.html b/20140413.html new file mode 100644 index 0000000..9309fe7 --- /dev/null +++ b/20140413.html @@ -0,0 +1,51 @@ +
+

20140413 - Minimal Single Symbol ELF For Using GL

+
+ +With the exception of graphics, everything else on Linux can easily be done via kernel system calls. For those working in a custom language, using GL adds the complexity nightmare of dynamic linking. However there is a way to reduce this complexity to the following (which enables a simpler ELF),
+
+(1.) Link to libdl.so only.
+(2.) Use only one symbol: dlsym().
+
+Using dlsym() one can get the address for dlopen(), which together enables manually opening libraries. Unfortunately some GL libraries require that the caller have the full libc treatment (everything that happens between _start() and main()). Implementing all that crap in a custom language is a great way to gain the full realization that the Linux people lost track of the K.I.S.S. principle a long time ago. Instead one can just dlopen() libc.so itself and manually pass through the complexity filter via __libc_start_main(). Here is a proof-of-concept in C for x86-64 which lacks a bunch of important stuff, but works enough to get into main() and then print "ok" via a Linux syscall.
+
+static inline long Linux1(long num, long arg1) { long ret; asm volatile ("syscall" : "=a" (ret) : "a" (num), "D" (arg1) : "cc", "memory", "%rcx", "%rdx", "%rsi", "%r8", "%r9", "%r10", "%r11"); return ret; }
+
+static inline long Linux3(long num, long arg1, long arg2, long arg3) { long ret; asm volatile ("syscall" : "=a" (ret) : "a" (num), "D" (arg1), "S" (arg2), "d" (arg3) : "cc", "memory", "%rcx", "%r8", "%r9", "%r10", "%r11"); return ret; }
+
+void* dlsym(void*, const char*);
+
+typedef void* (*dlopenF)(const char*, int);
+
+#define RTLD_NOW 2
+
+typedef int (*__libc_start_mainF)(int (*)(int, char**, char**), int, char**, void (*)(void), void(*)(void), void (*)(void), void (*));
+
+static void None(void) { }
+
+static int Main(int a, char** b, char** c) { char msg[]="ok\n"; Linux3(1, 1, (long)msg, 3); Linux1(231, 0); }
+
+void _start(void) {
+dlopenF dlopen;
+dlopen = (dlopenF)dlsym(0, "dlopen");
+void* libc = dlopen("libc.so", RTLD_NOW);
+__libc_start_mainF __libc_start_main;
+__libc_start_main = (__libc_start_mainF)dlsym(libc, "__libc_start_main");
+__libc_start_main(Main, 0, 0, None, None, None, 0); }

+
+This can be built with,
+
+gcc -std=gnu99 src.c -ldl -Os -fno-unwind-tables -fno-exceptions -nostdlib
+
+Even given the unnecessary garbage GNU ld dumps in the ELF, this binary will be under 3K, which almost half the size of compiling "void main(void) { }" using the standard libs. Going to assembly or some other custom language and manually building the ELF can make this much smaller. + + + + + + + + +
+ + diff --git a/index.html b/index.html index 7b1d803..34d2fe7 100644 --- a/index.html +++ b/index.html @@ -53,7 +53,7 @@ and attempting to restore what I can from prior lost images.

@@ -218,6 +218,8 @@ and attempting to restore what I can from prior lost images.
20140506 - The Other Project

+20140413 - Minimal Single Symbol ELF For Using GL
+
20140328 - Related to Filtering for VR

20140110 - Portable Read-Only Thumb Linux