#ifndef DNLOAD_H
#define DNLOAD_H

/** \file
 * \brief Dynamic loader header stub.
 *
 * This file was automatically generated by 'dnload.py'.
 */

#if defined(WIN32)
/** \cond */
#define _USE_MATH_DEFINES
#define NOMINMAX
/** \endcond */
#else
/** \cond */
#define GL_GLEXT_PROTOTYPES
/** \endcond */
#endif

#if defined(USE_LD)
#if defined(WIN32)
#include "windows.h"
#include "GL/glew.h"
#include "GL/glu.h"
#include "SDL.h"
#elif defined(__APPLE__)
#include "GL/glew.h"
#include <OpenGL/glu.h>
#include <SDL/SDL.h>
#else
#if defined(DNLOAD_VIDEOCORE)
#include "bcm_host.h"
#endif
#if defined(DNLOAD_GLESV2)
#include "EGL/egl.h"
#include "EGL/eglext.h"
#include "GLES2/gl2.h"
#include "GLES2/gl2ext.h"
#else
#include "GL/glew.h"
#include "GL/glu.h"
#endif
#include "SDL.h"
#endif
#include "bsd_rand.h"
#else
#if defined(DNLOAD_VIDEOCORE)
#include "bcm_host.h"
#endif
#if defined(DNLOAD_GLESV2)
#include "EGL/egl.h"
#include "EGL/eglext.h"
#include "GLES2/gl2.h"
#include "GLES2/gl2ext.h"
#else
#ifdef __APPLE__
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
#include <OpenGL/glu.h>
#else
#include "GL/gl.h"
#include "GL/glext.h"
#include "GL/glu.h"
#endif
#endif
#ifdef __APPLE__
#include <SDL/sdl.h>
#else
#include "SDL.h"
#endif
#endif

#if defined(__cplusplus)
#include <cmath>
#include <cstdlib>
#else
#include <math.h>
#include <stdlib.h>
#endif

/** Macro stringification helper (adds indirection). */
#define DNLOAD_MACRO_STR_HELPER(op) #op
/** Macro stringification. */
#define DNLOAD_MACRO_STR(op) DNLOAD_MACRO_STR_HELPER(op)

#if defined(DNLOAD_GLESV2)
/** Apientry definition (OpenGL ES 2.0). */
#define DNLOAD_APIENTRY GL_APIENTRY
#else
/** Apientry definition (OpenGL). */
#define DNLOAD_APIENTRY GLAPIENTRY
#endif

#if (defined(_LP64) && _LP64) || (defined(__LP64__) && __LP64__)
/** Size of pointer in bytes (64-bit). */
#define DNLOAD_POINTER_SIZE 8
#else
/** Size of pointer in bytes (32-bit). */
#define DNLOAD_POINTER_SIZE 4
#endif

#if !defined(USE_LD)
/** Error string for when assembler exit procedure is not available. */
#define DNLOAD_ASM_EXIT_ERROR "no assembler exit procedure defined for current operating system or architecture"
/** Perform exit syscall in assembler. */
static void asm_exit(void)
{
#if !defined(DNLOAD_NO_DEBUGGER_TRAP) && (defined(__x86_64__) || defined(__i386__))
  asm("int $0x3" : /* no output */ : /* no input */ : /* no clobber */);
#elif defined(__x86_64__)
#if defined(__FreeBSD__)
  asm_exit() asm("syscall" : /* no output */ : "a"(1) : /* no clobber */);
#elif defined(__linux__)
  asm_exit() asm("syscall" : /* no output */ : "a"(60) : /* no clobber */);
#else
#pragma message DNLOAD_MACRO_STR(DNLOAD_ASM_EXIT_ERROR)
#error
#endif
#elif defined(__i386__)
#if defined(__FreeBSD__) || defined(__linux__)
  asm("int $0x80" : /* no output */ : "a"(1) : /* no clobber */);
#else
#pragma message DNLOAD_MACRO_STR(DNLOAD_ASM_EXIT_ERROR)
#error
#endif
#elif defined(__arm__)
#if defined(__linux__)
  register int r7 asm("r7") = 1;
  asm("swi #0" : /* no output */ : "r"(r7) : /* no clobber */);
#else
#pragma message DNLOAD_MACRO_STR(DNLOAD_ASM_EXIT_ERROR)
#error
#endif
#else
#pragma message DNLOAD_MACRO_STR(DNLOAD_ASM_EXIT_ERROR)
#error
#endif
}
#endif

#if defined(__cplusplus)
extern "C" {
#endif

#if !defined(USE_LD)
#if defined(__clang__)
/** Program entry point. */
void _start();
#else
/** Program entry point. */
void _start() __attribute__((externally_visible));
#endif
#endif

#if defined(USE_LD)
/** \cond */
#define dnload_SDL_CondSignal SDL_CondSignal
#define dnload_glLinkProgram glLinkProgram
#define dnload_srandom srandom
#define dnload_fminf fminf
#define dnload_glBindBuffer glBindBuffer
#define dnload_SDL_CondWait SDL_CondWait
#define dnload_fmodf fmodf
#define dnload_glFramebufferTexture2D glFramebufferTexture2D
#define dnload_qsort qsort
#define dnload_sinf sinf
#define dnload_atanf atanf
#define dnload_glClear glClear
#define dnload_glUniform3fv glUniform3fv
#define dnload_glGetUniformLocation glGetUniformLocation
#define dnload_SDL_PauseAudio SDL_PauseAudio
#define dnload_SDL_Delay SDL_Delay
#define dnload_glAttachShader glAttachShader
#define dnload_cosf cosf
#define dnload_SDL_mutexP SDL_mutexP
#define dnload_SDL_mutexV SDL_mutexV
#define dnload_SDL_SetVideoMode SDL_SetVideoMode
#define dnload_glGenBuffers glGenBuffers
#define dnload_sqrtf sqrtf
#define dnload_tanf tanf
#define dnload_memset memset
#define dnload_SDL_OpenAudio SDL_OpenAudio
#define dnload_glUniform1f glUniform1f
#define dnload_glUniform1i glUniform1i
#define dnload_glUniform2f glUniform2f
#define dnload_glUniformMatrix3fv glUniformMatrix3fv
#define dnload_glUniformMatrix4fv glUniformMatrix4fv
#define dnload_glBindRenderbuffer glBindRenderbuffer
#define dnload_SDL_WaitThread SDL_WaitThread
#define dnload_glDrawElements glDrawElements
#define dnload_SDL_PollEvent SDL_PollEvent
#define dnload_glCreateShader glCreateShader
#define dnload_SDL_DestroyMutex SDL_DestroyMutex
#define dnload_SDL_Init SDL_Init
#define dnload_glCreateProgram glCreateProgram
#define dnload_glGenRenderbuffers glGenRenderbuffers
#define dnload_SDL_Quit SDL_Quit
#define dnload_SDL_CreateThread SDL_CreateThread
#define dnload_SDL_CreateCond SDL_CreateCond
#define dnload_powf powf
#define dnload_glBindTexture glBindTexture
#define dnload_glBufferData glBufferData
#define dnload_glGenTextures glGenTextures
#define dnload_SDL_DestroyCond SDL_DestroyCond
#define dnload_glBindFramebuffer glBindFramebuffer
#define dnload_glTexImage2D glTexImage2D
#define dnload_glDeleteBuffers glDeleteBuffers
#define dnload_glGenFramebuffers glGenFramebuffers
#define dnload_realloc realloc
#define dnload_glDisable glDisable
#define dnload_SDL_ShowCursor SDL_ShowCursor
#define dnload_glVertexAttribPointer glVertexAttribPointer
#define dnload_glCompileShader glCompileShader
#define dnload_glShaderSource glShaderSource
#define dnload_glDrawArrays glDrawArrays
#define dnload_glRenderbufferStorage glRenderbufferStorage
#define dnload_random random
#define dnload_SDL_CreateMutex SDL_CreateMutex
#define dnload_glUseProgram glUseProgram
#define dnload_roundf roundf
#define dnload_glGetAttribLocation glGetAttribLocation
#define dnload_SDL_GetTicks SDL_GetTicks
#define dnload_glActiveTexture glActiveTexture
#define dnload_SDL_GL_SwapBuffers SDL_GL_SwapBuffers
#define dnload_glTexParameteri glTexParameteri
#define dnload_fabsf fabsf
#define dnload_lrintf lrintf
#define dnload_glEnableVertexAttribArray glEnableVertexAttribArray
#define dnload_glFramebufferRenderbuffer glFramebufferRenderbuffer
#define dnload_glViewport glViewport
#define dnload_glEnable glEnable
#define dnload_fmaxf fmaxf
/** \endcond */
#else
/** \cond */
#define dnload_SDL_CondSignal g_symbol_table.SDL_CondSignal
#define dnload_glLinkProgram g_symbol_table.glLinkProgram
#define dnload_srandom g_symbol_table.srandom
#define dnload_fminf fminf
#define dnload_glBindBuffer g_symbol_table.glBindBuffer
#define dnload_SDL_CondWait g_symbol_table.SDL_CondWait
#define dnload_fmodf g_symbol_table.fmodf
#define dnload_glFramebufferTexture2D g_symbol_table.glFramebufferTexture2D
#define dnload_qsort g_symbol_table.qsort
#define dnload_sinf g_symbol_table.sinf
#define dnload_atanf g_symbol_table.atanf
#define dnload_glClear g_symbol_table.glClear
#define dnload_glUniform3fv g_symbol_table.glUniform3fv
#define dnload_glGetUniformLocation g_symbol_table.glGetUniformLocation
#define dnload_SDL_PauseAudio g_symbol_table.SDL_PauseAudio
#define dnload_SDL_Delay g_symbol_table.SDL_Delay
#define dnload_glAttachShader g_symbol_table.glAttachShader
#define dnload_cosf g_symbol_table.cosf
#define dnload_SDL_mutexP g_symbol_table.SDL_mutexP
#define dnload_SDL_mutexV g_symbol_table.SDL_mutexV
#define dnload_SDL_SetVideoMode g_symbol_table.SDL_SetVideoMode
#define dnload_glGenBuffers g_symbol_table.glGenBuffers
#define dnload_sqrtf sqrtf
#define dnload_tanf tanf
#define dnload_memset g_symbol_table.memset
#define dnload_SDL_OpenAudio g_symbol_table.SDL_OpenAudio
#define dnload_glUniform1f g_symbol_table.glUniform1f
#define dnload_glUniform1i g_symbol_table.glUniform1i
#define dnload_glUniform2f g_symbol_table.glUniform2f
#define dnload_glUniformMatrix3fv g_symbol_table.glUniformMatrix3fv
#define dnload_glUniformMatrix4fv g_symbol_table.glUniformMatrix4fv
#define dnload_glBindRenderbuffer g_symbol_table.glBindRenderbuffer
#define dnload_SDL_WaitThread g_symbol_table.SDL_WaitThread
#define dnload_glDrawElements g_symbol_table.glDrawElements
#define dnload_SDL_PollEvent g_symbol_table.SDL_PollEvent
#define dnload_glCreateShader g_symbol_table.glCreateShader
#define dnload_SDL_DestroyMutex g_symbol_table.SDL_DestroyMutex
#define dnload_SDL_Init g_symbol_table.SDL_Init
#define dnload_glCreateProgram g_symbol_table.glCreateProgram
#define dnload_glGenRenderbuffers g_symbol_table.glGenRenderbuffers
#define dnload_SDL_Quit g_symbol_table.SDL_Quit
#define dnload_SDL_CreateThread g_symbol_table.SDL_CreateThread
#define dnload_SDL_CreateCond g_symbol_table.SDL_CreateCond
#define dnload_powf g_symbol_table.powf
#define dnload_glBindTexture g_symbol_table.glBindTexture
#define dnload_glBufferData g_symbol_table.glBufferData
#define dnload_glGenTextures g_symbol_table.glGenTextures
#define dnload_SDL_DestroyCond g_symbol_table.SDL_DestroyCond
#define dnload_glBindFramebuffer g_symbol_table.glBindFramebuffer
#define dnload_glTexImage2D g_symbol_table.glTexImage2D
#define dnload_glDeleteBuffers g_symbol_table.glDeleteBuffers
#define dnload_glGenFramebuffers g_symbol_table.glGenFramebuffers
#define dnload_realloc g_symbol_table.realloc
#define dnload_glDisable g_symbol_table.glDisable
#define dnload_SDL_ShowCursor g_symbol_table.SDL_ShowCursor
#define dnload_glVertexAttribPointer g_symbol_table.glVertexAttribPointer
#define dnload_glCompileShader g_symbol_table.glCompileShader
#define dnload_glShaderSource g_symbol_table.glShaderSource
#define dnload_glDrawArrays g_symbol_table.glDrawArrays
#define dnload_glRenderbufferStorage g_symbol_table.glRenderbufferStorage
#define dnload_random g_symbol_table.random
#define dnload_SDL_CreateMutex g_symbol_table.SDL_CreateMutex
#define dnload_glUseProgram g_symbol_table.glUseProgram
#define dnload_roundf g_symbol_table.roundf
#define dnload_glGetAttribLocation g_symbol_table.glGetAttribLocation
#define dnload_SDL_GetTicks g_symbol_table.SDL_GetTicks
#define dnload_glActiveTexture g_symbol_table.glActiveTexture
#define dnload_SDL_GL_SwapBuffers g_symbol_table.SDL_GL_SwapBuffers
#define dnload_glTexParameteri g_symbol_table.glTexParameteri
#define dnload_fabsf fabsf
#define dnload_lrintf g_symbol_table.lrintf
#define dnload_glEnableVertexAttribArray g_symbol_table.glEnableVertexAttribArray
#define dnload_glFramebufferRenderbuffer g_symbol_table.glFramebufferRenderbuffer
#define dnload_glViewport g_symbol_table.glViewport
#define dnload_glEnable g_symbol_table.glEnable
#define dnload_fmaxf fmaxf
/** \endcond */
#endif

#if !defined(USE_LD)
/** \brief Symbol table structure.
 *
 * Contains all the symbols required for dynamic linking.
 */
static struct SymbolTableStruct
{
  int (*SDL_CondSignal)(SDL_cond*);
  void (DNLOAD_APIENTRY *glLinkProgram)(GLuint);
  void (*srandom)(unsigned int);
  void (DNLOAD_APIENTRY *glBindBuffer)(GLenum, GLuint);
  int (*SDL_CondWait)(SDL_cond*, SDL_mutex*);
  float (*fmodf)(float, float);
  void (DNLOAD_APIENTRY *glFramebufferTexture2D)(GLenum, GLenum, GLenum, GLuint, GLint);
  void (*qsort)(void*, size_t, size_t, int (*)(const void*, const void*));
  float (*sinf)(float);
  float (*atanf)(float);
  void (DNLOAD_APIENTRY *glClear)(GLbitfield);
  void (DNLOAD_APIENTRY *glUniform3fv)(GLint, GLsizei, const GLfloat*);
  GLint (DNLOAD_APIENTRY *glGetUniformLocation)(GLuint, const GLchar*);
  void (*SDL_PauseAudio)(int);
  void (*SDL_Delay)(Uint32);
  void (DNLOAD_APIENTRY *glAttachShader)(GLuint, GLuint);
  float (*cosf)(float);
  int (*SDL_mutexP)(SDL_mutex*);
  int (*SDL_mutexV)(SDL_mutex*);
  SDL_Surface* (*SDL_SetVideoMode)(int, int, int, Uint32);
  void (DNLOAD_APIENTRY *glGenBuffers)(GLsizei, GLuint*);
  void* (*memset)(void*, int, size_t);
  int (*SDL_OpenAudio)(SDL_AudioSpec*, SDL_AudioSpec*);
  void (DNLOAD_APIENTRY *glUniform1f)(GLint, GLfloat);
  void (DNLOAD_APIENTRY *glUniform1i)(GLint, GLint);
  void (DNLOAD_APIENTRY *glUniform2f)(GLint, GLfloat, GLfloat);
  void (DNLOAD_APIENTRY *glUniformMatrix3fv)(GLint, GLsizei, GLboolean, const GLfloat*);
  void (DNLOAD_APIENTRY *glUniformMatrix4fv)(GLint, GLsizei, GLboolean, const GLfloat*);
  void (DNLOAD_APIENTRY *glBindRenderbuffer)(GLenum, GLuint);
  void (*SDL_WaitThread)(SDL_Thread*, int*);
  void (DNLOAD_APIENTRY *glDrawElements)(GLenum, GLsizei, GLenum, const GLvoid*);
  int (*SDL_PollEvent)(SDL_Event*);
  GLuint (DNLOAD_APIENTRY *glCreateShader)(GLenum);
  void (*SDL_DestroyMutex)(SDL_mutex*);
  int (*SDL_Init)(Uint32);
  GLuint (DNLOAD_APIENTRY *glCreateProgram)(void);
  void (DNLOAD_APIENTRY *glGenRenderbuffers)(GLsizei, GLuint*);
  void (*SDL_Quit)(void);
  SDL_Thread* (*SDL_CreateThread)(int (*)(void*), void*);
  SDL_cond* (*SDL_CreateCond)(void);
  float (*powf)(float, float);
  void (DNLOAD_APIENTRY *glBindTexture)(GLenum, GLuint);
  void (DNLOAD_APIENTRY *glBufferData)(GLenum, GLsizeiptr, const GLvoid*, GLenum);
  void (DNLOAD_APIENTRY *glGenTextures)(GLsizei, GLuint*);
  void (*SDL_DestroyCond)(SDL_cond*);
  void (DNLOAD_APIENTRY *glBindFramebuffer)(GLenum, GLuint);
  void (DNLOAD_APIENTRY *glTexImage2D)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*);
  void (DNLOAD_APIENTRY *glDeleteBuffers)(GLsizei, const GLuint*);
  void (DNLOAD_APIENTRY *glGenFramebuffers)(GLsizei, GLuint*);
  void* (*realloc)(void*, size_t);
  void (DNLOAD_APIENTRY *glDisable)(GLenum);
  int (*SDL_ShowCursor)(int);
  void (DNLOAD_APIENTRY *glVertexAttribPointer)(GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid*);
  void (DNLOAD_APIENTRY *glCompileShader)(GLuint);
  void (DNLOAD_APIENTRY *glShaderSource)(GLuint, GLsizei, const GLchar**, const GLint*);
  void (DNLOAD_APIENTRY *glDrawArrays)(GLenum, GLint, GLsizei);
  void (DNLOAD_APIENTRY *glRenderbufferStorage)(GLenum, GLenum, GLsizei, GLsizei);
  int (*random)(void);
  SDL_mutex* (*SDL_CreateMutex)(void);
  void (DNLOAD_APIENTRY *glUseProgram)(GLuint);
  float (*roundf)(float);
  GLint (DNLOAD_APIENTRY *glGetAttribLocation)(GLuint, const GLchar*);
  uint32_t (*SDL_GetTicks)(void);
  void (DNLOAD_APIENTRY *glActiveTexture)(GLenum);
  void (*SDL_GL_SwapBuffers)(void);
  void (DNLOAD_APIENTRY *glTexParameteri)(GLenum, GLenum, GLint);
  long (*lrintf)(float);
  void (DNLOAD_APIENTRY *glEnableVertexAttribArray)(GLuint);
  void (DNLOAD_APIENTRY *glFramebufferRenderbuffer)(GLenum, GLenum, GLint, GLuint);
  void (DNLOAD_APIENTRY *glViewport)(GLint, GLint, GLsizei, GLsizei);
  void (DNLOAD_APIENTRY *glEnable)(GLenum);
} g_symbol_table =
{
  (int (*)(SDL_cond*))0x11f4f60e,
  (void (DNLOAD_APIENTRY *)(GLuint))0x133a35c5,
  (void (*)(unsigned int))0x1374d96,
  (void (DNLOAD_APIENTRY *)(GLenum, GLuint))0x15aa3ae2,
  (int (*)(SDL_cond*, SDL_mutex*))0x167a16bb,
  (float (*)(float, float))0x16a18daa,
  (void (DNLOAD_APIENTRY *)(GLenum, GLenum, GLenum, GLuint, GLint))0x18781f65,
  (void (*)(void*, size_t, size_t, int (*)(const void*, const void*)))0x19008aaf,
  (float (*)(float))0x1ab23d2e,
  (float (*)(float))0x1d89146,
  (void (DNLOAD_APIENTRY *)(GLbitfield))0x1fd92088,
  (void (DNLOAD_APIENTRY *)(GLint, GLsizei, const GLfloat*))0x223459b4,
  (GLint (DNLOAD_APIENTRY *)(GLuint, const GLchar*))0x25c12218,
  (void (*)(int))0x29f14a4,
  (void (*)(Uint32))0x2ccbf01f,
  (void (DNLOAD_APIENTRY *)(GLuint, GLuint))0x30b3cfcf,
  (float (*)(float))0x353e8f7f,
  (int (*)(SDL_mutex*))0x385e5ed5,
  (int (*)(SDL_mutex*))0x385e5edb,
  (SDL_Surface* (*)(int, int, int, Uint32))0x39b85060,
  (void (DNLOAD_APIENTRY *)(GLsizei, GLuint*))0x3dce2328,
  (void* (*)(void*, int, size_t))0x4593d4cd,
  (int (*)(SDL_AudioSpec*, SDL_AudioSpec*))0x46fd70c8,
  (void (DNLOAD_APIENTRY *)(GLint, GLfloat))0x4fe976c4,
  (void (DNLOAD_APIENTRY *)(GLint, GLint))0x4fe976c7,
  (void (DNLOAD_APIENTRY *)(GLint, GLfloat, GLfloat))0x4fea7703,
  (void (DNLOAD_APIENTRY *)(GLint, GLsizei, GLboolean, const GLfloat*))0x50a8d153,
  (void (DNLOAD_APIENTRY *)(GLint, GLsizei, GLboolean, const GLfloat*))0x5126e0d4,
  (void (DNLOAD_APIENTRY *)(GLenum, GLuint))0x53a3ca18,
  (void (*)(SDL_Thread*, int*))0x62469d23,
  (void (DNLOAD_APIENTRY *)(GLenum, GLsizei, GLenum, const GLvoid*))0x64074f40,
  (int (*)(SDL_Event*))0x64949d97,
  (GLuint (DNLOAD_APIENTRY *)(GLenum))0x6b4ffac6,
  (void (*)(SDL_mutex*))0x6dda9ec9,
  (int (*)(Uint32))0x70d6574,
  (GLuint (DNLOAD_APIENTRY *)(void))0x78721c3,
  (void (DNLOAD_APIENTRY *)(GLsizei, GLuint*))0x7c824ef2,
  (void (*)(void))0x7eb657f3,
  (SDL_Thread* (*)(int (*)(void*), void*))0x83d86faa,
  (SDL_cond* (*)(void))0x8ebee9c2,
  (float (*)(float, float))0x921b2a2e,
  (void (DNLOAD_APIENTRY *)(GLenum, GLuint))0x95e43fb9,
  (void (DNLOAD_APIENTRY *)(GLenum, GLsizeiptr, const GLvoid*, GLenum))0x9aa49d4f,
  (void (DNLOAD_APIENTRY *)(GLsizei, GLuint*))0x9bdd4fa3,
  (void (*)(SDL_cond*))0x9c453778,
  (void (DNLOAD_APIENTRY *)(GLenum, GLuint))0xa0fdff6b,
  (void (DNLOAD_APIENTRY *)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*))0xa259532b,
  (void (DNLOAD_APIENTRY *)(GLsizei, const GLuint*))0xb1319e23,
  (void (DNLOAD_APIENTRY *)(GLsizei, GLuint*))0xb1503371,
  (void* (*)(void*, size_t))0xb1ae4962,
  (void (DNLOAD_APIENTRY *)(GLenum))0xb5f7c43,
  (int (*)(int))0xb88bf697,
  (void (DNLOAD_APIENTRY *)(GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid*))0xc443174a,
  (void (DNLOAD_APIENTRY *)(GLuint))0xc5165dd3,
  (void (DNLOAD_APIENTRY *)(GLuint, GLsizei, const GLchar**, const GLint*))0xc609c385,
  (void (DNLOAD_APIENTRY *)(GLenum, GLint, GLsizei))0xcb871c63,
  (void (DNLOAD_APIENTRY *)(GLenum, GLenum, GLsizei, GLsizei))0xcbd90e40,
  (int (*)(void))0xcbee29a3,
  (SDL_mutex* (*)(void))0xcc177eff,
  (void (DNLOAD_APIENTRY *)(GLuint))0xcc55bb62,
  (float (*)(float))0xcd6ca938,
  (GLint (DNLOAD_APIENTRY *)(GLuint, const GLchar*))0xceb27dd0,
  (uint32_t (*)(void))0xd1d0b104,
  (void (DNLOAD_APIENTRY *)(GLenum))0xd7d4d450,
  (void (*)(void))0xda43e6ea,
  (void (DNLOAD_APIENTRY *)(GLenum, GLenum, GLint))0xdefef0c2,
  (long (*)(float))0xe5e5b9bd,
  (void (DNLOAD_APIENTRY *)(GLuint))0xe9e99723,
  (void (DNLOAD_APIENTRY *)(GLenum, GLenum, GLint, GLuint))0xea8c7dfe,
  (void (DNLOAD_APIENTRY *)(GLint, GLint, GLsizei, GLsizei))0xecca892b,
  (void (DNLOAD_APIENTRY *)(GLenum))0xf1854d68,
};
#endif

#if defined(USE_LD)
/** \cond */
#define dnload()
/** \endcond */
#else
#include <stdint.h>
/** \brief SDBM hash function.
 *
 * \param op String to hash.
 * \return Full hash.
 */
static uint32_t sdbm_hash(const uint8_t *op)
{
  uint32_t ret = 0;
  for(;;)
  {
    uint32_t cc = *op++;
    if(!cc)
    {
      return ret;
    }
    ret = ret * 65599 + cc;
  }
}
#if defined(__FreeBSD__)
#include <sys/link_elf.h>
#elif defined(__linux__)
#include <link.h>
#else
#error "no elf header location known for current platform"
#endif
#if (8 == DNLOAD_POINTER_SIZE)
/** Elf header type. */
typedef Elf64_Ehdr dnload_elf_ehdr_t;
/** Elf program header type. */
typedef Elf64_Phdr dnload_elf_phdr_t;
/** Elf dynamic structure type. */
typedef Elf64_Dyn dnload_elf_dyn_t;
/** Elf symbol table entry type. */
typedef Elf64_Sym dnload_elf_sym_t;
/** Elf dynamic structure tag type. */
typedef Elf64_Sxword dnload_elf_tag_t;
#else
/** Elf header type. */
typedef Elf32_Ehdr dnload_elf_ehdr_t;
/** Elf program header type. */
typedef Elf32_Phdr dnload_elf_phdr_t;
/** Elf dynamic structure type. */
typedef Elf32_Dyn dnload_elf_dyn_t;
/** Elf symbol table entry type. */
typedef Elf32_Sym dnload_elf_sym_t;
/** Elf dynamic structure tag type. */
typedef Elf32_Sword dnload_elf_tag_t;
#endif
/** \brief ELF base address. */
#define ELF_BASE_ADDRESS 0x400000
/** \brief Get dynamic section element by tag.
 *
 * \param dyn Dynamic section.
 * \param tag Tag to look for.
 * \return Pointer to dynamic element.
 */
