First Checked In.

git-svn-id: svn://10.0.0.236/trunk@50229 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
beard%netscape.com
1999-10-08 17:51:45 +00:00
parent 2b7533ef10
commit f5cc851bd0
7 changed files with 883 additions and 0 deletions

View File

@@ -0,0 +1,40 @@
=============================================
MetroNub Utilities Release Notes
=============================================
Date: 5/3/96
Author: Mike Lockwood
=============================================
MetroNub Utilities is an API that you can use in your program to communicate
with MetroNub. To use, just add the file MetroNubUtils.c to your project.
You can call IsMetroNubInstalled to find out if MetroNub is installed on your
machine, and the version of MetroNub supports the MetroNub Utilities API.
You can call IsMWDebuggerRunning to find out if the Metrowerks debugger is
currently running on your machine. Similarly, you can call AmIBeingMWDebugged
to find out if the Metrowerks debugger is currently debugging your program.
You might do this, for example, to decide whether or not to execute a DebugStr
within your program, or to enable other code only when you are debugging.
The MetroNub Utilities API is extensible, so we may add new utility functions
in the future. Be sure to let us know if you have any suggestions for future
versions of the API.
=====================
Contacting Metrowerks
=====================
For bug reports, technical questions and suggestions, please use the forms
in the Release Notes folder on the CD, and send them to support@metrowerks.com
You may also post reports, questions and suggestions about Java CodeWarrior to
comp.lang.java
Metrowerks tech support monitors this newsgroup closely.
--------------------------------------------------------------------------------
Mike Lockwood
Metrowerks Corporation

View File

@@ -0,0 +1,124 @@
// ===========================================================================
// MetroNubUserInterface.h ©1996-1998 Metrowerks Inc. All rights reserved.
// ===========================================================================
#ifndef __MetroNubUserInterface__
#define __MetroNubUserInterface__
#pragma once
#include <CodeFragments.h>
#if PRAGMA_ALIGN_SUPPORTED
#pragma options align=mac68k
#endif
#ifdef __cplusplus
extern "C" {
#endif
// ---------------------------------------------------------------------------
// ¥ Constants
// ---------------------------------------------------------------------------
const short kMetroNubUserAPIVersion = 1; // current User API version
const OSType kMetroNubUserSignature = 'MnUI';
// ---------------------------------------------------------------------------
// ¥ IsDebuggerRunning
// ---------------------------------------------------------------------------
// pascal Boolean IsDebuggerRunning ();
typedef pascal Boolean (*IsDebuggerRunningProcPtr)();
#if GENERATINGCFM
typedef UniversalProcPtr IsDebuggerRunningUPP;
#else
typedef IsDebuggerRunningProcPtr IsDebuggerRunningUPP;
#endif
enum {
uppIsDebuggerRunningProcInfo = kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(Boolean)))
};
#if GENERATINGCFM
#define NewIsDebuggerRunningProc(userRoutine) \
(IsDebuggerRunningUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppIsDebuggerRunningProcInfo, GetCurrentArchitecture())
#else
#define NewIsDebuggerRunningProc(userRoutine) \
((IsDebuggerRunningUPP) (userRoutine))
#endif
#if GENERATINGCFM
#define CallIsDebuggerRunningProc(userRoutine) \
CallUniversalProc((UniversalProcPtr)(userRoutine), uppIsDebuggerRunningProcInfo)
#else
#define CallIsDebuggerRunningProc(userRoutine) \
(*(userRoutine))()
#endif
// ---------------------------------------------------------------------------
// ¥ AmIBeingDebugged
// ---------------------------------------------------------------------------
// pascal Boolean AmIBeingDebugged ();
typedef pascal Boolean (*AmIBeingDebuggedProcPtr)();
#if GENERATINGCFM
typedef UniversalProcPtr AmIBeingDebuggedUPP;
#else
typedef AmIBeingDebuggedProcPtr AmIBeingDebuggedUPP;
#endif
enum {
uppAmIBeingDebuggedProcInfo = kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(Boolean)))
};
#if GENERATINGCFM
#define NewAmIBeingDebuggedProc(userRoutine) \
(AmIBeingDebuggedUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppAmIBeingDebuggedProcInfo, GetCurrentArchitecture())
#else
#define NewAmIBeingDebuggedProc(userRoutine) \
((AmIBeingDebuggedUPP) (userRoutine))
#endif
#if GENERATINGCFM
#define CallAmIBeingDebuggedProc(userRoutine) \
CallUniversalProc((UniversalProcPtr)(userRoutine), uppAmIBeingDebuggedProcInfo)
#else
#define CallAmIBeingDebuggedProc(userRoutine) \
(*(userRoutine))()
#endif
// ---------------------------------------------------------------------------
// ¥ MetroNubUserEntryBlock
// ---------------------------------------------------------------------------
struct MetroNubUserEntryBlock
{
long blockLength; // length of this block
short apiLowVersion; // lowest supported version of the Nub API
short apiHiVersion; // highest supported version of the Nub API
Str31 nubVersion; // short version string from 'vers' 1 resource
IsDebuggerRunningUPP isDebuggerRunning;
AmIBeingDebuggedUPP amIBeingDebugged;
};
typedef struct MetroNubUserEntryBlock MetroNubUserEntryBlock;
#ifdef __cplusplus
}
#endif
#if PRAGMA_ALIGN_SUPPORTED
#pragma options align=reset
#endif
#endif

