Browse Source

Start implementing support for debugging information (not complete or working yet).

git-svn-id: file:///var/svn/tigccpp/trunk/tigcc/ld-tigcc@199 9552661e-59e3-4036-b4f2-dbe53926924f
kevinkofler 19 years ago
parent
commit
2f0019cc1b
10 changed files with 292 additions and 19 deletions
  1. 3 3
      Makefile
  2. 13 0
      data.h
  3. 145 0
      export/exp_dbg.c
  4. 34 0
      export/exp_dbg.h
  5. 47 1
      export/export.c
  6. 7 1
      import/imp_coff.c
  7. 2 2
      intrface.h
  8. 37 9
      main.c
  9. 3 2
      manip.c
  10. 1 1
      manip.h

+ 3 - 3
Makefile

@@ -18,7 +18,7 @@ CC = gcc
 CFLAGS = -s -Os -fno-exceptions
 WARN_CFLAGS = -W -Wall -Wwrite-strings -Wpointer-arith
 DEFINES = -DCOFF_SUPPORT -DAMIGAOS_SUPPORT -DTIOS_SUPPORT -DFLASH_OS_SUPPORT -DNOSTUB_DLL_SUPPORT -DFARGO_SUPPORT -DDATA_VAR_SUPPORT -DTIOS_FILE_SUPPORT -DTIOS_UPGRADE_FILE_SUPPORT -DCOFF_TIGCC_EXTENSIONS -DAMIGAOS_TIGCC_EXTENSIONS
-EXE_DEFINES = -DENABLE_HELP -DENABLE_STATS -DENABLE_DUMP
+EXE_DEFINES = -DENABLE_HELP -DENABLE_STATS -DENABLE_DUMP -DDEBUGGING_INFO_SUPPORT
 
 RM = rm
 RMFLAGS = -f
@@ -27,9 +27,9 @@ COMPILE_C = $(CC) -c $(CFLAGS) $(ARCHFLAGS) $(WARN_CFLAGS) $(DEFINES)
 
 HEADERS = *.h formats/*.h import/*.h export/*.h bincode/*.h insert/*.h insert/model/*.h int_def.inc
 AR_HEADERS = ar/*.h ar/import/*.h ar/export/*.h *.h formats/*.h
-OBJECTS = main.o integers.o int_arb.o manip.o constmrg.o gcunused.o reorder.o import/import.o import/imp_coff.o import/imp_amig.o import/imp_ar.o export/export.o export/exp_def.o export/exp_os.o export/exp_tios.o export/exp_ndll.o export/exp_farg.o export/exp_data.o bincode/fix_m68k.o bincode/fix_tios.o bincode/fix_emu.o bincode/cutrange.o insert/ins_def.o insert/model/list.o insert/kernel.o insert/comprrlc.o insert/other.o special.o dump.o
+OBJECTS = main.o integers.o int_arb.o manip.o constmrg.o gcunused.o reorder.o import/import.o import/imp_coff.o import/imp_amig.o import/imp_ar.o export/export.o export/exp_def.o export/exp_os.o export/exp_tios.o export/exp_ndll.o export/exp_farg.o export/exp_data.o export/exp_dbg.o bincode/fix_m68k.o bincode/fix_tios.o bincode/fix_emu.o bincode/cutrange.o insert/ins_def.o insert/model/list.o insert/kernel.o insert/comprrlc.o insert/other.o special.o dump.o
 AR_OBJECTS = ar/main.o ar/manip.o ar/import/import.o ar/import/imp_coff.o ar/import/imp_amig.o ar/export/exp_ar.o ar/dump.o integers.o
-DLL_OBJECTS = main.do integers.do int_arb.do manip.do constmrg.do gcunused.do reorder.do import/import.do import/imp_coff.do import/imp_amig.do import/imp_ar.do export/export.do export/exp_def.do export/exp_os.do export/exp_tios.do export/exp_ndll.do export/exp_farg.do export/exp_data.do bincode/fix_m68k.do bincode/fix_tios.do bincode/fix_emu.do bincode/cutrange.do insert/ins_def.do insert/model/list.do insert/kernel.do insert/comprrlc.do insert/other.do special.do
+DLL_OBJECTS = main.do integers.do int_arb.do manip.do constmrg.do gcunused.do reorder.do import/import.do import/imp_coff.do import/imp_amig.do import/imp_ar.do export/export.do export/exp_def.do export/exp_os.do export/exp_tios.do export/exp_ndll.do export/exp_farg.do export/exp_data.do export/exp_dbg.do bincode/fix_m68k.do bincode/fix_tios.do bincode/fix_emu.do bincode/cutrange.do insert/ins_def.do insert/model/list.do insert/kernel.do insert/comprrlc.do insert/other.do special.do
 DLL_AR_OBJECTS = ar/main.do ar/manip.do ar/import/import.do ar/import/imp_coff.do ar/import/imp_amig.do ar/export/exp_ar.do
 BACKUPS = *~ format/*~ import/*~ export/*~ bincode/*~ insert/*~ insert/model/*~ ar/*~ ar/import/*~ ar/export/*~
 

+ 13 - 0
data.h

@@ -50,6 +50,13 @@ struct GLOBAL_IMPORT;
 // PT_FARGO:      Fargo II mode; uses specific output format
 typedef enum {PT_NATIVE = 1, PT_NOSTUB = 2, PT_KERNEL = 0, PT_NOSTUB_DLL = 3, PT_FLASH_OS = 4, PT_FARGO = 5} ProgramTypes;
 
+// Debugging Information Section Type Enumeration
+// DI_NONE:       Not debugging information (same as FALSE)
+// DI_STAB:       Stabs symbol table
+// DI_STABSTR:    Stabs string table
+// DI_LAST:       Last debugging information type, for iterating purposes
+typedef enum {DI_NONE = FALSE, DI_STAB = 1, DI_STABSTR = 2, DI_LAST = 2} DebuggingInfoTypes;
+
 typedef I4 VERSION;
 
 // Named Location in a Section
@@ -95,6 +102,11 @@ typedef struct PROGRAM {
 		*MainSection,     // Pointer to the main section, as soon as it is known. Usually only this section has to be written to the file.
 		*DataSection,     // Pointer to the data section, if code and data are separated.
 		*BSSSection;      // Pointer to the BSS section, if the program contains one.
+#ifdef DEBUGGING_INFO_SUPPORT
+	BOOLEAN HaveDebuggingInfo; // Flag set if any debugging information is present, so we don't emit a .dbg file if there is no debugging information anyway.
+	struct SECTION
+		*DebuggingInfoSection[DI_LAST]; // Pointers to the debugging information sections of each type.
+#endif
 	struct GLOBAL_IMPORT
 		*BSSImport;       // Pointer to the global import which handles the BSS section.
 	SECTION_MARKERS
@@ -126,6 +138,7 @@ typedef struct SECTION {
 	BOOLEAN Referenced;   // Specifies whether the section is either essential itself or referenced somewhere (in a reloc) from an essential section.
 	                      // This flag is significant only during RemoveUnusedSections. Before (or if not removing unused sections), it is always FALSE, afterwards, it is always TRUE.
 	OFFSET StartupNumber; // If nonzero, specifies the location of the section in respect to other startup sections.
+	DebuggingInfoTypes DebuggingInfoType; // Nonzero if this is a debugging information section, the actual value indicates what type of debugging information.
 	BOOLEAN Constructors; // Is a vector of constructor functions.
 	BOOLEAN Destructors;  // Is a vector of destructor functions.
 	BOOLEAN CanCutRanges; // Range cutting is allowed at least in parts of the section (i.e. the section or segments in it do not contain any implicit relative relocs).

+ 145 - 0
export/exp_dbg.c

@@ -0,0 +1,145 @@
+/* exp_dbg.c: Routines to export debugging information
+
+   Copyright (C) 2002-2004 Sebastian Reichelt
+   Copyright (C) 2005 Kevin Kofler
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef DEBUGGING_INFO_SUPPORT
+
+/* The format exported by these routines is a COFF file containing both the
+   actual program and the debugging information (which is stripped out of the
+   on-calc executable). They are actually object files, but with a ".dbg"
+   extension to distinguish them from ordinary object files. These files can be
+   read in by GDB as integrated into TiEmu.
+
+   Note that this means that this has to be plain vanilla COFF, NO TIGCC
+   extensions such as unoptimizable relocs are allowed, unless you are willing
+   to implement these in GDB/BFD as well. And I really mean IMPLEMENT, not
+   ignore, cluttering this file with information not used by GDB is useless. As
+   this format isn't used for linking anyway, the restrictions on the format are
+   not a problem, and it is pointless to add things not used by GDB. Using
+   debugging information files for linking purposes or any other non-debugging
+   purpose is NOT supported. This is NOT a "relocatable linking" feature.
+
+   Implementing actual relocatable linking (linking multiple object files into a
+   single object file) starting from this code is probably possible, but this
+   code needs to be separate, as relocatable linking SHOULD use TIGCC extensions
+   in order not to lose information. You'll also have to special-case the
+   relocatable linking all over the place for things like global imports,
+   startup sections, merging sections and so on.
+
+   -- Kevin Kofler */
+
+#include "exp_dbg.h"
+#include "../formats/coff.h"
+#include <string.h>
+
+static SIZE CountSectionCOFFSize (const SECTION *Section)
+{
+	SIZE Size = sizeof(COFF_SECTION);
+	const SYMBOL *Symbol;
+	const RELOC *Reloc;
+
+	if (!Section)
+		return 0;
+
+	Size += Section->Size;
+
+	for_each (Symbol, Section->Symbols)
+	{
+		COUNT NameLen = strlen (Symbol->Name);
+		// Symbol table entry
+		Size += sizeof (COFF_SYMBOL);
+		// String table entry
+		if (NameLen > 8)
+			Size += NameLen + 1;
+	}
+
+	for_each (Reloc, Section->Relocs)
+	{
+		// Ignore calc builtins.
+		if (IsCalcBuiltinLocation (&Reloc->Location))
+			continue;
+
+		// Reloc table entry
+		Size += sizeof (COFF_RELOC);
+	}
+
+	return Size;
+}
+
+// Get the file size needed to export the debugging information file.
+// Returns 0 on failure.
+// Call this function once to receive necessary error messages.
+static SIZE GetDebuggingInfoFileSize (const PROGRAM *Program)
+{
+	SIZE Size = sizeof(COFF_HEADER);
+
+	Size += CountSectionCOFFSize (Program->MainSection);
+	Size += CountSectionCOFFSize (Program->DataSection);
+	Size += CountSectionCOFFSize (Program->BSSSection);
+	Size += CountSectionCOFFSize (Program->DebuggingInfoSection[DI_STAB-1]);
+	Size += CountSectionCOFFSize (Program->DebuggingInfoSection[DI_STABSTR-1]);
+
+	return Size;
+}
+
+// Export the internal data structures into a TIOS file.
+static BOOLEAN ExportDebuggingInfoFile (const PROGRAM *Program, EXP_FILE *File, SIZE FileSize ATTRIBUTE_UNUSED)
+{
+	// A simple macro to make the code more readable.
+#define FailWithError(Err...) ({ Error (Err); return FALSE; })
+
+	// STUB
+	return FALSE;
+
+#undef FailWithError
+}
+
+// Export the debugging information to a .dbg file.
+// This function is a modified version of ExportProgramToFormat.
+BOOLEAN ExportDebuggingInfo (const PROGRAM *Program, OUTPUT_FILE_FUNCTION GetOutputFile, OUTPUT_FILE_FINALIZE_FUNCTION FinalizeOutputFile)
+{
+	BOOLEAN Success;
+	EXP_FILE File;
+	SIZE Size;
+	I4 EffectiveSize = 0;
+	
+	// Fill the output file struct with zeroes.
+	memset (&File, 0, sizeof (File));
+	
+	// Get the file size needed to export the file.
+	Size = GetDebuggingInfoFileSize (Program);
+	
+	// A size of 0 indicates an error.
+	if (Size <= 0)
+		return FALSE;
+	
+	// Create an output file with the specified format.
+	if (!(GetOutputFile (&(File.File), Size, 0, FR_DEBUGGING_INFO, FF_GDB_COFF, 0, NULL, FALSE, &EffectiveSize)))
+		return FALSE;
+	
+	// Export the program into the output file.
+	Success = ExportDebuggingInfoFile (Program, &File, Size);
+	
+	// Finalize and close the output file.
+	if (FinalizeOutputFile)
+		FinalizeOutputFile (&(File.File));
+	
+	return Success;
+}
+
+#endif /* DEBUGGING_INFO_SUPPORT */

