Import Tk 8.6.6 (as of svn r86089)
This commit is contained in:
166
macosx/tkMacOSXDebug.c
Normal file
166
macosx/tkMacOSXDebug.c
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* tkMacOSXDebug.c --
|
||||
*
|
||||
* Implementation of Macintosh specific functions for debugging MacOS
|
||||
* events, regions, etc...
|
||||
*
|
||||
* Copyright 2001-2009, Apple Inc.
|
||||
* Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
|
||||
*
|
||||
* See the file "license.terms" for information on usage and redistribution
|
||||
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
*/
|
||||
|
||||
#include "tkMacOSXPrivate.h"
|
||||
#include "tkMacOSXDebug.h"
|
||||
|
||||
#ifdef TK_MAC_DEBUG
|
||||
|
||||
#include <mach-o/dyld.h>
|
||||
#include <mach-o/nlist.h>
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
MODULE_SCOPE 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();
|
||||
size_t module_len = 0;
|
||||
|
||||
if (module && *module) {
|
||||
module_len = strlen(module);
|
||||
}
|
||||
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, module_len) != 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*)((const 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 && (uint32_t) strx < strsize &&
|
||||
strcmp(strings + strx, symbol) == 0) {
|
||||
addr = (char*) 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 */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: objc
|
||||
* c-basic-offset: 4
|
||||
* fill-column: 79
|
||||
* coding: utf-8
|
||||
* End:
|
||||
*/
|
||||
Reference in New Issue
Block a user