1/* 2 * tkMacOSXDebug.c -- 3 * 4 * Implementation of Macintosh specific functions for debugging MacOS events, 5 * regions, etc... 6 * 7 * Copyright 2001, Apple Computer, Inc. 8 * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net> 9 * 10 * See the file "license.terms" for information on usage and redistribution of 11 * this file, and for a DISCLAIMER OF ALL WARRANTIES. 12 * 13 * The following terms apply to all files originating from Apple 14 * Computer, Inc. ("Apple") and associated with the software 15 * unless explicitly disclaimed in individual files. 16 * 17 * 18 * Apple hereby grants permission to use, copy, modify, 19 * distribute, and license this software and its documentation 20 * for any purpose, provided that existing copyright notices are 21 * retained in all copies and that this notice is included 22 * verbatim in any distributions. No written agreement, license, 23 * or royalty fee is required for any of the authorized 24 * uses. Modifications to this software may be copyrighted by 25 * their authors and need not follow the licensing terms 26 * described here, provided that the new terms are clearly 27 * indicated on the first page of each file where they apply. 28 * 29 * 30 * IN NO EVENT SHALL APPLE, THE AUTHORS OR DISTRIBUTORS OF THE 31 * SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, 32 * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF 33 * THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, 34 * EVEN IF APPLE OR THE AUTHORS HAVE BEEN ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. APPLE, THE AUTHORS AND 36 * DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, 37 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, 38 * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS 39 * SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND APPLE,THE 40 * AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE 41 * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 42 * 43 * GOVERNMENT USE: If you are acquiring this software on behalf 44 * of the U.S. government, the Government shall have only 45 * "Restricted Rights" in the software and related documentation 46 * as defined in the Federal Acquisition Regulations (FARs) in 47 * Clause 52.227.19 (c) (2). If you are acquiring the software 48 * on behalf of the Department of Defense, the software shall be 49 * classified as "Commercial Computer Software" and the 50 * Government shall have only "Restricted Rights" as defined in 51 * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the 52 * foregoing, the authors grant the U.S. Government and others 53 * acting in its behalf permission to use and distribute the 54 * software in accordance with the terms specified in this 55 * license. 56 * 57 * RCS: @(#) $Id: tkMacOSXDebug.c,v 1.2.2.14 2007/11/09 06:26:55 das Exp $ 58 */ 59 60#include "tkMacOSXPrivate.h" 61#include "tkMacOSXDebug.h" 62 63#ifdef TK_MAC_DEBUG 64 65typedef struct { 66 EventKind kind; 67 const char * name; 68} MyEventName; 69 70typedef struct { 71 EventClass c; 72 MyEventName * names; 73} MyEventNameList; 74 75static MyEventName windowEventNames [] = { 76 { kEventWindowUpdate,"Update"}, 77 { kEventWindowDrawContent,"DrawContent"}, 78 { kEventWindowActivated,"Activated"}, 79 { kEventWindowDeactivated,"Deactivated"}, 80 { kEventWindowGetClickActivation,"GetClickActivation"}, 81 { kEventWindowShowing,"Showing"}, 82 { kEventWindowHiding,"Hiding"}, 83 { kEventWindowShown,"Shown"}, 84 { kEventWindowHidden,"Hidden"}, 85 { kEventWindowBoundsChanging,"BoundsChanging"}, 86 { kEventWindowBoundsChanged,"BoundsChanged"}, 87 { kEventWindowResizeStarted,"ResizeStarted"}, 88 { kEventWindowResizeCompleted,"ResizeCompleted"}, 89 { kEventWindowDragStarted,"DragStarted"}, 90 { kEventWindowDragCompleted,"DragCompleted"}, 91 { kEventWindowClickDragRgn,"ClickDragRgn"}, 92 { kEventWindowClickResizeRgn,"ClickResizeRgn"}, 93 { kEventWindowClickCollapseRgn,"ClickCollapseRgn"}, 94 { kEventWindowClickCloseRgn,"ClickCloseRgn"}, 95 { kEventWindowClickZoomRgn,"ClickZoomRgn"}, 96 { kEventWindowClickContentRgn,"ClickContentRgn"}, 97 { kEventWindowClickProxyIconRgn,"ClickProxyIconRgn"}, 98 { kEventWindowCursorChange,"CursorChange" }, 99 { kEventWindowCollapse,"Collapse"}, 100 { kEventWindowCollapsed,"Collapsed"}, 101 { kEventWindowCollapseAll,"CollapseAll"}, 102 { kEventWindowExpand,"Expand"}, 103 { kEventWindowExpanded,"Expanded"}, 104 { kEventWindowExpandAll,"ExpandAll"}, 105 { kEventWindowCollapse,"Collapse"}, 106 { kEventWindowClose,"Close"}, 107 { kEventWindowClosed,"Closed"}, 108 { kEventWindowCloseAll,"CloseAll"}, 109 { kEventWindowZoom,"Zoom"}, 110 { kEventWindowZoomed,"Zoomed"}, 111 { kEventWindowZoomAll,"ZoomAll"}, 112 { kEventWindowContextualMenuSelect,"ContextualMenuSelect"}, 113 { kEventWindowPathSelect,"PathSelect"}, 114 { kEventWindowGetIdealSize,"GetIdealSize"}, 115 { kEventWindowGetMinimumSize,"GetMinimumSize"}, 116 { kEventWindowGetMaximumSize,"GetMaximumSize"}, 117 { kEventWindowConstrain,"Constrain"}, 118 { kEventWindowHandleContentClick,"HandleContentClick"}, 119 { kEventWindowProxyBeginDrag,"ProxyBeginDra}"}, 120 { kEventWindowProxyEndDrag,"ProxyEndDrag"}, 121 { kEventWindowFocusAcquired,"FocusAcquired"}, 122 { kEventWindowFocusRelinquish,"FocusRelinquish"}, 123 { kEventWindowDrawFrame,"DrawFrame"}, 124 { kEventWindowDrawPart,"DrawPart"}, 125 { kEventWindowGetRegion,"GetRegion"}, 126 { kEventWindowHitTest,"HitTest"}, 127 { kEventWindowInit,"Init"}, 128 { kEventWindowDispose,"Dispose"}, 129 { kEventWindowDragHilite,"DragHilite"}, 130 { kEventWindowModified,"Modified"}, 131 { kEventWindowSetupProxyDragImage,"SetupProxyDragImage"}, 132 { kEventWindowStateChanged,"StateChanged"}, 133 { kEventWindowMeasureTitle,"MeasureTitle"}, 134 { kEventWindowDrawGrowBox,"DrawGrowBox"}, 135 { kEventWindowGetGrowImageRegion,"GetGrowImageRegion"}, 136 { kEventWindowPaint,"Paint"}, 137 { 0, NULL }, 138}; 139 140static MyEventName mouseEventNames [] = { 141 { kEventMouseMoved, "Moved"}, 142 { kEventMouseUp, "Up"}, 143 { kEventMouseDown, "Down"}, 144 { kEventMouseDragged, "Dragged"}, 145 { kEventMouseWheelMoved, "WheelMoved"}, 146 { 0, NULL} 147}; 148 149static MyEventName keyboardEventNames [] = { 150 { kEventRawKeyDown, "Down"}, 151 { kEventRawKeyRepeat, "Repeat"}, 152 { kEventRawKeyUp, "Up"}, 153 { kEventRawKeyModifiersChanged, "ModifiersChanged"}, 154 { kEventHotKeyPressed, "HotKeyPressed"}, 155 { kEventHotKeyReleased, "HotKeyReleased"}, 156 { 0, NULL} 157}; 158 159static MyEventName appEventNames [] = { 160 { kEventAppActivated, "Activated"}, 161 { kEventAppDeactivated, "Deactivated"}, 162 { kEventAppQuit, "Quit"}, 163 { kEventAppLaunchNotification, "LaunchNotification"}, 164 { kEventAppLaunched, "Launched"}, 165 { kEventAppTerminated, "Terminated"}, 166 { kEventAppFrontSwitched, "FrontSwitched"}, 167 { 0, NULL} 168}; 169 170static MyEventName menuEventNames [] = { 171 { kEventMenuBeginTracking, "BeginTracking"}, 172 { kEventMenuEndTracking, "EndTracking"}, 173 { kEventMenuChangeTrackingMode, "ChangeTrackingMode"}, 174 { kEventMenuOpening, "Opening"}, 175 { kEventMenuClosed, "Closed"}, 176 { kEventMenuTargetItem, "TargetItem"}, 177 { kEventMenuMatchKey, "MatchKey"}, 178 { kEventMenuEnableItems, "EnableItems"}, 179 { kEventMenuDispose, "Dispose"}, 180 { 0, NULL } 181}; 182 183static MyEventName controlEventNames [] = { 184 { kEventControlInitialize, "Initialize" }, 185 { kEventControlDispose, "Dispose" }, 186 { kEventControlGetOptimalBounds, "GetOptimalBounds" }, 187 { kEventControlHit, "Hit" }, 188 { kEventControlSimulateHit, "SimulateHit" }, 189 { kEventControlHitTest, "HitTest" }, 190 { kEventControlDraw, "Draw" }, 191 { kEventControlApplyBackground, "ApplyBackground" }, 192 { kEventControlApplyTextColor, "ApplyTextColor" }, 193 { kEventControlSetFocusPart, "SetFocusPart" }, 194 { kEventControlGetFocusPart, "GetFocusPart" }, 195 { kEventControlActivate, "Activate" }, 196 { kEventControlDeactivate, "Deactivate" }, 197 { kEventControlSetCursor, "SetCursor" }, 198 { kEventControlContextualMenuClick, "ContextualMenuClick" }, 199 { kEventControlClick, "Click" }, 200 { kEventControlTrack, "Track" }, 201 { kEventControlGetScrollToHereStartPoint, "GetScrollToHereStartPoint" }, 202 { kEventControlGetIndicatorDragConstraint, "GetIndicatorDragConstraint" }, 203 { kEventControlIndicatorMoved, "IndicatorMoved" }, 204 { kEventControlGhostingFinished, "GhostingFinished" }, 205 { kEventControlGetActionProcPart, "GetActionProcPart" }, 206 { kEventControlGetPartRegion, "GetPartRegion" }, 207 { kEventControlGetPartBounds, "GetPartBounds" }, 208 { kEventControlSetData, "SetData" }, 209 { kEventControlGetData, "GetData" }, 210 { kEventControlValueFieldChanged, "ValueFieldChanged" }, 211 { kEventControlAddedSubControl, "AddedSubControl" }, 212 { kEventControlRemovingSubControl, "RemovingSubControl" }, 213 { kEventControlBoundsChanged, "BoundsChanged" }, 214 { kEventControlOwningWindowChanged, "OwningWindowChanged" }, 215 { kEventControlArbitraryMessage, "ArbitraryMessage" }, 216 { 0, NULL } 217}; 218 219static MyEventName commandEventNames [] = { 220 { kEventCommandProcess, "Process" }, 221 { kEventCommandUpdateStatus, "UpdateStatus" }, 222 { 0, NULL } 223}; 224 225static MyEventNameList eventNameList [] = { 226 { kEventClassWindow, windowEventNames }, 227 { kEventClassMouse, mouseEventNames }, 228 { kEventClassKeyboard, keyboardEventNames }, 229 { kEventClassApplication, appEventNames }, 230 { kEventClassMenu, menuEventNames }, 231 { kEventClassControl, controlEventNames }, 232 { kEventClassCommand, commandEventNames }, 233 { 0, NULL} 234}; 235 236#ifdef TK_MACOSXDEBUG_UNUSED 237static MyEventName classicEventNames [] = { 238 { nullEvent,"nullEvent" }, 239 { mouseDown,"mouseDown" }, 240 { mouseUp,"mouseUp" }, 241 { keyDown,"keyDown" }, 242 { keyUp,"keyUp" }, 243 { autoKey,"autoKey" }, 244 { updateEvt,"updateEvt" }, 245 { diskEvt,"diskEvt" }, 246 { activateEvt,"activateEvt" }, 247 { osEvt,"osEvt" }, 248 { kHighLevelEvent,"kHighLevelEvent" }, 249 { 0, NULL } 250}; 251#endif /* TK_MACOSXDEBUG_UNUSED */ 252 253MODULE_SCOPE char * 254TkMacOSXCarbonEventToAscii(EventRef eventRef) 255{ 256 EventClass eventClass; 257 EventKind eventKind; 258 MyEventNameList * list = eventNameList; 259 MyEventName * names = NULL; 260 static char str[256]; 261 char *buf = str; 262 int *iPtr = (int*)str; 263 int found = 0; 264 265 eventClass = GetEventClass(eventRef); 266 eventKind = GetEventKind(eventRef); 267 268 *iPtr = eventClass; 269 buf[4] = 0; 270 strcat(buf, " "); 271 buf += strlen(buf); 272 while (list->names && (!names) ) { 273 if (eventClass == list->c) { 274 names = list -> names; 275 } else { 276 list++; 277 } 278 } 279 while (names && names->name) { 280 if (eventKind == names->kind) { 281 snprintf(buf, 250, "%-20s", names->name); 282 break; 283 } else { 284 names++; 285 } 286 } 287 if (!found) { 288 snprintf(buf, 250, "%-20d", eventKind); 289 } 290 return str; 291} 292 293#ifdef TK_MACOSXDEBUG_UNUSED 294MODULE_SCOPE char * 295TkMacOSXCarbonEventKindToAscii(EventRef eventRef, char * buf ) 296{ 297 EventClass eventClass; 298 EventKind eventKind; 299 MyEventNameList * list = eventNameList; 300 MyEventName * names = NULL; 301 int found = 0; 302 eventClass = GetEventClass(eventRef); 303 eventKind = GetEventKind(eventRef); 304 while (list->names && (!names) ) { 305 if (eventClass == list -> c) { 306 names = list -> names; 307 } else { 308 list++; 309 } 310 } 311 if (names) { 312 found = 0; 313 while ( names->name && !found ) { 314 if (eventKind == names->kind) { 315 sprintf(buf,"%s",names->name); 316 found = 1; 317 } else { 318 names++; 319 } 320 } 321 } 322 if (!found) { 323 sprintf ( buf,"%d", eventKind ); 324 } else { 325 sprintf ( buf,"%d", eventKind ); 326 } 327 return buf; 328} 329 330MODULE_SCOPE char * 331TkMacOSXClassicEventToAscii(EventRecord * eventPtr, char * buf ) 332{ 333 MyEventName * names = NULL; 334 int found = 0; 335 names = classicEventNames; 336 while ( names -> name && !found ) 337 if (eventPtr->what == names->kind) { 338 int * iPtr; 339 char cBuf[8]; 340 iPtr=(int *) &cBuf; 341 *iPtr = eventPtr->message; 342 cBuf[4] = 0; 343 sprintf(buf, "%-16s %08x %04x %s", names->name, 344 (int) eventPtr->message, 345 eventPtr->modifiers, 346 cBuf); 347 found = 1; 348 } else { 349 names++; 350 } 351 if (!found) { 352 sprintf(buf,"%-16d %08x %08x, %s", 353 eventPtr->what, (int) eventPtr->message, 354 eventPtr->modifiers, buf); 355 } 356 return buf; 357 358} 359 360MODULE_SCOPE void 361TkMacOSXPrintPoint(char * tag, Point * p ) 362{ 363 TkMacOSXDbgMsg("%s %4d %4d", tag,p->h,p->v ); 364} 365 366MODULE_SCOPE void 367TkMacOSXPrintRect(char * tag, Rect * r ) 368{ 369 TkMacOSXDbgMsg("%s %4d %4d %4d %4d (%dx%d)", 370 tag, r->left, r->top, r->right, r->bottom, 371 r->right - r->left + 1, r->bottom - r->top + 1); 372} 373 374MODULE_SCOPE void 375TkMacOSXPrintRegion(char * tag, RgnHandle rgn ) 376{ 377 Rect r; 378 GetRegionBounds(rgn,&r); 379 TkMacOSXPrintRect(tag,&r); 380} 381 382MODULE_SCOPE void 383TkMacOSXPrintWindowTitle(char * tag, WindowRef window ) 384{ 385 Str255 title; 386 GetWTitle(window,title); 387 title [title[0] + 1] = 0; 388 TkMacOSXDbgMsg("%s %s", tag, title +1 ); 389} 390 391typedef struct { 392 int msg; 393 char * name; 394} MsgName; 395 396static MsgName msgNames [] = { 397 { kMenuDrawMsg, "Draw"}, 398 { kMenuSizeMsg, "Size"}, 399 { kMenuPopUpMsg, "PopUp"}, 400 { kMenuCalcItemMsg, "CalcItem" }, 401 { kMenuThemeSavvyMsg, "ThemeSavvy"}, 402 { kMenuInitMsg, "Init" }, 403 { kMenuDisposeMsg, "Dispose" }, 404 { kMenuFindItemMsg, "FindItem" }, 405 { kMenuHiliteItemMsg, "HiliteItem" }, 406 { kMenuDrawItemsMsg, "DrawItems" }, 407 { -1, NULL } 408}; 409 410MODULE_SCOPE char * 411TkMacOSXMenuMessageToAscii(int msg, char * s) 412{ 413 MsgName * msgNamePtr; 414 for (msgNamePtr = msgNames;msgNamePtr->name;) { 415 if (msgNamePtr->msg == msg) { 416 strcpy(s,msgNamePtr->name); 417 return s; 418 } else { 419 msgNamePtr++; 420 } 421 } 422 sprintf(s,"unknown : %d", msg ); 423 return s; 424} 425 426static MsgName trackingNames [] = { 427 { kMouseTrackingMousePressed , "MousePressed " }, 428 { kMouseTrackingMouseReleased , "MouseReleased " }, 429 { kMouseTrackingMouseExited , "MouseExited " }, 430 { kMouseTrackingMouseEntered , "MouseEntered " }, 431 { kMouseTrackingMouseMoved , "MouseMoved " }, 432 { kMouseTrackingKeyModifiersChanged, "KeyModifiersChanged" }, 433 { kMouseTrackingUserCancelled , "UserCancelled " }, 434 { kMouseTrackingTimedOut , "TimedOut " }, 435 { -1, NULL } 436}; 437 438MODULE_SCOPE char * 439TkMacOSXMouseTrackingResultToAscii(MouseTrackingResult r, char * buf) 440{ 441 MsgName * namePtr; 442 for (namePtr = trackingNames; namePtr->name; namePtr++) { 443 if (namePtr->msg == r) { 444 strcpy(buf, namePtr->name); 445 return buf; 446 } 447 } 448 sprintf(buf, "Unknown mouse tracking result : %d", r); 449 return buf; 450} 451#endif /* TK_MACOSXDEBUG_UNUSED */ 452 453MODULE_SCOPE void 454TkMacOSXDebugFlashRegion( 455 Drawable d, 456 HIShapeRef rgn) 457{ 458 TkMacOSXInitNamedDebugSymbol(HIToolbox, int, QDDebugFlashRegion, 459 CGrafPtr port, RgnHandle region); 460 CFShow(rgn); 461 if (d && rgn && QDDebugFlashRegion && !HIShapeIsEmpty(rgn)) { 462 CGrafPtr port = TkMacOSXGetDrawablePort(d); 463 464 if (port) { 465 static RgnHandle qdRgn = NULL; 466 467 if (!qdRgn) { 468 qdRgn = NewRgn(); 469 } 470 ChkErr(HIShapeGetAsQDRgn, rgn, qdRgn); 471 472 /* 473 * Carbon-internal region flashing SPI (c.f. Technote 2124) 474 */ 475 476 QDDebugFlashRegion(port, qdRgn); 477 SetEmptyRgn(qdRgn); 478 } 479 } 480} 481 482#include <mach-o/dyld.h> 483#include <mach-o/nlist.h> 484 485/* 486 *---------------------------------------------------------------------- 487 * 488 * TkMacOSXGetNamedDebugSymbol -- 489 * 490 * 491 * Dynamically acquire address of a named symbol from a loaded 492 * dynamic library, so that we can use API that may not be 493 * available on all OS versions. 494 * For debugging purposes, if we cannot find the symbol with the 495 * usual dynamic library APIs, we manually walk the symbol table 496 * of the loaded library. This allows access to unexported 497 * symbols such as private_extern internal debugging functions. 498 * If module is NULL or the empty string, search all loaded 499 * libraries (could be very expensive and should be avoided). 500 * 501 * THIS FUCTION IS ONLY TO BE USED FOR DEBUGGING PURPOSES, IT MAY 502 * BREAK UNEXPECTEDLY IN THE FUTURE ! 503 * 504 * Results: 505 * Address of given symbol or NULL if unavailable. 506 * 507 * Side effects: 508 * None. 509 * 510 *---------------------------------------------------------------------- 511 */ 512 513MODULE_SCOPE void * 514TkMacOSXGetNamedDebugSymbol( 515 const char* module, 516 const char* symbol) 517{ 518 void* addr = TkMacOSXGetNamedSymbol(module, symbol); 519#ifndef __LP64__ 520 if (!addr) { 521 const struct mach_header *mh = NULL; 522 uint32_t i, n = _dyld_image_count(); 523 size_t module_len = 0; 524 525 if (module && *module) { 526 module_len = strlen(module); 527 } 528 for (i = 0; i < n; i++) { 529 if (module && *module) { 530 /* Find image with given module name */ 531 char *name; 532 const char *path = _dyld_get_image_name(i); 533 534 if (!path) { 535 continue; 536 } 537 name = strrchr(path, '/') + 1; 538 if (strncmp(name, module, module_len) != 0) { 539 continue; 540 } 541 } 542 mh = _dyld_get_image_header(i); 543 if (mh) { 544 struct load_command *lc; 545 struct symtab_command *st = NULL; 546 struct segment_command *sg = NULL; 547 uint32_t j, m, nsect = 0, txtsectx = 0; 548 549 lc = (struct load_command*)((const char*) mh + 550 sizeof(struct mach_header)); 551 m = mh->ncmds; 552 for (j = 0; j < m; j++) { 553 /* Find symbol table and index of __text section */ 554 if (lc->cmd == LC_SEGMENT) { 555 /* Find last segment before symbol table */ 556 sg = (struct segment_command*) lc; 557 if (!txtsectx) { 558 /* Count total sections until (__TEXT, __text) */ 559 uint32_t k, ns = sg->nsects; 560 561 if (strcmp(sg->segname, SEG_TEXT) == 0) { 562 struct section *s = (struct section *)( 563 (char *)sg + 564 sizeof(struct segment_command)); 565 566 for(k = 0; k < ns; k++) { 567 if (strcmp(s->sectname, SECT_TEXT) == 0) { 568 txtsectx = nsect+k+1; 569 break; 570 } 571 s++; 572 } 573 } 574 nsect += ns; 575 } 576 } else if (!st && lc->cmd == LC_SYMTAB) { 577 st = (struct symtab_command*) lc; 578 break; 579 } 580 lc = (struct load_command *)((char *) lc + lc->cmdsize); 581 } 582 if (st && sg && txtsectx) { 583 intptr_t base, slide = _dyld_get_image_vmaddr_slide(i); 584 char *strings; 585 struct nlist *sym; 586 uint32_t strsize = st->strsize; 587 int32_t strx; 588 589 /* Offset file positions by difference to actual position 590 in memory of last segment before symbol table: */ 591 base = (intptr_t) sg->vmaddr + slide - sg->fileoff; 592 strings = (char*)(base + st->stroff); 593 sym = (struct nlist*)(base + st->symoff); 594 m = st->nsyms; 595 for (j = 0; j < m; j++) { 596 /* Find symbol with given name in __text section */ 597 strx = sym->n_un.n_strx; 598 if ((sym->n_type & N_TYPE) == N_SECT && 599 sym->n_sect == txtsectx && 600 strx > 0 && (uint32_t) strx < strsize && 601 strcmp(strings + strx, symbol) == 0) { 602 addr = (char*) sym->n_value + slide; 603 break; 604 } 605 sym++; 606 } 607 } 608 } 609 if (module && *module) { 610 /* If given a module name, only search corresponding image */ 611 break; 612 } 613 } 614 } 615#endif /* __LP64__ */ 616 return addr; 617} 618 619#endif /* TK_MAC_DEBUG */ 620