+ 34 - 0
export/exp_dbg.h

@@ -0,0 +1,34 @@
+/* exp_dbg.h: Routines to export a debugging information file
+
+   Copyright (C) 2005 Kevin Kofler
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef EXP_DBG_H
+#define EXP_DBG_H
+
+#include "../generic.h"
+
+#ifdef DEBUGGING_INFO_SUPPORT
+
+#include "exp_def.h"
+#include "../data.h"
+
+// Export the debugging information to a .dbg file.
+BOOLEAN ExportDebuggingInfo (const PROGRAM *Program, OUTPUT_FILE_FUNCTION GetOutputFile, OUTPUT_FILE_FINALIZE_FUNCTION FinalizeOutputFile);
+
+#endif /* DEBUGGING_INFO_SUPPORT */
+
+#endif

+ 47 - 1
export/export.c

@@ -1,7 +1,7 @@
 /* export.c: Routines for file exports
 
    Copyright (C) 2002-2004 Sebastian Reichelt
-   Copyright (C) 2003-2004 Kevin Kofler
+   Copyright (C) 2003-2005 Kevin Kofler
    Copyright (C) 2004 Billy Charvet
 
    This program is free software; you can redistribute it and/or modify
@@ -35,6 +35,9 @@
 #ifdef DATA_VAR_SUPPORT
 #include "exp_data.h"
 #endif /* DATA_VAR_SUPPORT */