static const dnload_elf_dyn_t* elf_get_dynamic_element_by_tag(const void *dyn, dnload_elf_tag_t tag)
{
  const dnload_elf_dyn_t *dynamic = (const dnload_elf_dyn_t*)dyn;
  do {
    ++dynamic; // First entry in PT_DYNAMIC is probably nothing important.
#if defined(__linux__) && defined(DNLOAD_SAFE_SYMTAB_HANDLING)
    if(0 == dynamic->d_tag)
    {
      return NULL;
    }
#endif
  } while(dynamic->d_tag != tag);
  return dynamic;
}
#if defined(DNLOAD_NO_FIXED_R_DEBUG_ADDRESS) || defined(DNLOAD_SAFE_SYMTAB_HANDLING)
/** \brief Get the address associated with given tag in a dynamic section.
 *
 * \param dyn Dynamic section.
 * \param tag Tag to look for.
 * \return Address matching given tag.
 */
static const void* elf_get_dynamic_address_by_tag(const void *dyn, dnload_elf_tag_t tag)
{
  const dnload_elf_dyn_t *dynamic = elf_get_dynamic_element_by_tag(dyn, tag);
#if defined(__linux__) && defined(DNLOAD_SAFE_SYMTAB_HANDLING)
  if(NULL == dynamic)
  {
    return NULL;
  }
#endif
  return (const void*)dynamic->d_un.d_ptr;
}
#endif
#if !defined(DNLOAD_NO_FIXED_R_DEBUG_ADDRESS)
/** Link map address, fixed location in ELF headers. */
extern const struct r_debug *dynamic_r_debug;
#endif
/** \brief Get the program link map.
 *
 * \return Link map struct.
 */
