exp_dbg.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /* exp_dbg.c: Routines to export debugging information
  2. Copyright (C) 2002-2004 Sebastian Reichelt
  3. Copyright (C) 2005 Kevin Kofler
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software Foundation,
  14. Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  15. #ifdef DEBUGGING_INFO_SUPPORT
  16. /* The format exported by these routines is a COFF file containing both the
  17. actual program and the debugging information (which is stripped out of the
  18. on-calc executable). They are actually object files, but with a ".dbg"
  19. extension to distinguish them from ordinary object files. These files can be
  20. read in by GDB as integrated into TiEmu.
  21. Note that this means that this has to be plain vanilla COFF, NO TIGCC
  22. extensions such as unoptimizable relocs are allowed, unless you are willing
  23. to implement these in GDB/BFD as well. And I really mean IMPLEMENT, not
  24. ignore, cluttering this file with information not used by GDB is useless. As
  25. this format isn't used for linking anyway, the restrictions on the format are
  26. not a problem, and it is pointless to add things not used by GDB. Using
  27. debugging information files for linking purposes or any other non-debugging
  28. purpose is NOT supported. This is NOT a "relocatable linking" feature.
  29. Implementing actual relocatable linking (linking multiple object files into a
  30. single object file) starting from this code is probably possible, but this
  31. code needs to be separate, as relocatable linking SHOULD use TIGCC extensions
  32. in order not to lose information. You'll also have to special-case the
  33. relocatable linking all over the place for things like global imports,
  34. startup sections, merging sections and so on.
  35. -- Kevin Kofler */
  36. #include "exp_dbg.h"
  37. #include "../formats/coff.h"
  38. #include <string.h>
  39. static SIZE CountSectionCOFFSize (const SECTION *Section)
  40. {
  41. SIZE Size = sizeof(COFF_SECTION);
  42. const SYMBOL *Symbol;
  43. const RELOC *Reloc;
  44. if (!Section)
  45. return 0;
  46. Size += Section->Size;
  47. for_each (Symbol, Section->Symbols)
  48. {
  49. COUNT NameLen = strlen (Symbol->Name);
  50. // Symbol table entry
  51. Size += sizeof (COFF_SYMBOL);
  52. // String table entry
  53. if (NameLen > 8)
  54. Size += NameLen + 1;
  55. }
  56. for_each (Reloc, Section->Relocs)
  57. {
  58. // Ignore calc builtins.
  59. if (IsCalcBuiltinLocation (&Reloc->Location))
  60. continue;
  61. // Reloc table entry
  62. Size += sizeof (COFF_RELOC);
  63. }
  64. return Size;
  65. }
  66. // Get the file size needed to export the debugging information file.
  67. // Returns 0 on failure.
  68. // Call this function once to receive necessary error messages.
  69. static SIZE GetDebuggingInfoFileSize (const PROGRAM *Program)
  70. {
  71. SIZE Size = sizeof(COFF_HEADER);
  72. Size += CountSectionCOFFSize (Program->MainSection);
  73. Size += CountSectionCOFFSize (Program->DataSection);
  74. Size += CountSectionCOFFSize (Program->BSSSection);
  75. Size += CountSectionCOFFSize (Program->DebuggingInfoSection[DI_STAB-1]);
  76. Size += CountSectionCOFFSize (Program->DebuggingInfoSection[DI_STABSTR-1]);
  77. return Size;
  78. }
  79. // Export the internal data structures into a TIOS file.
  80. static BOOLEAN ExportDebuggingInfoFile (const PROGRAM *Program, EXP_FILE *File, SIZE FileSize ATTRIBUTE_UNUSED)
  81. {
  82. // A simple macro to make the code more readable.
  83. #define FailWithError(Err...) ({ Error (Err); return FALSE; })
  84. // STUB
  85. return FALSE;
  86. #undef FailWithError
  87. }
  88. // Export the debugging information to a .dbg file.
  89. // This function is a modified version of ExportProgramToFormat.
  90. BOOLEAN ExportDebuggingInfo (const PROGRAM *Program, OUTPUT_FILE_FUNCTION GetOutputFile, OUTPUT_FILE_FINALIZE_FUNCTION FinalizeOutputFile)
  91. {
  92. BOOLEAN Success;
  93. EXP_FILE File;
  94. SIZE Size;
  95. I4 EffectiveSize = 0;
  96. // Fill the output file struct with zeroes.
  97. memset (&File, 0, sizeof (File));
  98. // Get the file size needed to export the file.
  99. Size = GetDebuggingInfoFileSize (Program);
  100. // A size of 0 indicates an error.
  101. if (Size <= 0)
  102. return FALSE;
  103. // Create an output file with the specified format.
  104. if (!(GetOutputFile (&(File.File), Size, 0, FR_DEBUGGING_INFO, FF_GDB_COFF, 0, NULL, FALSE, &EffectiveSize)))
  105. return FALSE;
  106. // Export the program into the output file.
  107. Success = ExportDebuggingInfoFile (Program, &File, Size);
  108. // Finalize and close the output file.
  109. if (FinalizeOutputFile)
  110. FinalizeOutputFile (&(File.File));
  111. return Success;
  112. }
  113. #endif /* DEBUGGING_INFO_SUPPORT */