+#ifdef DEBUGGING_INFO_SUPPORT
+#include "exp_dbg.h"
+#endif /* DEBUGGING_INFO_SUPPORT */
 
 #include "../formats/tios.h"
 #include "../formats/tiosupgd.h"
@@ -179,6 +182,15 @@ BOOLEAN ExportProgram (const PROGRAM *Program, OUTPUT_FILE_FUNCTION GetOutputFil
 	if (!GetOutputFile)
 		return FALSE;
 	
+#ifdef DEBUGGING_INFO_SUPPORT
+	// If we have debugging information to export, do it.
+	if (Program->HaveDebuggingInfo)
+	{
+			if (!ExportDebuggingInfo (Program, GetOutputFile, FinalizeOutputFile))
+				return FALSE;
+	}
+#endif
+
 	switch (Program->Type)
 	{
 #ifdef FLASH_OS_SUPPORT
@@ -543,6 +555,34 @@ BOOLEAN GetOutputFile (INT_EXP_FILE *File, SIZE FileSize, unsigned int DestCalc,
 			break;
 #endif /* TIOS_UPGRADE_FILE_SUPPORT */
 		
+#ifdef DEBUGGING_INFO_SUPPORT
+		case FF_GDB_COFF:
+			*EffectiveSize = FileSize;
+			{
+				SIZE FileNameSize = DestFileSize+4;
+					
+				// Create a temporary file name string.
+				char CurOutputFileName[FileNameSize+1];
+				strncpy (CurOutputFileName, DestFile, DestFileSize);
+					
+				// Append ".dbg" to the file name.
+				strcpy (CurOutputFileName + DestFileSize, ".dbg");
+				
+				// Zero-terminate the string.
+				CurOutputFileName [FileNameSize] = 0;
+				
+				// Open a file with the specified name.
+				if (!(File->File = fopen (CurOutputFileName, "wb")))
+				{
+					Error (CurOutputFileName, "Could not open file for writing.");
+					return FALSE;
+				}
+				
+				return TRUE;
+			}
+			break;
+#endif /* DEBUGGING_INFO_SUPPORT */
+
 		default:
 			Error (NULL, "Unrecognized output file format.");
 	}
@@ -625,6 +665,12 @@ void FinalizeOutputFile (INT_EXP_FILE *File)
 			}
 			break;
 #endif /* TIOS_UPGRADE_FILE_SUPPORT */
+
+#ifdef DEBUGGING_INFO_SUPPORT
+		case FF_GDB_COFF:
+			// Do nothing.
+			break;
+#endif /* DEBUGGING_INFO_SUPPORT */
 	}
 	
 	// Close the file.

+ 7 - 1
import/imp_coff.c

@@ -1,7 +1,7 @@
 /* imp_coff.c: Routines to import a COFF file
 
    Copyright (C) 2002-2003 Sebastian Reichelt
-   Copyright (C) 2003-2004 Kevin Kofler
+   Copyright (C) 2003-2005 Kevin Kofler
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -170,6 +170,12 @@ BOOLEAN ImportCOFFFile (PROGRAM *Program, const I1 *File, SIZE FileSize, const c
 				Section->StartupNumber = StartupNumber;
 				Section->Constructors  = (!(strcmp (SectionName, ".ctors")));
 				Section->Destructors   = (!(strcmp (SectionName, ".dtors")));
+#ifdef DEBUGGING_INFO_SUPPORT
+				if (!strcmp (SectionName, ".stab"))
+					Section->DebuggingInfoType = DI_STAB;
+				else if (!strcmp (SectionName, ".stabstr"))
+					Section->DebuggingInfoType = DI_STABSTR;
+#endif
 				Section->CanCutRanges  = AllRelocs;
 				Section->FileName      = FileName;
 				

+ 2 - 2
intrface.h

@@ -77,10 +77,10 @@ typedef enum {
 #define HIGHEST_CALC CALC_V200
 
 // File Role Constants (File Output)
-typedef enum {FR_MAIN = 0, FR_DATA = 1} FileRoles;
+typedef enum {FR_MAIN = 0, FR_DATA = 1, FR_DEBUGGING_INFO = 2} FileRoles;
 
 // File Format Constants (File Output)
-typedef enum {FF_NONE = -1, FF_TIOS = 0, FF_TIOS_UPGRADE = 1} FileFormats;
+typedef enum {FF_NONE = -1, FF_TIOS = 0, FF_TIOS_UPGRADE = 1, FF_GDB_COFF = 2} FileFormats;
 
 #ifdef TARGET_EMBEDDED
 

+ 37 - 9
main.c

@@ -1,7 +1,7 @@
 /* main.c: Main entry point for ld-tigcc, handling the command line input
 
    Copyright (C) 2002-2004 Sebastian Reichelt
-   Copyright (C) 2004 Kevin Kofler
+   Copyright (C) 2004-2005 Kevin Kofler
    Copyright (C) 2004 Billy Charvet
 
    This program is free software; you can redistribute it and/or modify
@@ -18,6 +18,14 @@
    along with this program; if not, write to the Free Software Foundation,
    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
 
+#ifdef DEBUGGING_INFO_SUPPORT
+#ifdef TARGET_EMBEDDED
+#error Debugging information is not yet supported for link.dll.
+#else
+#warning Debugging information support is experimental.
+#endif
+#endif
+
 #include "generic.h"
 #include "intrface.h"
 #include "data.h"
@@ -226,7 +234,7 @@ int main (int ArgCount, const char **Args)
 			DoDump (1);
 			
 			// Merge all zero-data and uninitialized sections.
-			Program.BSSSection = MergeAllSections (&Program, NULL, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE);
+			Program.BSSSection = MergeAllSections (&Program, NULL, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, DI_NONE);
 			
 			// As a dirty trick, allow the caller to skip the BSS
 			// initialization entirely.
@@ -234,9 +242,29 @@ int main (int ArgCount, const char **Args)
 				Program.BSSSection->Initialized = FALSE;
 			
 			// Extract, merge, and mark constructor and destructor sections.
-			CreateSectionMarkers (&(Program.Constructors), MergeAllSections (&Program, NULL, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE,  FALSE, TRUE, TRUE));
-			CreateSectionMarkers (&(Program.Destructors),  MergeAllSections (&Program, NULL, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE,  TRUE, TRUE));
+			CreateSectionMarkers (&(Program.Constructors), MergeAllSections (&Program, NULL, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE,  FALSE, TRUE, TRUE, DI_NONE));
+			CreateSectionMarkers (&(Program.Destructors),  MergeAllSections (&Program, NULL, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE,  TRUE, TRUE, DI_NONE));
 				
+#ifdef DEBUGGING_INFO_SUPPORT
+			// If we want debugging information, merge all debugging information
+			// sections of each type.
+			{
+				DebuggingInfoTypes i;
+				for (i = 0; i < DI_LAST; i++)
+				{
+					Program.DebuggingInfoSection[i] = MergeAllSections (&Program, NULL, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, i + 1);
+					if (Program.DebuggingInfoSection[i])
+					{
+						Program.DebuggingInfoSection[i]->Handled = TRUE;
+						// FIXME: How should we remove unused sections with debugging information in place?
+						//        The linker will probably have to understand the debugging information formats up to some point.
+						Program.DebuggingInfoSection[i]->Essential = TRUE;
+						Program.HaveDebuggingInfo = TRUE;
+					}
+				}
+			}
+#endif
+
 #ifdef DATA_VAR_SUPPORT
 			// If we want a separate data variable, merge all data
 			// sections.
@@ -265,7 +293,7 @@ int main (int ArgCount, const char **Args)
 					DoSpecialDump (1, "(const-merged)");
 				}
 				
-				Program.DataSection = MergeAllSections (&Program, NULL, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE);
+				Program.DataSection = MergeAllSections (&Program, NULL, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, FALSE, DI_NONE);
 				// Mark the section as "handled" so it will not be merged
 				// with code.
 				if (Program.DataSection)
@@ -359,16 +387,16 @@ int main (int ArgCount, const char **Args)
 					// area (base 2), the big OS code part.
 					
 					// Merge all startup sections.
-					MergeAllSections (&Program, NULL, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE);
+					MergeAllSections (&Program, NULL, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, DI_NONE);
 					// Merge all normal sections.
-					MergeAllSections (&Program, NULL, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE);
+					MergeAllSections (&Program, NULL, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, DI_NONE);
 				}				
 #endif /* FLASH_OS_SUPPORT */
 				
 				// Merge all initialized sections.
