mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 16:30:41 +00:00
make class lookup more reliable
This commit is contained in:
parent
d6ef10f224
commit
911c5cdd66
5 changed files with 55 additions and 74 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
||||||
|
2019-02-14 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
* Source/GSPrivate.h:
|
||||||
|
* Source/NSBundle.m:
|
||||||
|
* Source/NSPathUtilities.m:
|
||||||
|
* Source/objc-load.m:
|
||||||
|
GSPrivateSymbolPath() simplified by removing the unused argument
|
||||||
|
and consolidated code so that, if the class lookup via dladdr()
|
||||||
|
fails, we fall back to use __objc_dynamic_get_symbol_path().
|
||||||
|
|
||||||
2019-02-14 Richard Frith-Macdonald <rfm@gnu.org>
|
2019-02-14 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* Source/Additions/GSMime.m: Fix encoded word encoding specifier
|
* Source/Additions/GSMime.m: Fix encoded word encoding specifier
|
||||||
|
|
|
@ -501,16 +501,12 @@ GSPrivateStrExternalize(GSStr s) GS_ATTRIB_PRIVATE;
|
||||||
* argv[0] (which might be something as horrible as './obj/test')
|
* argv[0] (which might be something as horrible as './obj/test')
|
||||||
* for classes in the main executable.
|
* for classes in the main executable.
|
||||||
*
|
*
|
||||||
* If theCategory argument is not NULL, GSPrivateSymbolPath() will return
|
|
||||||
* the filesystem path to the module from which the category theCategory
|
|
||||||
* of the class theClass was loaded.
|
|
||||||
*
|
|
||||||
* Currently, the function will return nil if any of the following
|
* Currently, the function will return nil if any of the following
|
||||||
* conditions is satisfied:
|
* conditions is satisfied:
|
||||||
* - the required functionality is not available on the platform we are
|
* - the required functionality is not available on the platform we are
|
||||||
* running on;
|
* running on;
|
||||||
* - memory allocation fails;
|
* - memory allocation fails;
|
||||||
* - the symbol for that class/category could not be found.
|
* - the symbol for that class could not be found.
|
||||||
*
|
*
|
||||||
* In general, if the function returns nil, it means something serious
|
* In general, if the function returns nil, it means something serious
|
||||||
* went wrong in the system preventing it from getting the symbol path.
|
* went wrong in the system preventing it from getting the symbol path.
|
||||||
|
@ -521,7 +517,7 @@ GSPrivateStrExternalize(GSStr s) GS_ATTRIB_PRIVATE;
|
||||||
* runtime ... as far as I know.
|
* runtime ... as far as I know.
|
||||||
*/
|
*/
|
||||||
NSString *
|
NSString *
|
||||||
GSPrivateSymbolPath (Class theClass, Category *theCategory) GS_ATTRIB_PRIVATE;
|
GSPrivateSymbolPath(Class theClass) GS_ATTRIB_PRIVATE;
|
||||||
|
|
||||||
/* Combining class for composite unichars
|
/* Combining class for composite unichars
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -724,7 +724,7 @@ _find_main_bundle_for_tool(NSString *toolName)
|
||||||
* really universal way of getting the framework path ... we can
|
* really universal way of getting the framework path ... we can
|
||||||
* locate the framework no matter where it is on disk!
|
* locate the framework no matter where it is on disk!
|
||||||
*/
|
*/
|
||||||
bundlePath = GSPrivateSymbolPath (frameworkClass, NULL);
|
bundlePath = GSPrivateSymbolPath(frameworkClass);
|
||||||
|
|
||||||
if ([bundlePath isEqualToString: GSPrivateExecutablePath()])
|
if ([bundlePath isEqualToString: GSPrivateExecutablePath()])
|
||||||
{
|
{
|
||||||
|
@ -1078,7 +1078,7 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory)
|
||||||
_emptyTable = [NSDictionary new];
|
_emptyTable = [NSDictionary new];
|
||||||
|
|
||||||
/* Create basic mapping dictionaries for bootstrapping and
|
/* Create basic mapping dictionaries for bootstrapping and
|
||||||
* for use if the full ductionaries can't be loaded from the
|
* for use if the full dictionaries can't be loaded from the
|
||||||
* gnustep-base library resource bundle.
|
* gnustep-base library resource bundle.
|
||||||
*/
|
*/
|
||||||
langAliases = [[NSDictionary alloc] initWithObjectsAndKeys:
|
langAliases = [[NSDictionary alloc] initWithObjectsAndKeys:
|
||||||
|
@ -1513,7 +1513,7 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory)
|
||||||
|
|
||||||
[load_lock lock];
|
[load_lock lock];
|
||||||
/* Try lookup ... if not found, make sure that all loaded bundles have
|
/* Try lookup ... if not found, make sure that all loaded bundles have
|
||||||
* class->bundle mapp entries set up and check again.
|
* class->bundle map entries set up and check again.
|
||||||
*/
|
*/
|
||||||
bundle = (NSBundle *)NSMapGet(_byClass, aClass);
|
bundle = (NSBundle *)NSMapGet(_byClass, aClass);
|
||||||
if ((id)bundle == (id)[NSNull null])
|
if ((id)bundle == (id)[NSNull null])
|
||||||
|
@ -1561,7 +1561,7 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory)
|
||||||
* convert it to the format for a library name as used for
|
* convert it to the format for a library name as used for
|
||||||
* obtaining a library resource bundle.
|
* obtaining a library resource bundle.
|
||||||
*/
|
*/
|
||||||
lib = GSPrivateSymbolPath (aClass, NULL);
|
lib = GSPrivateSymbolPath(aClass);
|
||||||
if ([lib isEqual: GSPrivateExecutablePath()] == YES)
|
if ([lib isEqual: GSPrivateExecutablePath()] == YES)
|
||||||
{
|
{
|
||||||
lib = nil; // In program, not library.
|
lib = nil; // In program, not library.
|
||||||
|
@ -2707,7 +2707,7 @@ IF_NO_GC(
|
||||||
}
|
}
|
||||||
if (self->_bundleType == NSBUNDLE_LIBRARY)
|
if (self->_bundleType == NSBUNDLE_LIBRARY)
|
||||||
{
|
{
|
||||||
return GSPrivateSymbolPath ([self principalClass], NULL);
|
return GSPrivateSymbolPath([self principalClass]);
|
||||||
}
|
}
|
||||||
object = [[self infoDictionary] objectForKey: @"NSExecutable"];
|
object = [[self infoDictionary] objectForKey: @"NSExecutable"];
|
||||||
if (object == nil || [object length] == 0)
|
if (object == nil || [object length] == 0)
|
||||||
|
|
|
@ -961,7 +961,7 @@ GNUstepConfig(NSDictionary *newConfig)
|
||||||
{
|
{
|
||||||
Class c = [NSProcessInfo class];
|
Class c = [NSProcessInfo class];
|
||||||
|
|
||||||
path = GSPrivateSymbolPath (c, 0);
|
path = GSPrivateSymbolPath(c);
|
||||||
// Remove library name from path
|
// Remove library name from path
|
||||||
path = [path stringByDeletingLastPathComponent];
|
path = [path stringByDeletingLastPathComponent];
|
||||||
if ([file hasPrefix: @"./"] == YES)
|
if ([file hasPrefix: @"./"] == YES)
|
||||||
|
|
|
@ -246,12 +246,11 @@ GSPrivateUnloadModule(FILE *errorStream,
|
||||||
// dladdr() wrapping this function, so we no longer need a Windows-only code
|
// dladdr() wrapping this function, so we no longer need a Windows-only code
|
||||||
// path
|
// path
|
||||||
NSString *
|
NSString *
|
||||||
GSPrivateSymbolPath(Class theClass, Category *theCategory)
|
GSPrivateSymbolPath(Class theClass)
|
||||||
{
|
{
|
||||||
unichar buf[MAX_PATH];
|
unichar buf[MAX_PATH];
|
||||||
NSString *s = nil;
|
NSString *s = nil;
|
||||||
MEMORY_BASIC_INFORMATION memInfo;
|
MEMORY_BASIC_INFORMATION memInfo;
|
||||||
NSCAssert(!theCategory, @"GSPrivateSymbolPath doesn't support categories");
|
|
||||||
|
|
||||||
VirtualQueryEx(GetCurrentProcess(), theClass, &memInfo, sizeof(memInfo));
|
VirtualQueryEx(GetCurrentProcess(), theClass, &memInfo, sizeof(memInfo));
|
||||||
if (GetModuleFileNameW(memInfo.AllocationBase, buf, sizeof(buf)))
|
if (GetModuleFileNameW(memInfo.AllocationBase, buf, sizeof(buf)))
|
||||||
|
@ -263,81 +262,57 @@ GSPrivateSymbolPath(Class theClass, Category *theCategory)
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
#elif LINKER_GETSYMBOL
|
#else
|
||||||
NSString *GSPrivateSymbolPath(Class theClass, Category *theCategory)
|
NSString *GSPrivateSymbolPath(Class theClass)
|
||||||
{
|
{
|
||||||
void *addr = (NULL == theCategory) ? (void*)theClass : (void*)theCategory;
|
#if LINKER_GETSYMBOL
|
||||||
Dl_info info;
|
Dl_info info;
|
||||||
|
|
||||||
/* This is correct: dladdr() does the opposite thing to all other UNIX
|
/* This is correct: dladdr() does the opposite thing to all other UNIX
|
||||||
* functions.
|
* functions.
|
||||||
|
* On success, return the results, otherwise fall back to use the
|
||||||
|
* __objc_dynamic_get_symbol_path() function.
|
||||||
*/
|
*/
|
||||||
if (0 == dladdr(addr, &info))
|
if (0 != dladdr((void*)theClass, &info))
|
||||||
{
|
{
|
||||||
return nil;
|
return [NSString stringWithUTF8String: info.dli_fname];
|
||||||
}
|
}
|
||||||
return [NSString stringWithUTF8String: info.dli_fname];
|
#endif
|
||||||
}
|
|
||||||
#else
|
|
||||||
NSString *
|
|
||||||
GSPrivateSymbolPath(Class theClass, Category *theCategory)
|
|
||||||
{
|
|
||||||
const char *ret;
|
|
||||||
char buf[125], *p = buf;
|
|
||||||
const char *className = class_getName(theClass);
|
|
||||||
int len = strlen(className);
|
|
||||||
|
|
||||||
if (theCategory == NULL)
|
if (theClass != nil)
|
||||||
{
|
{
|
||||||
if (len + sizeof(char)*19 > sizeof(buf))
|
const char *ret;
|
||||||
{
|
char buf[125];
|
||||||
p = malloc(len + sizeof(char)*19);
|
char *p = buf;
|
||||||
|
const char *className = class_getName(theClass);
|
||||||
|
int len = strlen(className);
|
||||||
|
|
||||||
if (p == NULL)
|
if (len + sizeof(char)*19 > sizeof(buf))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Unable to allocate memory !!");
|
p = malloc(len + sizeof(char)*19);
|
||||||
return nil;
|
|
||||||
}
|
if (p == NULL)
|
||||||
}
|
{
|
||||||
|
fprintf(stderr, "Unable to allocate memory !!");
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(p, "__objc_class_name_", sizeof(char)*18);
|
memcpy(p, "__objc_class_name_", sizeof(char)*18);
|
||||||
memcpy(&p[18*sizeof(char)], className, strlen(className) + 1);
|
memcpy(&p[18*sizeof(char)], className, strlen(className) + 1);
|
||||||
|
|
||||||
|
ret = __objc_dynamic_get_symbol_path(0, p);
|
||||||
|
|
||||||
|
if (p != buf)
|
||||||
|
{
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
return [NSString stringWithUTF8String: ret];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
len += strlen(theCategory->category_name);
|
|
||||||
|
|
||||||
if (len + sizeof(char)*23 > sizeof(buf))
|
|
||||||
{
|
|
||||||
p = malloc(len + sizeof(char)*23);
|
|
||||||
|
|
||||||
if (p == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Unable to allocate memory !!");
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(p, "__objc_category_name_", sizeof(char)*21);
|
|
||||||
memcpy(&p[21*sizeof(char)], theCategory->class_name,
|
|
||||||
strlen(theCategory->class_name) + 1);
|
|
||||||
memcpy(&p[strlen(p)], "_", 2*sizeof(char));
|
|
||||||
memcpy(&p[strlen(p)], theCategory->category_name,
|
|
||||||
strlen(theCategory->category_name) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = __objc_dynamic_get_symbol_path(0, p);
|
|
||||||
|
|
||||||
if (p != buf)
|
|
||||||
{
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
return [NSString stringWithUTF8String: ret];
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue