blob: 8d05fa79912495c1e85421264e4f34a3590fa673 [file] [log] [blame]
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* This file will include OS specific functions which are not inlineable.
* Any inlineable functions should be defined in os-inline.c instead.
*/
#include "ap_config.h"
#include "os.h"
/* some linkers complain unless there's at least one function in each
* .o file... and extra prototype is for gcc -Wmissing-prototypes
*/
extern void ap_is_not_here(void);
void ap_is_not_here(void) {}
/*
* Insert the DSO emulation code for AIX for releases of AIX prior
* to 4.3. Use the native DSO code for 4.3 and later.
*/
#if defined(AIX) && !defined(NO_DL_NEEDED)
#if AIX < 430
#include "os-aix-dso.c"
#endif
#endif
/*
* Abstraction layer for loading
* Apache modules under run-time via
* dynamic shared object (DSO) mechanism
*/
#ifdef HAVE_DYLD /* NeXT/Apple dynamic linker */
#include <mach-o/dyld.h>
/*
* NSUnlinkModule() is a noop in old versions of dyld.
* Let's install an error handler to deal with "multiply defined
* symbol" runtime errors.
*/
#ifdef DYLD_CANT_UNLOAD
#include "httpd.h"
#include "http_log.h"
ap_private_extern
void undefined_symbol_handler(const char *symbolName)
{
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_EMERG, NULL,
"dyld found undefined symbol: %s\n"
"Aborting.\n",
symbolName);
abort();
}
ap_private_extern
NSModule multiple_symbol_handler (NSSymbol s, NSModule old, NSModule new)
{
/*
* Since we can't unload symbols, we're going to run into this
* every time we reload a module. Workaround here is to just
* rebind to the new symbol, and forget about the old one.
* This is crummy, because it's basically a memory leak.
*/
#ifdef DEBUG
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, NULL,
"dyld found a multiply defined symbol %s in modules:\n"
"%s\n%s\n",
NSNameOfSymbol(s),
NSNameOfModule(old), NSNameOfModule(new));
#endif
return(new);
}
ap_private_extern
void linkEdit_symbol_handler (NSLinkEditErrors c, int errorNumber,
const char *fileName, const char *errorString)
{
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_EMERG, NULL,
"dyld errors during link edit for file %s\n%s\n",
fileName, errorString);
abort();
}
#endif /* DYLD_CANT_UNLOAD */
#endif /* HAVE_DYLD */
void ap_os_dso_init(void)
{
#if defined(HAVE_DYLD) && defined(DYLD_CANT_UNLOAD)
NSLinkEditErrorHandlers handlers;
handlers.undefined = undefined_symbol_handler;
handlers.multiple = multiple_symbol_handler;
handlers.linkEdit = linkEdit_symbol_handler;
NSInstallLinkEditErrorHandlers(&handlers);
#endif
}
void *ap_os_dso_load(const char *path)
{
#if defined(HPUX) || defined(HPUX10) || defined(HPUX11)
shl_t handle;
handle = shl_load(path, BIND_IMMEDIATE|BIND_VERBOSE, 0L);
return (void *)handle;
#elif defined(HAVE_DYLD)
NSObjectFileImage image;
NSModule handle;
if (NSCreateObjectFileImageFromFile(path, &image) !=
NSObjectFileImageSuccess)
return NULL;
#if defined(NSLINKMODULE_OPTION_RETURN_ON_ERROR) && defined(NSLINKMODULE_OPTION_NONE)
handle = NSLinkModule(image, path,
NSLINKMODULE_OPTION_RETURN_ON_ERROR |
NSLINKMODULE_OPTION_NONE);
#else
handle = NSLinkModule(image, path, FALSE);
#endif
NSDestroyObjectFileImage(image);
return handle;
#elif defined(OSF1) || defined(SEQUENT) ||\
(defined(__FreeBSD_version) && (__FreeBSD_version >= 220000))
return dlopen((char *)path, RTLD_NOW | RTLD_GLOBAL);
#else
return dlopen(path, RTLD_NOW | RTLD_GLOBAL);
#endif
}
void ap_os_dso_unload(void *handle)
{
#if defined(HPUX) || defined(HPUX10) || defined(HPUX11)
shl_unload((shl_t)handle);
#elif defined(HAVE_DYLD)
NSUnLinkModule(handle,FALSE);
#else
dlclose(handle);
#endif
return;
}
void *ap_os_dso_sym(void *handle, const char *symname)
{
#if defined(HPUX) || defined(HPUX10) || defined(HPUX11)
void *symaddr = NULL;
int status;
errno = 0;
status = shl_findsym((shl_t *)&handle, symname, TYPE_PROCEDURE, &symaddr);
if (status == -1 && errno == 0) /* try TYPE_DATA instead */
status = shl_findsym((shl_t *)&handle, symname, TYPE_DATA, &symaddr);
return (status == -1 ? NULL : symaddr);
#elif defined(HAVE_DYLD)
NSSymbol symbol;
char *symname2 = (char*)malloc(sizeof(char)*(strlen(symname)+2));
sprintf(symname2, "_%s", symname);
symbol = NSLookupAndBindSymbol(symname2);
free(symname2);
return NSAddressOfSymbol(symbol);
#elif defined(DLSYM_NEEDS_UNDERSCORE)
char *symbol = (char*)malloc(sizeof(char)*(strlen(symname)+2));
void *retval;
sprintf(symbol, "_%s", symname);
retval = dlsym(handle, symbol);
free(symbol);
return retval;
#elif defined(SEQUENT)
return dlsym(handle, (char *)symname);
#else
return dlsym(handle, symname);
#endif
}
const char *ap_os_dso_error(void)
{
#if defined(HPUX) || defined(HPUX10) || defined(HPUX11)
return strerror(errno);
#elif defined(HAVE_DYLD)
return NULL;
#else
return dlerror();
#endif
}