-				Program.MainSection = MergeAllSections (&Program, NULL, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE);
+				Program.MainSection = MergeAllSections (&Program, NULL, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, DI_NONE);
 				// Merge all unhandled sections.
-				Program.MainSection = MergeAllSections (&Program, Program.MainSection, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE);
+				Program.MainSection = MergeAllSections (&Program, Program.MainSection, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, DI_NONE);
 				
 				// Record the size of the BSS section.
 				if (Program.BSSSection)

+ 3 - 2
manip.c

@@ -945,7 +945,7 @@ SECTION *MergeSections (SECTION *Dest, SECTION *Src)
 }
 
 // Merge all sections of the specified type.
-SECTION *MergeAllSections (PROGRAM *Program, SECTION *Dest, BOOLEAN AcceptInitialized, BOOLEAN AcceptUninitialized, BOOLEAN AcceptZeroes, BOOLEAN AcceptContents, BOOLEAN AcceptData, BOOLEAN AcceptCode, BOOLEAN AcceptNonConstructors, BOOLEAN AcceptConstructors, BOOLEAN AcceptDestructors, BOOLEAN AcceptNonStartup, BOOLEAN AcceptStartup)
+SECTION *MergeAllSections (PROGRAM *Program, SECTION *Dest, BOOLEAN AcceptInitialized, BOOLEAN AcceptUninitialized, BOOLEAN AcceptZeroes, BOOLEAN AcceptContents, BOOLEAN AcceptData, BOOLEAN AcceptCode, BOOLEAN AcceptNonConstructors, BOOLEAN AcceptConstructors, BOOLEAN AcceptDestructors, BOOLEAN AcceptNonStartup, BOOLEAN AcceptStartup, DebuggingInfoTypes AcceptDebuggingInfo)
 {
 	BOOLEAN MergeForward = FALSE;
 	SECTION *CurMergedSection = NULL, *Section, *NextSection;
@@ -969,7 +969,8 @@ SECTION *MergeAllSections (PROGRAM *Program, SECTION *Dest, BOOLEAN AcceptInitia
 			&& (AcceptConstructors    || (!(Section->Constructors)))
 			&& (AcceptDestructors     || (!(Section->Destructors)))
 			&& (AcceptNonStartup      || Section->StartupNumber)
-			&& (AcceptStartup         || (!(Section->StartupNumber))))
+			&& (AcceptStartup         || (!(Section->StartupNumber)))
+			&& (AcceptDebuggingInfo   == Section->DebuggingInfoType))
 		{
 			// If no current merged section has been specified, make this
 			// one current. Otherwise, merge the current merged section

+ 1 - 1
manip.h

@@ -98,7 +98,7 @@ void OptimizeRelocs (PROGRAM *Program);
 SECTION *MergeSections (SECTION *Dest, SECTION *Src);
 // Merge all sections of the specified type.
 // Returns the merged section if successful (even if Dest is NULL).
-SECTION *MergeAllSections (PROGRAM *Program, SECTION *Dest, BOOLEAN AcceptInitialized, BOOLEAN AcceptUninitialized, BOOLEAN AcceptZeroes, BOOLEAN AcceptContents, BOOLEAN AcceptData, BOOLEAN AcceptCode, BOOLEAN AcceptNonConstructors, BOOLEAN AcceptConstructors, BOOLEAN AcceptDestructors, BOOLEAN AcceptNonStartup, BOOLEAN AcceptStartup);
+SECTION *MergeAllSections (PROGRAM *Program, SECTION *Dest, BOOLEAN AcceptInitialized, BOOLEAN AcceptUninitialized, BOOLEAN AcceptZeroes, BOOLEAN AcceptContents, BOOLEAN AcceptData, BOOLEAN AcceptCode, BOOLEAN AcceptNonConstructors, BOOLEAN AcceptConstructors, BOOLEAN AcceptDestructors, BOOLEAN AcceptNonStartup, BOOLEAN AcceptStartup, DebuggingInfoTypes AcceptDebuggingInfo);
 
 // Get the size that would result from padding a section of size
 // OrigSize to a multiple of Alignment.