static const struct link_map* elf_get_link_map()
{
#if defined(DNLOAD_NO_FIXED_R_DEBUG_ADDRESS)
  // ELF header is in a fixed location in memory.
  // First program header is located directly afterwards.
  const dnload_elf_ehdr_t *ehdr = (const dnload_elf_ehdr_t*)ELF_BASE_ADDRESS;
  const dnload_elf_phdr_t *phdr = (const dnload_elf_phdr_t*)((size_t)ehdr + (size_t)ehdr->e_phoff);
  do {
    ++phdr; // Dynamic header is probably never first in PHDR list.
  } while(phdr->p_type != PT_DYNAMIC);
  // Find the debug entry in the dynamic header array.
  {
    const struct r_debug *debug = (const struct r_debug*)elf_get_dynamic_address_by_tag((const void*)phdr->p_vaddr, DT_DEBUG);
    return debug->r_map;
  }
#else
  return dynamic_r_debug->r_map;
#endif
}
/** \brief Return pointer from link map address.
 *
 * \param lmap Link map.
 * \param ptr Pointer in this link map.
 */
static const void* elf_transform_dynamic_address(const struct link_map *lmap, const void *ptr)
{
#if defined(__FreeBSD__)
  return (uint8_t*)ptr + (size_t)lmap->l_addr;
#else
  (void)lmap;
  return ptr;
#endif
}
#if defined(DNLOAD_SAFE_SYMTAB_HANDLING)
/** \brief Get address of one dynamic section corresponding to given library.
 *
 * \param lmap Link map.
 * \param tag Tag to look for.
 * \return Pointer to given section or NULL.
 */
