diff options
author | das <das> | 2006-01-10 05:38:19 (GMT) |
---|---|---|
committer | das <das> | 2006-01-10 05:38:19 (GMT) |
commit | bad210c83a783476d088f18141f858e71894fea3 (patch) | |
tree | 87862859fde56ea445ee805d344b86ae4489b329 /macosx/tkMacOSXDebug.c | |
parent | c97f485feb8a8de6050fa13f72a5a808cc6f05d0 (diff) | |
download | tk-bad210c83a783476d088f18141f858e71894fea3.zip tk-bad210c83a783476d088f18141f858e71894fea3.tar.gz tk-bad210c83a783476d088f18141f858e71894fea3.tar.bz2 |
* macosx/tkMacOSXDraw.c: re-added inclusion of tclInt.h to allow access
* macosx/tkMacOSXFont.c: to 8.4-internal Tcl_CreateNamespace().
* macosx/tkMacOSXDebug.c: add TkMacOSXGetNamedDebugSymbol() function
* macosx/tkMacOSXDebug.h: that finds unexported symbols in loaded
libraries by manually walking their symbol table; only to be used for
debugging purposes, may break unexpectedly in the future. Needed to get
access to private_extern internal debugging functions in HIToolbox.
* macosx/tkMacOSXCarbonEvents.c: fix debug event tracing on Tiger.
* macosx/tkMacOSXMenu.c: add debug menu printing during reconfigure.
* macosx/tkMacOSXInit.c: conditionalize 64bit-unsafe dyld code.
* macosx/Makefile: add 'wish8.x' symlink to SYMROOT.
* unix/configure: add caching, use AC_CACHE_CHECK instead of
* unix/configure.in: AC_CACHE_VAL where possible, consistent message
* unix/tcl.m4: quoting, sync relevant tclconfig/tcl.m4 changes and
gratuitous formatting differences, fix SC_CONFIG_MANPAGES with default
argument, Darwin improvements to SC_LOAD_*CONFIG.
Diffstat (limited to 'macosx/tkMacOSXDebug.c')
-rw-r--r-- | macosx/tkMacOSXDebug.c | 134 |
1 files changed, 133 insertions, 1 deletions
diff --git a/macosx/tkMacOSXDebug.c b/macosx/tkMacOSXDebug.c index 77d700d..37d2750 100644 --- a/macosx/tkMacOSXDebug.c +++ b/macosx/tkMacOSXDebug.c @@ -50,13 +50,17 @@ * software in accordance with the terms specified in this * license. * - * RCS: @(#) $Id: tkMacOSXDebug.c,v 1.2.2.4 2005/11/27 02:36:46 das Exp $ + * RCS: @(#) $Id: tkMacOSXDebug.c,v 1.2.2.5 2006/01/10 05:38:20 das Exp $ */ +#include "tkMacOSXInt.h" #include "tkMacOSXDebug.h" #ifdef TK_MAC_DEBUG +#include <mach-o/dyld.h> +#include <mach-o/nlist.h> + typedef struct { EventKind kind; char * name; @@ -447,5 +451,133 @@ MouseTrackingResultToAscii(MouseTrackingResult r, char * buf) sprintf(buf, "Unknown mouse tracking result : %d", r); return buf; } + +/* + *---------------------------------------------------------------------- + * + * TkMacOSXGetNamedDebugSymbol -- + * + * + * Dynamically acquire address of a named symbol from a loaded + * dynamic library, so that we can use API that may not be + * available on all OS versions. + * For debugging purposes, if we cannot find the symbol with the + * usual dynamic library APIs, we manually walk the symbol table + * of the loaded library. This allows access to unexported + * symbols such as private_extern internal debugging functions. + * If module is NULL or the empty string, search all loaded + * libraries (could be very expensive and should be avoided). + * + * THIS FUCTION IS ONLY TO BE USED FOR DEBUGGING PURPOSES, IT MAY + * BREAK UNEXPECTEDLY IN THE FUTURE ! + * + * Results: + * Address of given symbol or NULL if unavailable. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +void * +TkMacOSXGetNamedDebugSymbol(const char* module, const char* symbol) +{ + void* addr = TkMacOSXGetNamedSymbol(module, symbol); +#ifndef __LP64__ + if (!addr) { + const struct mach_header *mh = NULL; + uint32_t i, n = _dyld_image_count(); + + for (i = 0; i < n; i++) { + if (module && *module) { + /* Find image with given module name */ + char *name; + const char *path = _dyld_get_image_name(i); + + if (!path) { + continue; + } + name = strrchr(path, '/') + 1; + if (strncmp(name, module, strlen(name)) != 0) { + continue; + } + } + mh = _dyld_get_image_header(i); + if (mh) { + struct load_command *lc; + struct symtab_command *st = NULL; + struct segment_command *sg = NULL; + uint32_t j, m, nsect = 0, txtsectx = 0; + + lc = (struct load_command*)((char *) mh + + sizeof(struct mach_header)); + m = mh->ncmds; + for (j = 0; j < m; j++) { + /* Find symbol table and index of __text section */ + if (lc->cmd == LC_SEGMENT) { + /* Find last segment before symbol table */ + sg = (struct segment_command*) lc; + if (!txtsectx) { + /* Count total sections until (__TEXT, __text) */ + uint32_t k, ns = sg->nsects; + + if (strcmp(sg->segname, SEG_TEXT) == 0) { + struct section *s = (struct section *)( + (char *)sg + + sizeof(struct segment_command)); + + for(k = 0; k < ns; k++) { + if (strcmp(s->sectname, SECT_TEXT) == 0) { + txtsectx = nsect+k+1; + break; + } + s++; + } + } + nsect += ns; + } + } else if (!st && lc->cmd == LC_SYMTAB) { + st = (struct symtab_command*) lc; + break; + } + lc = (struct load_command *)((char *) lc + lc->cmdsize); + } + if (st && sg && txtsectx) { + intptr_t base, slide = _dyld_get_image_vmaddr_slide(i); + char *strings; + struct nlist *sym; + uint32_t strsize = st->strsize; + int32_t strx; + + /* Offset file positions by difference to actual position + in memory of last segment before symbol table: */ + base = (intptr_t) sg->vmaddr + slide - sg->fileoff; + strings = (char*)(base + st->stroff); + sym = (struct nlist*)(base + st->symoff); + m = st->nsyms; + for (j = 0; j < m; j++) { + /* Find symbol with given name in __text section */ + strx = sym->n_un.n_strx; + if ((sym->n_type & N_TYPE) == N_SECT && + sym->n_sect == txtsectx && + strx > 0 && strx < strsize && + strcmp(strings + strx, symbol) == 0) { + addr = (void*) sym->n_value + slide; + break; + } + sym++; + } + } + } + if (module && *module) { + /* If given a module name, only search corresponding image */ + break; + } + } + } +#endif /* __LP64__ */ + return addr; +} #endif /* TK_MAC_DEBUG */ |