#include #include #include "stabs.h" #include extern long __LIB_LIST__; extern __attribute__((noreturn)) void exit(int returncode); #pragma GCC push_options #pragma GCC optimize ("-O2") #define FAILED " failed to load\n" static __attribute__((noreturn)) __attribute__((noinline)) void __openliberror() { char buf[80]; long * l = &__LIB_LIST__ + 1; while (*l) { long * base = l++; char const * const name = *(char **) (l++); if (*base == -1) { char * p = buf; for (char const * q = name; *q;) { *p++ = *q++; } // strcpy for (char const * q = FAILED; *q;) { *p++ = *q++; } // strcat *p = 0; Write(Output(), buf, strlen(buf)); } } exit(20); } __attribute__((noinline)) static int endswithResource(char const * name) { char const * p = name; while (*p) ++p; p -= 9; if (p < name) return 0; for (char const * q = ".resource";*q;++p, ++q) { if (*p != *q) return 0; } return 1; } void __initlibraries(void) { long * l = &__LIB_LIST__ + 1; long failed = 0; while (*l) { long * base = l++; char const * const name = *(char **) (l++); long lib = (long)(endswithResource(name) ? OpenResource(name) : OldOpenLibrary(name)); if (lib) *base = lib; else failed = 1; } if (failed) __openliberror(); } void __exitlibraries(void) { long * l = &__LIB_LIST__ + 1; while (*l) { long * base = l++; char const * const name = *(char **) (l++); if (*base != -1) { if (!endswithResource(name)) CloseLibrary((struct Library *)*base); } } } #pragma GCC pop_options ADD2INIT(__initlibraries, -79); ADD2EXIT(__exitlibraries, -79);