static const void* elf_get_library_dynamic_section(const struct link_map *lmap, dnload_elf_tag_t tag)
{
  return elf_transform_dynamic_address(lmap, elf_get_dynamic_address_by_tag(lmap->l_ld, tag));
}
#endif
/** \brief Find a symbol in any of the link maps.
 *
 * Should a symbol with name matching the given hash not be present, this function will happily continue until
 * we crash. Size-minimal code has no room for error checking.
 *
 * \param hash Hash of the function name string.
 * \return Symbol found.
 */
static void* dnload_find_symbol(uint32_t hash)
{
  const struct link_map* lmap = elf_get_link_map();
#if defined(__linux__) && (8 == DNLOAD_POINTER_SIZE)
  // On 64-bit Linux, the second entry is not usable.
  lmap = lmap->l_next;
#endif
  for(;;)
  {
    // First entry is this object itself, safe to advance first.
    lmap = lmap->l_next;
    {
#if defined(DNLOAD_SAFE_SYMTAB_HANDLING)
      // Find symbol from link map. We need the string table and a corresponding symbol table.
      const char* strtab = (const char*)elf_get_library_dynamic_section(lmap, DT_STRTAB);
      const dnload_elf_sym_t *symtab = (const dnload_elf_sym_t*)elf_get_library_dynamic_section(lmap, DT_SYMTAB);
      const uint32_t* hashtable = (const uint32_t*)elf_get_library_dynamic_section(lmap, DT_HASH);
      unsigned dynsymcount;
      unsigned ii;
#if defined(__linux__)
      if(NULL == hashtable)
      {
        hashtable = (const uint32_t*)elf_get_library_dynamic_section(lmap, DT_GNU_HASH);
        // DT_GNU_HASH symbol counter borrows from FreeBSD rtld-elf implementation.
        dynsymcount = 0;
        {
          unsigned bucket_count = hashtable[0];
          const uint32_t* buckets = hashtable + 4 + ((sizeof(void*) / 4) * hashtable[2]);
          const uint32_t* chain_zero = buckets + bucket_count + hashtable[1];
          for(ii = 0; (ii < bucket_count); ++ii)
          {
            unsigned bkt = buckets[ii];
            if(bkt == 0)
            {
              continue;
            }
            {
              const uint32_t* hashval = chain_zero + bkt;
              do {
                ++dynsymcount;
              } while(0 == (*hashval++ & 1u));              
            }
          }
        }
      }
      else
#endif
      {
        dynsymcount = hashtable[1];
      }
      for(ii = 0; (ii < dynsymcount); ++ii)
      {
        const dnload_elf_sym_t *sym = &symtab[ii];
#else
      // Assume DT_SYMTAB dynamic entry immediately follows DT_STRTAB dynamic entry.
      // Assume DT_STRTAB memory block immediately follows DT_SYMTAB dynamic entry.
      const dnload_elf_dyn_t *dynamic = elf_get_dynamic_element_by_tag(lmap->l_ld, DT_STRTAB);
      const char* strtab = (const char*)elf_transform_dynamic_address(lmap, (const void*)(dynamic->d_un.d_ptr));
      const dnload_elf_sym_t *sym = (const dnload_elf_sym_t*)elf_transform_dynamic_address(lmap, (const void*)((dynamic + 1)->d_un.d_ptr));
      for(; ((void*)sym < (void*)strtab); ++sym)
      {
#endif
        const char *name = strtab + sym->st_name;
#if defined(DNLOAD_SAFE_SYMTAB_HANDLING)
        // UND symbols have valid names but no value.
        if(!sym->st_value)
        {
          continue;
        }
#endif
        if(sdbm_hash((const uint8_t*)name) == hash)
        {
          //if(!sym->st_value)
          //{
          //  printf("incorrect symbol in library '%s': '%s'\n", lmap->l_name, name);
          //}
          return (void*)((const uint8_t*)sym->st_value + (size_t)lmap->l_addr);
        }
      }
    }
  }
}
/** \brief Perform init.
 *
 * Import by hash - style.
 */
static void dnload(void)
{
  unsigned ii;
  for(ii = 0; (71 > ii); ++ii)
  {
    void **iter = ((void**)&g_symbol_table) + ii;
    *iter = dnload_find_symbol(*(uint32_t*)iter);
  }
}
#endif

#if defined(__cplusplus)
}
#endif

#endif