View File

@@ -0,0 +1,72 @@
// ===========================================================================
// MetroNubUtils.c ©1996-1998 Metrowerks Inc. All rights reserved.
// ===========================================================================
#ifndef __MetroNubUtils__
#include "MetroNubUtils.h"
#endif
#ifndef __MetroNubUserInterface__
#include "MetroNubUserInterface.h"
#endif
#ifndef __GESTALT__
#include <Gestalt.h>
#endif
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
static MetroNubUserEntryBlock* gMetroNubEntry = NULL;
Boolean IsMetroNubInstalled()
{
static Boolean lookedForMetroNub = false;
if (! lookedForMetroNub)
{
long result;
// look for MetroNub's Gestalt selector
if (Gestalt(kMetroNubUserSignature, &result) == noErr)
{
MetroNubUserEntryBlock* block = (MetroNubUserEntryBlock *)result;
// make sure the version of the API is compatible
if (block->apiLowVersion <= kMetroNubUserAPIVersion &&
kMetroNubUserAPIVersion <= block->apiHiVersion)
gMetroNubEntry = block; // success!
}
lookedForMetroNub = true;
}
return (gMetroNubEntry != NULL);
}
Boolean IsMWDebuggerRunning()
{
if (IsMetroNubInstalled())
return CallIsDebuggerRunningProc(gMetroNubEntry->isDebuggerRunning);
else
return false;
}
Boolean AmIBeingMWDebugged()
{
if (IsMetroNubInstalled())
return CallAmIBeingDebuggedProc(gMetroNubEntry->amIBeingDebugged);
else
return false;
}

View File

