Collection FileInfoByName; /* File infos sorted by name */
Collection FileInfoById; /* File infos sorted by id */
Collection LineInfoByAddr; /* Line information sorted by address */
+ Collection SymInfoByName; /* Symbol information sorted by name */
};
/* Input tokens */
} Seg;
};
+/* Internally used symbol info struct */
+typedef struct SymInfo SymInfo;
+struct SymInfo {
+ cc65_symbol_type Type; /* Type of symbol */
+ long Value; /* Value of symbol */
+ char SymName[1]; /* Name of symbol */
+};
+
/*****************************************************************************/
+/*****************************************************************************/
+/* Symbol info */
+/*****************************************************************************/
+
+
+
+static SymInfo* NewSymInfo (const StrBuf* Name, long Val, cc65_symbol_type Type)
+/* Create a new SymInfo struct, intialize and return it */
+{
+ /* Allocate memory */
+ SymInfo* S = xmalloc (sizeof (SymInfo) + SB_GetLen (Name));
+
+ /* Initialize it */
+ S->Value = Val;
+ S->Type = Type;
+ memcpy (S->SymName, SB_GetConstBuf (Name), SB_GetLen (Name) + 1);
+
+ /* Return it */
+ return S;
+}
+
+
+
+static void FreeSymInfo (SymInfo* S)
+/* Free a SymInfo struct */
+{
+ xfree (S);
+}
+
+
+
+static int CompareSymInfoByName (const void* L, const void* R)
+/* Helper function to sort symbol infos in a collection by name */
+{
+ /* Sort by file name */
+ return strcmp (((const SymInfo*) L)->SymName,
+ ((const SymInfo*) R)->SymName);
+}
+
+
+
/*****************************************************************************/
/* Debug info */
/*****************************************************************************/
InitCollection (&Info->FileInfoByName);
InitCollection (&Info->FileInfoById);
InitCollection (&Info->LineInfoByAddr);
+ InitCollection (&Info->SymInfoByName);
/* Return it */
return Info;
/* Free line info */
DoneCollection (&Info->LineInfoByAddr);
+ /* Free symbol info */
+ for (I = 0; I < CollCount (&Info->SymInfoByName); ++I) {
+ FreeSymInfo (CollAt (&Info->SymInfoByName, I));
+ }
+ DoneCollection (&Info->SymInfoByName);
+
/* Free the structure itself */
xfree (Info);
}
cc65_symbol_type Type;
long Value;
StrBuf SymName = STRBUF_INITIALIZER;
+ SymInfo* S;
enum {
ibNone = 0x00,
ibSymName = 0x01,
}
/* Create the symbol info and remember it */
-#if 0
- S = NewSegInfo (&SegName, Id, Start, Size, &OutputName, OutputOffs);
- CollAppend (&D->Info->SegInfoByName, S);
-#endif
+ S = NewSymInfo (&SymName, Value, Type);
+ CollAppend (&D->Info->SymInfoByName, S);
ErrorExit:
/* Entry point in case of errors */
+static void ProcessSymInfo (InputData* D)
+/* Postprocess symbol infos */
+{
+ /* Get pointers to the symbol info collections */
+ Collection* SymInfoByName = &D->Info->SymInfoByName;
+
+ /* Sort the symbol infos by name */
+ CollSort (SymInfoByName, CompareSymInfoByName);
+}
+
+
+
+static int FindSymInfoByName (Collection* SymInfos, const char* SymName, int* Index)
+/* Find the SymInfo for a given file name. The function returns true if the
+ * name was found. In this case, Index contains the index of the first item
+ * that matches. If the item wasn't found, the function returns false and
+ * Index contains the insert position for SymName.
+ */
+{
+ /* Do a binary search */
+ int Lo = 0;
+ int Hi = (int) CollCount (SymInfos) - 1;
+ int Found = 0;
+ while (Lo <= Hi) {
+
+ /* Mid of range */
+ int Cur = (Lo + Hi) / 2;
+
+ /* Get item */
+ SymInfo* CurItem = CollAt (SymInfos, Cur);
+
+ /* Compare */
+ int Res = strcmp (CurItem->SymName, SymName);
+
+ /* Found? */
+ if (Res < 0) {
+ Lo = Cur + 1;
+ } else {
+ Hi = Cur - 1;
+ /* Since we may have duplicates, repeat the search until we've
+ * the first item that has a match.
+ */
+ if (Res == 0) {
+ Found = 1;
+ }
+ }
+ }
+
+ /* Pass back the index. This is also the insert position */
+ *Index = Lo;
+ return Found;
+}
+
+
+
/*****************************************************************************/
/* Code */
/*****************************************************************************/
ProcessSegInfo (&D);
ProcessFileInfo (&D);
ProcessLineInfo (&D);
+ ProcessSymInfo (&D);
/* Return the debug info struct that was created */
return D.Info;
for (I = 0; I < CollCount (FileInfoByName); ++I) {
/* Get this item */
- FileInfo* F = CollAt (FileInfoByName, I);
+ const FileInfo* F = CollAt (FileInfoByName, I);
/* Copy the data */
D->data[I].source_name = F->FileName;
/* The handle is actually a pointer to a debug info struct */
Info = (DbgInfo*) Handle;
- /* Get a pointer to the file list */
+ /* Get a pointer to the segment list */
SegInfoByName = &Info->SegInfoByName;
/* Allocate memory for the data structure returned to the caller */
for (I = 0; I < CollCount (SegInfoByName); ++I) {
/* Get this item */
- SegInfo* S = CollAt (SegInfoByName, I);
+ const SegInfo* S = CollAt (SegInfoByName, I);
/* Copy the data */
D->data[I].segment_name = S->SegName;
+cc65_symbolinfo* cc65_symbol_byname (cc65_dbginfo Handle, const char* Name)
+/* Return a list of symbols with a given name. The function returns NULL if
+ * no symbol with this name was found.
+ */
+{
+ DbgInfo* Info;
+ Collection* SymInfoByName;
+ cc65_symbolinfo* D;
+ unsigned I;
+ int Index;
+ unsigned Count;
+
+ /* Check the parameter */
+ assert (Handle != 0);
+
+ /* The handle is actually a pointer to a debug info struct */
+ Info = (DbgInfo*) Handle;
+
+ /* Get a pointer to the symbol list */
+ SymInfoByName = &Info->SymInfoByName;
+
+ /* Search for the symbol */
+ if (!FindSymInfoByName (SymInfoByName, Name, &Index)) {
+ /* Not found */
+ return 0;
+ }
+
+ /* Index contains the position. Count how many symbols with this name
+ * we have. Skip the first one, since we have at least one.
+ */
+ Count = 1;
+ while ((unsigned) Index + Count < CollCount (SymInfoByName)) {
+ const SymInfo* S = CollAt (SymInfoByName, (unsigned) Index + Count);
+ if (strcmp (S->SymName, Name) != 0) {
+ break;
+ }
+ ++Count;
+ }
+
+ /* Allocate memory for the data structure returned to the caller */
+ D = xmalloc (sizeof (*D) + (Count - 1) * sizeof (D->data[0]));
+
+ /* Fill in the data */
+ D->count = Count;
+ while (Count--) {
+
+ /* Get this item */
+ const SymInfo* S = CollAt (SymInfoByName, Index);
+
+ /* Copy the data */
+ D->data[I].symbol_name = S->SymName;
+ D->data[I].symbol_type = S->Type;
+ D->data[I].symbol_value = S->Value;
+ }
+
+ /* Return the result */
+ return D;
+}
+
+
+
+void cc65_free_symbolinfo (cc65_dbginfo Handle, cc65_symbolinfo* Info)
+/* Free a symbol info record */
+{
+ /* Just for completeness, check the handle */
+ assert (Handle != 0);
+
+ /* Free the memory */
+ xfree (Info);
+}
+
+
+
cc65_dbginfo Info;
cc65_sourceinfo* Sources;
cc65_segmentinfo* Segments;
- cc65_lineinfo* L;
+ cc65_lineinfo* Lines;
+ cc65_symbolinfo* Symbols;
unsigned I;
unsigned long Addr;
/* Check one line */
printf ("Requesting line info for crt0.s(59):\n");
- L = cc65_lineinfo_byname (Info, "crt0.s", 59);
- if (L == 0) {
+ Lines = cc65_lineinfo_byname (Info, "crt0.s", 59);
+ if (Lines == 0) {
printf (" Not found\n");
} else {
printf (" Code range is $%04X-$%04X\n",
- L->data[0].line_start,
- L->data[0].line_end);
- cc65_free_lineinfo (Info, L);
+ Lines->data[0].line_start,
+ Lines->data[0].line_end);
+ cc65_free_lineinfo (Info, Lines);
}
/* Output debug information for all addresses in the complete 6502 address
*/
printf ("Line info:\n");
for (Addr = 0; Addr < 0x10000; ++Addr) {
- L = cc65_lineinfo_byaddr (Info, Addr);
- if (L) {
+ Lines = cc65_lineinfo_byaddr (Info, Addr);
+ if (Lines) {
unsigned I;
printf (" $%04lX: ", Addr);
- for (I = 0; I < L->count; ++I) {
+ for (I = 0; I < Lines->count; ++I) {
if (I > 0) {
printf (", ");
}
- printf ("%s(%lu)",
- L->data[I].source_name,
- (unsigned long) L->data[I].source_line);
- if (L->data[I].output_name) {
+ printf ("%s(%lu)",
+ Lines->data[I].source_name,
+ (unsigned long) Lines->data[I].source_line);
+ if (Lines->data[I].output_name) {
printf (" %s($%06lX)",
- L->data[I].output_name,
- L->data[I].output_offs);
+ Lines->data[I].output_name,
+ Lines->data[I].output_offs);
}
}
printf ("\n");
- cc65_free_lineinfo (Info, L);
+ cc65_free_lineinfo (Info, Lines);
}
}
+ /* Check for address of main */
+ printf ("Requesting address of _main:\n");
+ Symbols = cc65_symbol_byname (Info, "_main");
+ if (Symbols == 0) {
+ printf (" Not found\n");
+ } else {
+ unsigned I;
+ for (I = 0; I < Symbols->count; ++I) {
+ printf (" %-20s = %04lX\n",
+ Symbols->data[I].symbol_name,
+ Symbols->data[I].symbol_value);
+ }
+ cc65_free_symbolinfo (Info, Symbols);
+ }
+
+
/* Free the debug info */
cc65_free_dbginfo (Info);