Fixed cstrike module crash on OS X (r=dvander).
authorScott Ehlert <ds@alliedmods.net>
Tue Sep 03 17:56:27 2013 -0500 (2013-09-03)
changeset 1870b19788dcc03
parent 186 23e7e65280de
child 188 83a0f433f014
Fixed cstrike module crash on OS X (r=dvander).

Valve now compiles OS X binaries with -fvisibility=hidden, so dlsym no longer works with non-exported symbols.
dlls/cstrike/cstrike/CstrikeHacks.cpp
     1.1 --- a/dlls/cstrike/cstrike/CstrikeHacks.cpp	Tue Sep 03 17:53:42 2013 -0500
     1.2 +++ b/dlls/cstrike/cstrike/CstrikeHacks.cpp	Tue Sep 03 17:56:27 2013 -0500
     1.3 @@ -11,11 +11,15 @@
     1.4  #endif
     1.5  #endif
     1.6  
     1.7 +#if defined(__APPLE__)
     1.8 +#include <mach-o/nlist.h>
     1.9 +#endif
    1.10 +
    1.11  /* Utils */
    1.12  unsigned char *UTIL_CodeAlloc(size_t size);
    1.13  void UTIL_CodeFree(unsigned char *addr);
    1.14  void UTIL_MemProtect(void *addr, int length, int prot);
    1.15 -bool UTIL_GetLibraryOfAddress(void *memInBase, char *buffer, size_t maxlength);
    1.16 +bool UTIL_GetLibraryOfAddress(void *memInBase, char *buffer, size_t maxlength, uintptr_t *base);
    1.17  
    1.18  /* Detours */
    1.19  void CtrlDetour_ClientCommand(bool set);
    1.20 @@ -72,10 +76,12 @@
    1.21  #if defined(__linux__) || defined(__APPLE__)
    1.22  		/* Find the DLL */
    1.23  		char dll[256];
    1.24 -		if (!UTIL_GetLibraryOfAddress(target, dll, sizeof(dll)))
    1.25 +		uintptr_t base;
    1.26 +		if (!UTIL_GetLibraryOfAddress(target, dll, sizeof(dll), &base))
    1.27  		{
    1.28  			return;
    1.29  		}
    1.30 +#if defined(__linux__)
    1.31  		void *handle = dlopen(dll, RTLD_NOW);
    1.32  		if (!handle)
    1.33  		{
    1.34 @@ -84,7 +90,20 @@
    1.35  		g_UseBotArgs = (int *)dlsym(handle, "UseBotArgs");
    1.36  		g_BotArgs = (const char **)dlsym(handle, "BotArgs");
    1.37  		dlclose(handle);
    1.38 -#else
    1.39 +#elif defined(__APPLE__)
    1.40 +		/* Using dlsym on OS X won't work because the symbols are hidden */
    1.41 +		struct nlist symbols[3];
    1.42 +		memset(symbols, 0, sizeof(symbols));
    1.43 +		symbols[0].n_un.n_name = (char *)"_UseBotArgs";
    1.44 +		symbols[1].n_un.n_name = (char *)"_BotArgs";
    1.45 +		if (nlist(dll, symbols) != 0)
    1.46 +		{
    1.47 +			return;
    1.48 +		}
    1.49 +		g_UseBotArgs = (int *)(base + symbols[0].n_value);
    1.50 +		g_BotArgs = (const char **)(base + symbols[1].n_value);
    1.51 +#endif
    1.52 +#else /* Windows */
    1.53  		/* Find the bot args addresses */
    1.54  		paddr = (unsigned char *)target + CS_CLICMD_OFFS_USEBOTARGS;
    1.55  		g_UseBotArgs = *(int **)paddr;
    1.56 @@ -178,7 +197,7 @@
    1.57  #endif
    1.58  }
    1.59  
    1.60 -bool UTIL_GetLibraryOfAddress(void *memInBase, char *buffer, size_t maxlength)
    1.61 +bool UTIL_GetLibraryOfAddress(void *memInBase, char *buffer, size_t maxlength, uintptr_t *base)
    1.62  {
    1.63  #if defined(__linux__) || defined(__APPLE__)
    1.64  	Dl_info info;
    1.65 @@ -192,6 +211,10 @@
    1.66  	}
    1.67  	const char *dllpath = info.dli_fname;
    1.68  	snprintf(buffer, maxlength, "%s", dllpath);
    1.69 +	if (base)
    1.70 +	{
    1.71 +		*base = (uintptr_t)info.dli_fbase;
    1.72 +	}
    1.73  #else
    1.74  	MEMORY_BASIC_INFORMATION mem;
    1.75  	if (!VirtualQuery(memInBase, &mem, sizeof(mem)))
    1.76 @@ -204,6 +227,10 @@
    1.77  	}
    1.78  	HMODULE dll = (HMODULE)mem.AllocationBase;
    1.79  	GetModuleFileName(dll, (LPTSTR)buffer, maxlength);
    1.80 +	if (base)
    1.81 +	{
    1.82 +		*base = (uintptr_t)mem.AllocationBase;
    1.83 +	}
    1.84  #endif
    1.85  	return true;
    1.86  }