@@ -0,0 +1,29 @@
// ===========================================================================
// MetroNubUtils.h ©1996-1998 Metrowerks Inc. All rights reserved.
// ===========================================================================
#ifndef __MetroNubUtils__
#define __MetroNubUtils__
#pragma once
#include <Types.h>
#ifdef __cplusplus
extern "C" {
#endif
Boolean IsMetroNubInstalled(); // returns true if a compatible version
// of MetroNub is installed
Boolean IsMWDebuggerRunning(); // returns true if the Metrowerks debugger
// is running
Boolean AmIBeingMWDebugged(); // returns true if this process is being
// debugged by the Metrowerks debugger
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,302 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (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.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Patrick C. Beard <beard@netscape.com>
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the NPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the NPL or the GPL.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Memory.h>
#include "SymFiles.h"
#include "sym_file.h"
#include "gc.h"
extern "C" {
FILE* FSp_fopen(ConstFSSpecPtr spec, const char * open_mode);
}
static int getFileReferenceTableEntry(FILE* symFile,
const DiskSymbolHeaderBlock& header,
const FileReference& fileRef,
FileReferenceTableEntry* frte)
{
UInt32 fileRefsPerPage = (header.dshb_page_size / sizeof(FileReferenceTableEntry));
UInt32 fileRefPage = (fileRef.fref_frte_index / fileRefsPerPage);
UInt32 fileRefIndex = (fileRef.fref_frte_index % fileRefsPerPage);
// seek to the specified frte.
fseek(symFile, (header.dshb_frte.dti_first_page + fileRefPage) * header.dshb_page_size + fileRefIndex * sizeof(FileReferenceTableEntry), SEEK_SET);
return fread(frte, sizeof(FileReferenceTableEntry), 1, symFile);
}
static int getContainedStatementTableEntry(FILE* symFile,
const DiskSymbolHeaderBlock& header,
UInt32 statementIndex,
ContainedStatementsTableEntry* statementEntry)
{
UInt32 entriesPerPage = (header.dshb_page_size / sizeof(ContainedStatementsTableEntry));
UInt32 entryPage = (statementIndex / entriesPerPage);
UInt32 entryIndex = (statementIndex % entriesPerPage);
fseek(symFile, (header.dshb_csnte.dti_first_page + entryPage) * header.dshb_page_size + entryIndex * sizeof(ContainedStatementsTableEntry), SEEK_SET);
return fread(statementEntry, sizeof(ContainedStatementsTableEntry), 1, symFile);
}
inline UInt32 delta(UInt32 x, UInt32 y)
{
if (x > y)
return (x - y);
else
return (y - x);
}
inline bool isMeatyModule(const ModulesTableEntry& moduleEntry)
{
return (moduleEntry.mte_kind == MODULE_KIND_PROCEDURE) || (moduleEntry.mte_kind == MODULE_KIND_FUNCTION);
}
static const UInt8* getName(const DiskSymbolHeaderBlock& header, const UInt8* nameTable[], UInt32 nameIndex)
{
UInt32 nameOffset = 2 * nameIndex;
const UInt8* page = nameTable[nameOffset / header.dshb_page_size];
const UInt8* name = page + (nameOffset % header.dshb_page_size);
return name;
}
static int getSource(UInt32 codeOffset, FILE* symFile,
const DiskSymbolHeaderBlock& header,
const ResourceTableEntry& codeEntry,
const UInt8* nameTable[], char fileName[256], UInt32* fileOffset)
{
// since module entries can't span pages, must compute which page module entry size.
UInt32 modulesPerPage = (header.dshb_page_size / sizeof(ModulesTableEntry));
// search for MTE nearest specified offset.
// seek to first MTE.
for (UInt16 i = codeEntry.rte_mte_first; i <= codeEntry.rte_mte_last; i++) {
ModulesTableEntry moduleEntry;
UInt32 modulePage = (i / modulesPerPage);
UInt32 moduleIndex = (i % modulesPerPage);
fseek(symFile, (header.dshb_mte.dti_first_page + modulePage) * header.dshb_page_size + moduleIndex * sizeof(ModulesTableEntry), SEEK_SET);
if (fread(&moduleEntry, sizeof(moduleEntry), 1, symFile) == 1) {
const UInt8* moduleName = getName(header, nameTable, moduleEntry.mte_nte_index);
// printf("module name = %#s\n", moduleName);
if (isMeatyModule(moduleEntry) && (codeOffset >= moduleEntry.mte_res_offset) && (codeOffset - moduleEntry.mte_res_offset) < moduleEntry.mte_size) {
FileReferenceTableEntry frte;
if (getFileReferenceTableEntry(symFile, header, moduleEntry.mte_imp_fref, &frte) == 1) {
// get the name of the file.
const UInt8* name = getName(header, nameTable, frte.frte_fn.nte_index);
UInt32 length = name[0];
BlockMoveData(name + 1, fileName, length);
fileName[length] = '\0';
// printf("file name = %s\n", fileName);
// try to refine the location, using the contained statements table entries.
UInt32 closestFileOffset = moduleEntry.mte_imp_fref.fref_offset;
UInt32 closestCodeOffset = moduleEntry.mte_res_offset;
UInt32 closestCodeDelta = 0xFFFFFFFF;
UInt32 currentFileOffset, currentCodeOffset = moduleEntry.mte_res_offset, currentCodeDelta;
for (UInt32 j = moduleEntry.mte_csnte_idx_1; j <= moduleEntry.mte_csnte_idx_2; j++) {
ContainedStatementsTableEntry statementEntry;
if (getContainedStatementTableEntry(symFile, header, j, &statementEntry) == 1) {
switch (statementEntry.csnte_file.change) {
case kSourceFileChange:
currentFileOffset = statementEntry.csnte_file.fref.fref_offset;
break;
case kEndOfList:
break;
default:
currentFileOffset += statementEntry.csnte.file_delta;
currentCodeOffset = moduleEntry.mte_res_offset + statementEntry.csnte.mte_offset;
currentCodeDelta = delta(currentCodeOffset, codeOffset);
if (currentCodeDelta < closestCodeDelta) {
closestFileOffset = currentFileOffset;
closestCodeOffset = currentCodeOffset;
closestCodeDelta = currentCodeDelta;
}
break;
}
}
}
*fileOffset = closestFileOffset;
// printf("closest file offset = %d\n", closestFileOffset);
// printf("closest code offset = %d\n", closestCodeOffset);
return 1;
}
}
}
}
return 0;
}
/**
* Returns the complete name table from the symbol file.
*/
static UInt8** getNameTable(FILE* symFile, const DiskSymbolHeaderBlock& header)
{
UInt8** nameTable = new UInt8*[header.dshb_nte.dti_page_count];
long count = 0;
if (nameTable != NULL) {
// seek to first page of the name table.
fseek(symFile, header.dshb_nte.dti_first_page * header.dshb_page_size, SEEK_SET);
// read all of the pages into memory, for speed.
for (int i = 0; i < header.dshb_nte.dti_page_count; i++) {
// allocate each page atomically, so GC won't have to scan them.
UInt8* page = nameTable[i] = (UInt8*) GC_malloc_atomic(header.dshb_page_size);
if (page != NULL)
fread(page, header.dshb_page_size, 1, symFile);
}
}
return nameTable;
}
struct sym_file {
FILE* mFile;
DiskSymbolHeaderBlock mHeader;
ResourceTableEntry mCodeEntry;
UInt8** mNameTable;
sym_file() : mFile(NULL), mNameTable(NULL) {}
~sym_file();
};
sym_file::~sym_file()
{
// this seems to die when we are being debugged.
if (mFile != NULL) {
::fclose(mFile);
mFile = NULL;
}
if (mNameTable != NULL) {
UInt8** nameTable = mNameTable;
UInt16 pageCount = mHeader.dshb_nte.dti_page_count;
while (pageCount-- > 0) {
GC_free(*nameTable++);
}
delete[] mNameTable;
mNameTable = NULL;
}
}
sym_file* open_sym_file(const FSSpec* symSpec)
{
sym_file* symbols = new sym_file;
if (symbols != NULL) {
symbols->mFile = FSp_fopen(symSpec, "rb");
if (symbols->mFile == NULL)
goto err_exit;
// read the header. should make sure it is a valid .xSYM file, etc.
DiskSymbolHeaderBlock& header = symbols->mHeader;
if (fread(&header, sizeof(header), 1, symbols->mFile) != 1)
goto err_exit;
// read the RTE tables.
fseek(symbols->mFile, header.dshb_rte.dti_first_page * header.dshb_page_size + sizeof(ResourceTableEntry), SEEK_SET);
for (int i = 1; i <= header.dshb_rte.dti_object_count; i++) {
ResourceTableEntry resEntry;
if (fread(&resEntry, sizeof(resEntry), 1, symbols->mFile) == 1) {
switch (resEntry.rte_ResType) {
case 'CODE':
symbols->mCodeEntry = resEntry;
break;
case 'DATA':
break;
}
}
}
symbols->mNameTable = getNameTable(symbols->mFile, symbols->mHeader);
}
return symbols;
err_exit:
delete symbols;
return NULL;
}
void close_sym_file(sym_file* symbols)
{
delete symbols;
}
int get_source(sym_file* symbols, UInt32 codeOffset, char fileName[256], UInt32* fileOffset)
{
return getSource(codeOffset, symbols->mFile, symbols->mHeader, symbols->mCodeEntry, symbols->mNameTable, fileName, fileOffset);
}
#if 0
int main()
{
printf ("Opening my own .xSYM file.\n");
FILE* symFile = fopen("SymFiles.xSYM", "rb");
if (symFile != NULL) {
DiskSymbolHeaderBlock header;
if (fread (&header, sizeof(header), 1, symFile) == 1) {
// read the RTE tables.
ResourceTableEntry codeEntry, dataEntry;
fseek(symFile, header.dshb_rte.dti_first_page * header.dshb_page_size + sizeof(ResourceTableEntry), SEEK_SET);
for (int i = 1; i <= header.dshb_rte.dti_object_count; i++) {
ResourceTableEntry resEntry;
if (fread(&resEntry, sizeof(resEntry), 1, symFile) == 1) {
switch (resEntry.rte_ResType) {
case 'CODE':
codeEntry = resEntry;
break;
case 'DATA':
dataEntry = resEntry;
break;
}
}
}
printf("data entry size = %d\n", dataEntry.rte_res_size);
printf("code entry size = %d\n", codeEntry.rte_res_size);
printf("actual code size = %d\n", __code_end__ - __code_start__);
// load the name table.
UInt8** nameTable = getNameTable(symFile, header);
// get source location of a routine.
char fileName[256];
UInt32 fileOffset;
TV* tv = (TV*)&getSource;
getSource(UInt32(tv->addr - __code_start__) + 536, symFile, header, codeEntry, nameTable, fileName, &fileOffset);
}
fclose(symFile);
}
return 0;
}
#endif

View File

@@ -0,0 +1,260 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (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.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Patrick C. Beard <beard@netscape.com>
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the NPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the NPL or the GPL.
*/
#include <MacTypes.h>
#ifndef __SYM_FILES__
#define __SYM_FILES__
#if PRAGMA_STRUCT_ALIGN
#pragma options align=mac68k
#elif PRAGMA_STRUCT_PACKPUSH
#pragma pack(push, 2)
#elif PRAGMA_STRUCT_PACK
#pragma pack(2)
#endif
/* Note: these structures are for .xSYM file format v3.3. */
struct DiskTableInfo {
UInt16 dti_first_page; /* table's first page */
UInt16 dti_page_count; /* # pages in the table */
UInt32 dti_object_count; /* # objects in the table */
};
typedef struct DiskTableInfo DiskTableInfo;
struct DiskSymbolHeaderBlock {
Str31 dshb_id; /* Version information */
UInt16 dshb_page_size; /* Size of the pages/blocks */
UInt16 dshb_hash_page; /* Disk page for the hash table */
UInt16 dshb_root_mte; /* MTE index of the program root */
UInt32 dshb_mod_date; /* executable's mod date */
DiskTableInfo dshb_frte; /* Per TABLE information */
DiskTableInfo dshb_rte;
DiskTableInfo dshb_mte;
DiskTableInfo dshb_cmte;
DiskTableInfo dshb_cvte;
DiskTableInfo dshb_csnte;
DiskTableInfo dshb_clte;
DiskTableInfo dshb_ctte;
DiskTableInfo dshb_tte;
DiskTableInfo dshb_nte;
DiskTableInfo dshb_tinfo;
DiskTableInfo dshb_fite;
DiskTableInfo dshb_const;
OSType dshb_file_creator; /* executable's creator */
OSType dshb_file_type; /* executable's file type */
};
typedef struct DiskSymbolHeaderBlock DiskSymbolHeaderBlock;
/*
RESOURCE_TABLE_ENTRY = RECORD
rte_ResType: ResType; { resource type }
rte_res_number: INTEGER; { resource id }
rte_nte_index: LONGINT; { the resource's name }
rte_mte_first: INTEGER; { first MTE contained in the resource }
rte_mte_last: INTEGER; { last MTE contained in the resource }
rte_res_size: LONGINT; { the size of the resource }
END;
*/
struct ResourceTableEntry {
ResType rte_ResType; /* resource type */
SInt16 rte_res_number; /* resource id */
UInt32 rte_nte_index; /* resource name */
UInt16 rte_mte_first; /* first MTE contained in the resource */
UInt16 rte_mte_last; /* last MTE contained in the resource */
UInt32 rte_res_size; /* the size of the resource */
};
typedef struct ResourceTableEntry ResourceTableEntry;
/*
FILE_REFERENCE = RECORD
fref_frte_index: LONGINT; { File Reference Table index }
fref_offset: LONGINT; { absolute offset into the source file }
END;
*/
struct FileReference {
UInt16 fref_frte_index; /* File Reference Table index */
UInt32 fref_offset; /* absolute offset into the source file */
};
typedef struct FileReference FileReference;
/*
MODULES_TABLE_ENTRY = RECORD
mte_rte_index: UNSIGNED; { which resource the MTE is in }
mte_res_offset: LONGINT; { offset into the resource }
mte_size: LONGINT; { size of the MTE }
mte_kind: SignedByte; { kind of MTE }
mte_scope: SignedByte; { MTE's visibility }
mte_parent: INTEGER; { index of parent MTE }
mte_imp_fref: FILE_REFERENCE; { implementation source location }
mte_imp_end: LONGINT; { end of implementation }
mte_nte_index: LONGINT; { MTE's name }
mte_cmte_index: INTEGER; { MTEs contained by this MTE }
mte_cvte_index: LONGINT; { variables contained by this MTE}
mte_clte_index: INTEGER; { labels contained by this MTE }
mte_ctte_index: INTEGER; { types contained by this MTE }
mte_csnte_idx_1: LONGINT; { CSNTE index of first statement }
mte_csnte_idx_2: LONGINT; { CSNTE index of last statement }
END;
*/
struct ModulesTableEntry {
UInt16 mte_rte_index; /* which resource the MTE is in */
UInt32 mte_res_offset; /* offset into the resource */
UInt32 mte_size; /* size of the MTE */
SInt8 mte_kind; /* kind of MTE */
SInt8 mte_scope; /* MTE's visibility */
UInt16 mte_parent; /* index of parent MTE */
FileReference mte_imp_fref; /* implementation source location */
UInt32 mte_imp_end; /* end of implementation */
UInt32 mte_nte_index; /* MTE's name */
UInt16 mte_cmte_index; /* MTEs contained by this MTE */
UInt32 mte_cvte_index; /* variables contained by this MTE */
UInt16 mte_clte_index; /* labels contained by this MTE */
UInt16 mte_ctte_index; /* types contained by this MTE */
UInt32 mte_csnte_idx_1; /* CSNTE index of first statement */
UInt32 mte_csnte_idx_2; /* CSNTE index of last statement */
};
typedef struct ModulesTableEntry ModulesTableEntry;
/* MODULE_KIND_xxx
** The type of module. Taken from the OMF document
*/
#define MODULE_KIND_NONE 0
#define MODULE_KIND_PROGRAM 1
#define MODULE_KIND_UNIT 2
#define MODULE_KIND_PROCEDURE 3
#define MODULE_KIND_FUNCTION 4
#define MODULE_KIND_DATA 5
#define MODULE_KIND_BLOCK 6 /* The module is an internal block */
/*
FILE_REFERENCE_TABLE_ENTRY = RECORD
CASE INTEGER OF
FILE_NAME_INDEX:
(
frte_name_entry: INTEGER; { = FILE_NAME_INDEX }
frte_nte_index: LONGINT; { name of the source file }
frte_mod_date: LONGINT; { the source file's mod date }
);
0: {¥ FILE_NAME_INDEX and ¥ END_OF_LIST, a FRTE entry: }
(
frte_mte_index: INTEGER; { the MTE's index }
frte_file_offset: LONGINT; { the MTE's source file offset}
);
END_OF_LIST:
(
frte_end_of_list: INTEGER; { = END_OF_LIST }
);
END;
*/
enum {
kEndOfList = 0xFFFF,
kFileNameIndex = kEndOfList - 1
};
union FileReferenceTableEntry {
struct {
UInt16 name_entry; /* = kFileNameIndex */
UInt32 nte_index; /* Name table entry */
UInt32 mod_date; /* When file was last modified */
} frte_fn;
struct {
UInt16 mte_index; /* Module table entry < kFileNameIndex */
UInt32 file_offset; /* Absolute offset into the source file */
} frte_mte;
UInt16 frte_end_of_list; /* = kEndOfList */
};
typedef union FileReferenceTableEntry FileReferenceTableEntry;
/*
CONTAINED_STATEMENTS_TABLE_ENTRY = RECORD
CASE INTEGER OF
SOURCE_FILE_CHANGE:
(
csnte_file_change: INTEGER; { = SOURCE_FILE_CHANGE }
csnte_fref: FILE_REFERENCE; { the new source file }
);
0: {¥ to SOURCE_FILE_CHANGE or END_OF_LIST, a statement entry:}
(
csnte_mte_index: INTEGER; { the MTE the statement is in }
csnte_file_delta: INTEGER; { delta from previous src loc }
csnte_mte_offset: LONGINT; { code location, offset into MTE }
);
END_OF_LIST:
(
csnte_end_of_list: INTEGER; { indicates end of stmt list }
);
END;
*/
enum {
kSourceFileChange = kEndOfList - 1
};
union ContainedStatementsTableEntry {
struct {
UInt16 change; /* = kSourceFileChange */
FileReference fref; /* the new source file */
} csnte_file;
struct {
UInt16 mte_index; /* the MTE the statement is in */
UInt16 file_delta; /* delta from previous src loc */
UInt32 mte_offset; /* code location, offset into MTE */
} csnte;
UInt16 csnte_end_of_list; /* = END_OF_LIST */
};
typedef union ContainedStatementsTableEntry ContainedStatementsTableEntry;
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#elif PRAGMA_STRUCT_PACKPUSH
#pragma pack(pop)
#elif PRAGMA_STRUCT_PACK
#pragma pack()
#endif
#endif /* __SYM_FILES__ */

View File

@@ -0,0 +1,56 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (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.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Patrick C. Beard <beard@netscape.com>
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the NPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the NPL or the GPL.
*/
#pragma once
#ifndef __FILES__
#include <Files.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct sym_file sym_file;
sym_file* open_sym_file(const FSSpec* symSpec);
void close_sym_file(sym_file* symbols);
int get_source(sym_file* symbols, UInt32 codeOffset, char fileName[256], UInt32* fileOffset);
#ifdef __cplusplus
} /* extern "C" */
#endif