Added dbg file generation

git-svn-id: svn://svn.cc65.org/cc65/trunk@764 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz
2001-05-29 07:39:46 +00:00
parent 45242a8e02
commit 3889a2bec9
20 changed files with 344 additions and 132 deletions

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1999-2000 Ullrich von Bassewitz */ /* (C) 1999-2001 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Wacholderweg 14 */
/* D-70597 Stuttgart */ /* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -45,6 +45,7 @@
#include "global.h" #include "global.h"
#include "error.h" #include "error.h"
#include "fileio.h" #include "fileio.h"
#include "lineinfo.h"
#include "segments.h" #include "segments.h"
#include "exports.h" #include "exports.h"
#include "config.h" #include "config.h"
@@ -186,6 +187,7 @@ static void BinWriteMem (BinDesc* D, Memory* M)
* if the memory area is the load area. * if the memory area is the load area.
*/ */
if (DoWrite) { if (DoWrite) {
RelocLineInfo (S->Seg);
SegWrite (D->F, S->Seg, BinWriteExpr, D); SegWrite (D->F, S->Seg, BinWriteExpr, D);
} else if (M->Flags & MF_FILL) { } else if (M->Flags & MF_FILL) {
WriteMult (D->F, M->FillVal, S->Seg->Size); WriteMult (D->F, M->FillVal, S->Seg->Size);

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1999 Ullrich von Bassewitz */ /* (C) 1999-2001 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Wacholderweg 14 */
/* D-70597 Stuttgart */ /* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */

View File

@@ -2,7 +2,7 @@
/* */ /* */
/* dbgsyms.c */ /* dbgsyms.c */
/* */ /* */
/* Debug symbol handing for the ld65 linker */ /* Debug symbol handling for the ld65 linker */
/* */ /* */
/* */ /* */
/* */ /* */

View File

@@ -2,7 +2,7 @@
/* */ /* */
/* dbgsyms.h */ /* dbgsyms.h */
/* */ /* */
/* Debug symbol handing for the ld65 linker */ /* Debug symbol handling for the ld65 linker */
/* */ /* */
/* */ /* */
/* */ /* */

View File

@@ -43,6 +43,17 @@
/*****************************************************************************/
/* Forwards */
/*****************************************************************************/
struct LineInfo;
struct Section;
/*****************************************************************************/ /*****************************************************************************/
/* Data */ /* Data */
/*****************************************************************************/ /*****************************************************************************/

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998 Ullrich von Bassewitz */ /* (C) 1998-2001 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Wacholderweg 14 */
/* D-70597 Stuttgart */ /* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -50,6 +50,7 @@ unsigned long StartAddr = 0x200; /* Start address */
unsigned char VerboseMap = 0; /* Verbose map file */ unsigned char VerboseMap = 0; /* Verbose map file */
const char* MapFileName = 0; /* Name of the map file */ const char* MapFileName = 0; /* Name of the map file */
const char* LabelFileName = 0; /* Name of the label file */ const char* LabelFileName = 0; /* Name of the label file */
const char* DbgFileName = 0; /* Name of the debug file */
unsigned char WProtSegs = 0; /* Mark write protected segments */ unsigned char WProtSegs = 0; /* Mark write protected segments */

View File

@@ -1,15 +1,15 @@
/*****************************************************************************/ /*****************************************************************************/
/* */ /* */
/* global.h */ /* global.h */
/* */ /* */
/* Global variables for the ld65 linker */ /* Global variables for the ld65 linker */
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998 Ullrich von Bassewitz */ /* (C) 1998-2001 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Wacholderweg 14 */
/* D-70597 Stuttgart */ /* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -51,6 +51,7 @@ extern unsigned long StartAddr; /* Start address */
extern unsigned char VerboseMap; /* Verbose map file */ extern unsigned char VerboseMap; /* Verbose map file */
extern const char* MapFileName; /* Name of the map file */ extern const char* MapFileName; /* Name of the map file */
extern const char* LabelFileName; /* Name of the label file */ extern const char* LabelFileName; /* Name of the label file */
extern const char* DbgFileName; /* Name of the debug file */
extern unsigned char WProtSegs; /* Mark write protected segments */ extern unsigned char WProtSegs; /* Mark write protected segments */

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2000 Ullrich von Bassewitz */ /* (C) 1998-2001 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Wacholderweg 14 */
/* D-70597 Stuttgart */ /* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -78,29 +78,31 @@ static ObjData** Index = 0;
static void LibReadObjHeader (ObjData* O) static void LibReadObjHeader (ObjData* O)
/* Read the header of the object file checking the signature */ /* Read the header of the object file checking the signature */
{ {
O->Header.Magic = Read32 (Lib); O->Header.Magic = Read32 (Lib);
if (O->Header.Magic != OBJ_MAGIC) { if (O->Header.Magic != OBJ_MAGIC) {
Error ("Object file `%s' in library `%s' is invalid", Error ("Object file `%s' in library `%s' is invalid",
GetObjFileName (O), LibName); GetObjFileName (O), LibName);
} }
O->Header.Version = Read16 (Lib); O->Header.Version = Read16 (Lib);
if (O->Header.Version != OBJ_VERSION) { if (O->Header.Version != OBJ_VERSION) {
Error ("Object file `%s' in library `%s' has wrong version", Error ("Object file `%s' in library `%s' has wrong version",
GetObjFileName (O), LibName); GetObjFileName (O), LibName);
} }
O->Header.Flags = Read16 (Lib); O->Header.Flags = Read16 (Lib);
O->Header.OptionOffs = Read32 (Lib); O->Header.OptionOffs = Read32 (Lib);
O->Header.OptionSize = Read32 (Lib); O->Header.OptionSize = Read32 (Lib);
O->Header.FileOffs = Read32 (Lib); O->Header.FileOffs = Read32 (Lib);
O->Header.FileSize = Read32 (Lib); O->Header.FileSize = Read32 (Lib);
O->Header.SegOffs = Read32 (Lib); O->Header.SegOffs = Read32 (Lib);
O->Header.SegSize = Read32 (Lib); O->Header.SegSize = Read32 (Lib);
O->Header.ImportOffs = Read32 (Lib); O->Header.ImportOffs = Read32 (Lib);
O->Header.ImportSize = Read32 (Lib); O->Header.ImportSize = Read32 (Lib);
O->Header.ExportOffs = Read32 (Lib); O->Header.ExportOffs = Read32 (Lib);
O->Header.ExportSize = Read32 (Lib); O->Header.ExportSize = Read32 (Lib);
O->Header.DbgSymOffs = Read32 (Lib); O->Header.DbgSymOffs = Read32 (Lib);
O->Header.DbgSymSize = Read32 (Lib); O->Header.DbgSymSize = Read32 (Lib);
O->Header.LineInfoOffs = Read32 (Lib);
O->Header.LineInfoSize = Read32 (Lib);
} }
@@ -187,7 +189,7 @@ static void LibCheckExports (ObjData* O)
for (I = 0; I < O->ExportCount; ++I) { for (I = 0; I < O->ExportCount; ++I) {
InsertExport (O->Exports [I]); InsertExport (O->Exports [I]);
} }
/* Insert the imports */ /* Insert the imports */
for (I = 0; I < O->ImportCount; ++I) { for (I = 0; I < O->ImportCount; ++I) {
InsertImport (O->Imports [I]); InsertImport (O->Imports [I]);
} }
@@ -230,45 +232,52 @@ void LibAdd (FILE* F, const char* Name)
do { do {
Add = 0; Add = 0;
for (I = 0; I < ModuleCount; ++I) { for (I = 0; I < ModuleCount; ++I) {
ObjData* O = Index [I]; ObjData* O = Index [I];
if ((O->Flags & OBJ_REF) == 0) { if ((O->Flags & OBJ_REF) == 0) {
LibCheckExports (O); LibCheckExports (O);
if (O->Flags & OBJ_REF) { if (O->Flags & OBJ_REF) {
/* The routine added the file */ /* The routine added the file */
Add = 1; Add = 1;
} }
} }
} }
} while (Add); } while (Add);
/* Add the files list and sections for all requested modules */ /* Add the files list and sections for all requested modules */
for (I = 0; I < ModuleCount; ++I) { for (I = 0; I < ModuleCount; ++I) {
ObjData* O = Index [I]; ObjData* O = Index [I];
if (O->Flags & OBJ_REF) { if (O->Flags & OBJ_REF) {
/* Seek to the start of the object file and read the header */ /* Seek to the start of the object file and read the header */
fseek (Lib, O->Start, SEEK_SET); fseek (Lib, O->Start, SEEK_SET);
LibReadObjHeader (O); LibReadObjHeader (O);
/* Seek to the start of the files list and read the files list */ /* Seek to the start of the files list and read the files list */
fseek (Lib, O->Start + O->Header.FileOffs, SEEK_SET); fseek (Lib, O->Start + O->Header.FileOffs, SEEK_SET);
ObjReadFiles (Lib, O); ObjReadFiles (Lib, O);
/* Seek to the start of the segment list and read the segments */ /* Seek to the start of the debug info and read the debug info */
fseek (Lib, O->Start + O->Header.SegOffs, SEEK_SET); fseek (Lib, O->Start + O->Header.DbgSymOffs, SEEK_SET);
ObjReadSections (Lib, O); ObjReadDbgSyms (Lib, O);
/* Seek to the start of the debug info and read the debug info */ /* Seek to the start of the line infos and read them */
fseek (Lib, O->Start + O->Header.DbgSymOffs, SEEK_SET); fseek (Lib, O->Start + O->Header.LineInfoOffs, SEEK_SET);
ObjReadDbgSyms (Lib, O); ObjReadLineInfos (Lib, O);
/* Seek to the start of the segment list and read the segments.
* This must be last, since the data here may reference other
* stuff.
*/
fseek (Lib, O->Start + O->Header.SegOffs, SEEK_SET);
ObjReadSections (Lib, O);
/* We have the data now */ /* We have the data now */
O->Flags |= OBJ_HAVEDATA; O->Flags |= OBJ_HAVEDATA;
} }
/* Add a pointer to the library name */ /* Add a pointer to the library name */
O->LibName = LibName; O->LibName = LibName;
} }
/* Done. Close the file, release allocated memory */ /* Done. Close the file, release allocated memory */

View File

@@ -39,6 +39,8 @@
/* ld65 */ /* ld65 */
#include "fileio.h" #include "fileio.h"
#include "fragment.h"
#include "segments.h"
#include "lineinfo.h" #include "lineinfo.h"
@@ -49,6 +51,22 @@
static CodeRange* NewCodeRange (unsigned long Offs, unsigned long Size)
/* Create and return a new CodeRange struct */
{
/* Allocate memory */
CodeRange* R = xmalloc (sizeof (CodeRange));
/* Initialize the fields */
R->Offs = Offs;
R->Size = Size;
/* Return the new struct */
return R;
}
static LineInfo* NewLineInfo (void) static LineInfo* NewLineInfo (void)
/* Create and return a new LineInfo struct */ /* Create and return a new LineInfo struct */
{ {
@@ -59,6 +77,7 @@ static LineInfo* NewLineInfo (void)
LI->File = 0; LI->File = 0;
InitFilePos (&LI->Pos); InitFilePos (&LI->Pos);
InitCollection (&LI->Fragments); InitCollection (&LI->Fragments);
InitCollection (&LI->CodeRanges);
/* Return the new struct */ /* Return the new struct */
return LI; return LI;
@@ -85,3 +104,88 @@ LineInfo* ReadLineInfo (FILE* F, ObjData* O)
static void AddCodeRange (LineInfo* LI, unsigned long Offs, unsigned long Size)
/* Add a range of code to this line */
{
unsigned I;
/* Get a pointer to the collection */
Collection* CodeRanges = &LI->CodeRanges;
/* We will keep the CodeRanges collection sorted by starting offset,
* so we have to search for the correct insert position. Since in most
* cases, the fragments have increasing order, and there is usually not
* more than one or two ranges, we do a linear search.
*/
for (I = 0; I < CollCount (CodeRanges); ++I) {
CodeRange* R = CollAtUnchecked (CodeRanges, I);
if (Offs < R->Offs) {
/* Got the insert position */
if (Offs + Size == R->Offs) {
/* Merge the two */
R->Offs = Offs;
R->Size += Size;
} else {
/* Insert a new entry */
CollInsert (CodeRanges, NewCodeRange (Offs, Size), I);
}
/* Done */
return;
} else if (R->Offs + R->Size == Offs) {
/* This is the regular case. Merge the two. */
R->Size += Size;
/* Done */
return;
}
}
/* We must append an entry */
CollAppend (CodeRanges, NewCodeRange (Offs, Size));
}
void RelocLineInfo (struct Segment* S)
/* Relocate the line info for a segment. */
{
unsigned long Offs = 0;
/* Loop over all sections in this segment */
Section* Sec = S->SecRoot;
while (Sec) {
Fragment* Frag;
/* Adjust for fill bytes */
Offs += Sec->Fill;
/* Loop over all fragments in this section */
Frag = Sec->FragRoot;
while (Frag) {
/* Add the range for this fragment to the line info if there
* is any
*/
if (Frag->LI) {
AddCodeRange (Frag->LI, Offs, Frag->Size);
}
/* Update the offset */
Offs += Frag->Size;
/* Next fragment */
Frag = Frag->Next;
}
/* Next section */
Sec = Sec->Next;
}
}

View File

@@ -48,16 +48,35 @@
/*****************************************************************************/ /*****************************************************************************/
/* Data */ /* Forwards */
/*****************************************************************************/ /*****************************************************************************/
struct Segment;
/*****************************************************************************/
/* Data */
/*****************************************************************************/
typedef struct CodeRange CodeRange;
struct CodeRange {
unsigned long Offs;
unsigned long Size;
};
typedef struct LineInfo LineInfo; typedef struct LineInfo LineInfo;
struct LineInfo { struct LineInfo {
struct FileInfo* File; /* File struct for this line */ struct FileInfo* File; /* File struct for this line */
FilePos Pos; /* File position */ FilePos Pos; /* File position */
Collection Fragments; /* Fragments for this line */ Collection Fragments; /* Fragments for this line */
Collection CodeRanges; /* Code ranges for this line */
}; };
@@ -71,6 +90,9 @@ struct LineInfo {
LineInfo* ReadLineInfo (FILE* F, ObjData* O); LineInfo* ReadLineInfo (FILE* F, ObjData* O);
/* Read a line info from a file and return it */ /* Read a line info from a file and return it */
void RelocLineInfo (struct Segment* S);
/* Relocate the line info for a segment. */
/* End of lineinfo.h */ /* End of lineinfo.h */

View File

@@ -226,6 +226,14 @@ static void OptConfig (const char* Opt, const char* Arg)
static void OptDbgFile (const char* Opt, const char* Arg)
/* Give the name of the debug file */
{
DbgFileName = Arg;
}
static void OptHelp (const char* Opt, const char* Arg) static void OptHelp (const char* Opt, const char* Arg)
/* Print usage information and exit */ /* Print usage information and exit */
{ {
@@ -288,7 +296,8 @@ int main (int argc, char* argv [])
/* Program long options */ /* Program long options */
static const LongOpt OptTab[] = { static const LongOpt OptTab[] = {
{ "--config", 1, OptConfig }, { "--config", 1, OptConfig },
{ "--help", 0, OptHelp }, { "--dbgfile", 1, OptDbgFile },
{ "--help", 0, OptHelp },
{ "--mapfile", 1, OptMapFile }, { "--mapfile", 1, OptMapFile },
{ "--start-addr", 1, OptStartAddr }, { "--start-addr", 1, OptStartAddr },
{ "--target", 1, OptTarget }, { "--target", 1, OptTarget },
@@ -425,6 +434,9 @@ int main (int argc, char* argv [])
if (LabelFileName) { if (LabelFileName) {
CreateLabelFile (); CreateLabelFile ();
} }
if (DbgFileName) {
CreateDbgFile ();
}
/* Dump the data for debugging */ /* Dump the data for debugging */
if (Verbosity > 1) { if (Verbosity > 1) {

View File

@@ -22,6 +22,7 @@ OBJS = bin.o \
binfmt.o \ binfmt.o \
condes.o \ condes.o \
config.o \ config.o \
dbginfo.o \
dbgsyms.o \ dbgsyms.o \
error.o \ error.o \
exports.o \ exports.o \

View File

@@ -71,6 +71,7 @@ OBJS = bin.obj \
binfmt.obj \ binfmt.obj \
condes.obj \ condes.obj \
config.obj \ config.obj \
dbginfo.obj \
dbgsyms.obj \ dbgsyms.obj \
error.obj \ error.obj \
exports.obj \ exports.obj \
@@ -115,6 +116,7 @@ FILE bin.obj
FILE binfmt.obj FILE binfmt.obj
FILE condes.obj FILE condes.obj
FILE config.obj FILE config.obj
FILE dbginfo.obj
FILE dbgsyms.obj FILE dbgsyms.obj
FILE error.obj FILE error.obj
FILE exports.obj FILE exports.obj

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998 Ullrich von Bassewitz */ /* (C) 1998-2001 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Wacholderweg 14 */
/* D-70597 Stuttgart */ /* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -41,6 +41,7 @@
#include "error.h" #include "error.h"
#include "objdata.h" #include "objdata.h"
#include "segments.h" #include "segments.h"
#include "dbginfo.h"
#include "dbgsyms.h" #include "dbgsyms.h"
#include "exports.h" #include "exports.h"
#include "config.h" #include "config.h"
@@ -82,7 +83,7 @@ void CreateMapFile (void)
for (I = 0; I < O->SectionCount; ++I) { for (I = 0; I < O->SectionCount; ++I) {
const Section* S = O->Sections [I]; const Section* S = O->Sections [I];
/* Don't include zero sized sections if not explicitly /* Don't include zero sized sections if not explicitly
* requested * requested
*/ */
if (VerboseMap || S->Size > 0) { if (VerboseMap || S->Size > 0) {
fprintf (F, " %-15s Offs = %06lX Size = %06lX\n", fprintf (F, " %-15s Offs = %06lX Size = %06lX\n",
@@ -124,7 +125,7 @@ void CreateLabelFile (void)
{ {
ObjData* O; ObjData* O;
/* Open the map file */ /* Open the label file */
FILE* F = fopen (LabelFileName, "w"); FILE* F = fopen (LabelFileName, "w");
if (F == 0) { if (F == 0) {
Error ("Cannot create label file `%s': %s", LabelFileName, strerror (errno)); Error ("Cannot create label file `%s': %s", LabelFileName, strerror (errno));
@@ -168,3 +169,33 @@ void CreateLabelFile (void)
void CreateDbgFile (void)
/* Create a debug info file */
{
ObjData* O;
/* Open the debug info file */
FILE* F = fopen (DbgFileName, "w");
if (F == 0) {
Error ("Cannot create label file `%s': %s", DbgFileName, strerror (errno));
}
/* Print line infos from all modules we have linked into the output file */
O = ObjRoot;
while (O) {
if (O->Flags & OBJ_HAVEDATA) {
/* We've linked this module */
PrintDbgInfo (O, F);
}
O = O->Next;
}
/* Close the file */
if (fclose (F) != 0) {
Error ("Error closing map file `%s': %s", DbgFileName, strerror (errno));
}
}

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998 Ullrich von Bassewitz */ /* (C) 1998-2001 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Wacholderweg 14 */
/* D-70597 Stuttgart */ /* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -54,6 +54,9 @@ void CreateMapFile (void);
void CreateLabelFile (void); void CreateLabelFile (void);
/* Create a label file */ /* Create a label file */
void CreateDbgFile (void);
/* Create a debug info file */
/* End of mapfile.h */ /* End of mapfile.h */

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1999-2000 Ullrich von Bassewitz */ /* (C) 1999-2001 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Wacholderweg 14 */
/* D-70597 Stuttgart */ /* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -50,6 +50,7 @@
#include "expr.h" #include "expr.h"
#include "fileio.h" #include "fileio.h"
#include "global.h" #include "global.h"
#include "lineinfo.h"
#include "o65.h" #include "o65.h"
@@ -72,7 +73,7 @@
#define O65SEG_TEXT 0x02 #define O65SEG_TEXT 0x02
#define O65SEG_DATA 0x03 #define O65SEG_DATA 0x03
#define O65SEG_BSS 0x04 #define O65SEG_BSS 0x04
#define O65SEG_ZP 0x05 #define O65SEG_ZP 0x05
/* Relocation type codes for the o65 format */ /* Relocation type codes for the o65 format */
#define O65RELOC_WORD 0x80 #define O65RELOC_WORD 0x80
@@ -82,8 +83,8 @@
#define O65RELOC_SEG 0xa0 #define O65RELOC_SEG 0xa0
/* O65 executable file header */ /* O65 executable file header */
typedef struct O65Header_ O65Header; typedef struct O65Header O65Header;
struct O65Header_ { struct O65Header {
unsigned Version; /* Version number for o65 format */ unsigned Version; /* Version number for o65 format */
unsigned Mode; /* Mode word */ unsigned Mode; /* Mode word */
unsigned long TextBase; /* Base address of text segment */ unsigned long TextBase; /* Base address of text segment */
@@ -98,8 +99,8 @@ struct O65Header_ {
}; };
/* An o65 option */ /* An o65 option */
typedef struct O65Option_ O65Option; typedef struct O65Option O65Option;
struct O65Option_ { struct O65Option {
O65Option* Next; /* Next in option list */ O65Option* Next; /* Next in option list */
unsigned char Type; /* Type of option */ unsigned char Type; /* Type of option */
unsigned char Len; /* Data length */ unsigned char Len; /* Data length */
@@ -108,54 +109,54 @@ struct O65Option_ {
/* A o65 relocation table */ /* A o65 relocation table */
#define RELOC_BLOCKSIZE 4096 #define RELOC_BLOCKSIZE 4096
typedef struct O65RelocTab_ O65RelocTab; typedef struct O65RelocTab O65RelocTab;
struct O65RelocTab_ { struct O65RelocTab {
unsigned Size; /* Size of the table */ unsigned Size; /* Size of the table */
unsigned Fill; /* Amount used */ unsigned Fill; /* Amount used */
unsigned char* Buf; /* Buffer, dynamically allocated */ unsigned char* Buf; /* Buffer, dynamically allocated */
}; };
/* Structure describing the format */ /* Structure describing the format */
struct O65Desc_ { struct O65Desc {
O65Header Header; /* File header */ O65Header Header; /* File header */
O65Option* Options; /* List of file options */ O65Option* Options; /* List of file options */
ExtSymTab* Exports; /* Table with exported symbols */ ExtSymTab* Exports; /* Table with exported symbols */
ExtSymTab* Imports; /* Table with imported symbols */ ExtSymTab* Imports; /* Table with imported symbols */
unsigned Undef; /* Count of undefined symbols */ unsigned Undef; /* Count of undefined symbols */
FILE* F; /* The file we're writing to */ FILE* F; /* The file we're writing to */
char* Filename; /* Name of the output file */ char* Filename; /* Name of the output file */
O65RelocTab* TextReloc; /* Relocation table for text segment */ O65RelocTab* TextReloc; /* Relocation table for text segment */
O65RelocTab* DataReloc; /* Relocation table for data segment */ O65RelocTab* DataReloc; /* Relocation table for data segment */
unsigned TextCount; /* Number of segments assigned to .text */ unsigned TextCount; /* Number of segments assigned to .text */
SegDesc** TextSeg; /* Array of text segments */ SegDesc** TextSeg; /* Array of text segments */
unsigned DataCount; /* Number of segments assigned to .data */ unsigned DataCount; /* Number of segments assigned to .data */
SegDesc** DataSeg; /* Array of data segments */ SegDesc** DataSeg; /* Array of data segments */
unsigned BssCount; /* Number of segments assigned to .bss */ unsigned BssCount; /* Number of segments assigned to .bss */
SegDesc** BssSeg; /* Array of bss segments */ SegDesc** BssSeg; /* Array of bss segments */
unsigned ZPCount; /* Number of segments assigned to .zp */ unsigned ZPCount; /* Number of segments assigned to .zp */
SegDesc** ZPSeg; /* Array of zp segments */ SegDesc** ZPSeg; /* Array of zp segments */
/* Temporary data for writing segments */ /* Temporary data for writing segments */
unsigned long SegSize; unsigned long SegSize;
O65RelocTab* CurReloc; O65RelocTab* CurReloc;
long LastOffs; long LastOffs;
}; };
/* Structure for parsing expression trees */ /* Structure for parsing expression trees */
typedef struct ExprDesc_ ExprDesc; typedef struct ExprDesc ExprDesc;
struct ExprDesc_ { struct ExprDesc {
O65Desc* D; /* File format descriptor */ O65Desc* D; /* File format descriptor */
long Val; /* The offset value */ long Val; /* The offset value */
int TooComplex; /* Expression too complex */ int TooComplex; /* Expression too complex */
Section* SegRef; /* Section referenced if any */ Section* SegRef; /* Section referenced if any */
ExtSym* ExtRef; /* External reference if any */ ExtSym* ExtRef; /* External reference if any */
}; };
/*****************************************************************************/ /*****************************************************************************/
/* Helper functions */ /* Helper functions */
/*****************************************************************************/ /*****************************************************************************/
@@ -343,7 +344,7 @@ static void O65WriteReloc (O65RelocTab* R, FILE* F)
/*****************************************************************************/ /*****************************************************************************/
/* Option handling */ /* Option handling */
/*****************************************************************************/ /*****************************************************************************/
@@ -380,7 +381,7 @@ static void FreeO65Option (O65Option* O)
/*****************************************************************************/ /*****************************************************************************/
/* Subroutines to write o65 sections */ /* Subroutines to write o65 sections */
/*****************************************************************************/ /*****************************************************************************/
@@ -427,7 +428,7 @@ static void O65WriteHeader (O65Desc* D)
static unsigned O65WriteExpr (ExprNode* E, int Signed, unsigned Size, static unsigned O65WriteExpr (ExprNode* E, int Signed, unsigned Size,
unsigned long Offs, void* Data) unsigned long Offs, void* Data)
/* Called from SegWrite for an expression. Evaluate the expression, check the /* Called from SegWrite for an expression. Evaluate the expression, check the
* range and write the expression value to the file, update the relocation * range and write the expression value to the file, update the relocation
* table. * table.
@@ -522,7 +523,7 @@ static unsigned O65WriteExpr (ExprNode* E, int Signed, unsigned Size,
break; break;
case 2: case 2:
RelocType = O65RELOC_WORD; RelocType = O65RELOC_WORD;
break; break;
case 3: case 3:
@@ -580,6 +581,7 @@ static void O65WriteSeg (O65Desc* D, SegDesc** Seg, unsigned Count, int DoWrite)
/* Write this segment */ /* Write this segment */
if (DoWrite) { if (DoWrite) {
RelocLineInfo (S->Seg);
SegWrite (D->F, S->Seg, O65WriteExpr, D); SegWrite (D->F, S->Seg, O65WriteExpr, D);
} }
@@ -1069,4 +1071,3 @@ void O65WriteTarget (O65Desc* D, File* F)

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1999 Ullrich von Bassewitz */ /* (C) 1999-2001 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Wacholderweg 14 */
/* D-70597 Stuttgart */ /* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -52,7 +52,7 @@
/* Structure describing the format */ /* Structure describing the format */
typedef struct O65Desc_ O65Desc; typedef struct O65Desc O65Desc;
/* Option tags */ /* Option tags */
#define O65OPT_FILENAME 0 #define O65OPT_FILENAME 0

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998 Ullrich von Bassewitz */ /* (C) 1998-2001 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Wacholderweg 14 */
/* D-70597 Stuttgart */ /* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -206,8 +206,8 @@ void ObjAdd (FILE* Obj, const char* Name)
ObjReadHeader (Obj, &O->Header, Name); ObjReadHeader (Obj, &O->Header, Name);
/* Initialize the object module data structure */ /* Initialize the object module data structure */
O->Name = xstrdup (GetModule (Name)); O->Name = xstrdup (GetModule (Name));
O->Flags = OBJ_HAVEDATA; O->Flags = OBJ_HAVEDATA;
/* Read the files list from the object file */ /* Read the files list from the object file */
fseek (Obj, O->Header.FileOffs, SEEK_SET); fseek (Obj, O->Header.FileOffs, SEEK_SET);

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998 Ullrich von Bassewitz */ /* (C) 1998-2001 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Wacholderweg 14 */
/* D-70597 Stuttgart */ /* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -40,8 +40,10 @@
#include <stdio.h> #include <stdio.h>
#include "../common/objdefs.h" /* common */
#include "objdefs.h"
/* ld65 */
#include "objdata.h" #include "objdata.h"
@@ -64,6 +66,9 @@ void ObjReadExports (FILE* F, ObjData* O);
void ObjReadDbgSyms (FILE* F, ObjData* O); void ObjReadDbgSyms (FILE* F, ObjData* O);
/* Read the debug symbols from a file at the current position */ /* Read the debug symbols from a file at the current position */
void ObjReadLineInfos (FILE* F, ObjData* O);
/* Read the line infos from a file at the current position */
void ObjReadSections (FILE* F, ObjData* O); void ObjReadSections (FILE* F, ObjData* O);
/* Read the section data from a file at the current position */ /* Read the section data from a file at the current position */

View File

@@ -312,7 +312,13 @@ Section* ReadSection (FILE* F, ObjData* O)
LineInfoIndex = ReadVar (F); LineInfoIndex = ReadVar (F);
if (LineInfoIndex) { if (LineInfoIndex) {
--LineInfoIndex; --LineInfoIndex;
CHECK (LineInfoIndex < O->LineInfoCount); if (LineInfoIndex >= O->LineInfoCount) {
Internal ("In module `%s', file `%s', line %lu: Invalid line "
"info with index %u (max count %u)",
GetObjFileName (O),
GetSourceFileName (O, Frag->Pos.Name),
Frag->Pos.Line, LineInfoIndex, O->LineInfoCount);
}
/* Point from the fragment to the line info... */ /* Point from the fragment to the line info... */
Frag->LI = O->LineInfos[LineInfoIndex]; Frag->LI = O->LineInfos[LineInfoIndex];
/* ...and back from the line info to the fragment */ /* ...and back from the line info to the fragment */
@@ -495,6 +501,7 @@ void SegWrite (FILE* Tgt, Segment* S, SegWriteFunc F, void* Data)
/* If we have fill bytes, write them now */ /* If we have fill bytes, write them now */
WriteMult (Tgt, S->FillVal, Sec->Fill); WriteMult (Tgt, S->FillVal, Sec->Fill);
Offs += Sec->Fill;
/* Loop over all fragments in this section */ /* Loop over all fragments in this section */
Frag = Sec->FragRoot; Frag = Sec->FragRoot;