manip.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /* manip.h: Routines to manipulate the internal data
  2. Copyright (C) 2002-2003 Sebastian Reichelt
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2, or (at your option)
  6. any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software Foundation,
  13. Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  14. #ifndef MANIP_H
  15. #define MANIP_H
  16. #include "generic.h"
  17. #include "data.h"
  18. // Free the program tree.
  19. void FreeProgram (PROGRAM *Program);
  20. // Free a section. The section is assumed not to be referenced. Use
  21. // RemoveSectionIfUnused instead if the section might still be referenced.
  22. void FreeSection (SECTION *Section);
  23. // Free a relocation entry.
  24. void FreeReloc (RELOC *Reloc);
  25. // Free the relation reference of a relocation entry, and set it to
  26. // NULL.
  27. void FreeRelocRelation (RELOC *Reloc);
  28. // Free the symbol name of a location, if this is necessary.
  29. // If a symbol is already known, set the symbol name to its name.
  30. // Decrease the number of unresolved relocs in the section.
  31. void FreeLocationSymbolName (SECTION *Section, LOCATION *Location);
  32. // Free a section if it is no longer referenced. Update the ReferencedLibCount
  33. // accordingly.
  34. BOOLEAN RemoveSectionIfUnused (SECTION *Section);
  35. // Create a section symbol for the given section, if none has been
  36. // created yet. If there already is one, set its name accordingly.
  37. // Return the section symbol.
  38. SYMBOL *CreateSectionSymbol (SECTION *Section, const char *SectionName);
  39. // Create a segment for the entire given section, if none has been
  40. // created yet. If the section already contains segments, return
  41. // NULL.
  42. SEGMENT *CreateSectionSegment (SECTION *Section);
  43. // If the section is a startup section, insert it at the place where
  44. // it belongs. Otherwise, append it to the end of the program.
  45. void InsertSection (PROGRAM *Program, SECTION *Section);
  46. // Find the last startup section below or at StartupNumber.
  47. // If there is no such section, the function returns NULL.
  48. SECTION *FindStartupSection (const PROGRAM *Program, OFFSET StartupNumber);
  49. // Insert the item at the correct place in the section.
  50. void InsertSymbol (SECTION *Section, SYMBOL *Symbol);
  51. void InsertReloc (SECTION *Section, RELOC *Reloc);
  52. // Find the item preceding or following the given location. May return NULL.
  53. #define DefineFindItemAtPos(Type,Item) Type *Find##Item##AtPos (const SECTION *Section, OFFSET Location, BOOLEAN Following)
  54. DefineFindItemAtPos (SYMBOL, Symbol);
  55. DefineFindItemAtPos (RELOC, Reloc);
  56. DefineFindItemAtPos (ROM_CALL, ROMCall);
  57. DefineFindItemAtPos (RAM_CALL, RAMCall);
  58. DefineFindItemAtPos (LIB_CALL, LibCall);
  59. #undef DefineFindItemAtPos
  60. // Get the file name where the code at a given location in the
  61. // section came from. May return NULL.
  62. const char *GetFileName (const SECTION *Section, OFFSET Location);
  63. // Return the offset of the specified location into the section. If the
  64. // offset is unknown, emit a warning and return 0.
  65. OFFSET GetLocationOffset (const SECTION *Section, const LOCATION *Location);
  66. // Increase the counters and reference information necessary when this
  67. // location is used in the specified reloc.
  68. void HandleLocation (RELOC *Reloc, LOCATION *Location);
  69. // Point the location to the appropriate symbol, if one is found.
  70. SYMBOL *ResolveLocation (PROGRAM *Program, SECTION *Section, LOCATION *Location);
  71. // Resolve the reloc, if possible.
  72. // Force: Fail on unresolvable references.
  73. BOOLEAN ResolveReloc (RELOC *Reloc, BOOLEAN Force);
  74. // Resolve all relocs in the program, if possible.
  75. // Force: Fail on unresolvable references.
  76. BOOLEAN ResolveRelocs (PROGRAM *Program, BOOLEAN Force);
  77. // Optimize the location to have the least possible offset.
  78. void OptimizeLocation (LOCATION *Location);
  79. // Optimize all relocs to have the least possible target and relation offset.
  80. void OptimizeRelocs (PROGRAM *Program);
  81. // Remove all unused sections.
  82. void RemoveUnusedSections (PROGRAM *Program);
  83. // Merge section Src into Dest.
  84. // Returns Dest if successful.
  85. SECTION *MergeSections (SECTION *Dest, SECTION *Src);
  86. // Merge all sections of the specified type.
  87. // Returns the merged section if successful (even if Dest is NULL).
  88. 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);
  89. // Get the size that would result from padding a section of size
  90. // OrigSize to a multiple of Alignment.
  91. SIZE GetPaddedSize (SIZE OrigSize, COUNT Alignment);
  92. // Pad the section so its size becomes a multiple of Alignment.
  93. BOOLEAN PadSection (SECTION *Section, COUNT Alignment);
  94. // Try to resolve and remove relative relocs.
  95. BOOLEAN FixupRelativeRelocs (PROGRAM *Program);
  96. // Try to resolve and remove a single relative reloc.
  97. // This may cause the reloc to be freed.
  98. BOOLEAN FixupRelativeReloc (RELOC *Reloc);
  99. // Find a reloc with the same location and size as this one.
  100. RELOC *FindCompatibleReloc (const RELOC *Reloc, BOOLEAN AllowRelative);
  101. // Find a reloc which matches the specified criteria.
  102. RELOC *FindMatchingReloc (const SECTION *Section, OFFSET Location, SIZE Size, BOOLEAN AllowRelative, const void *Exception, const RELOC *Hint);
  103. // Make a reloc relative, and set its relation to the beginning of
  104. // the section plus Offset. If Section is NULL, the program entry
  105. // point is used as the relation.
  106. BOOLEAN SetRelocRelation (RELOC *Reloc, SECTION *Section, OFFSET Offset);
  107. // Make a reloc relative to the program entry point.
  108. BOOLEAN SetRelocProgramRelative (RELOC *Reloc);
  109. // Find or create a common symbol with specified name and size.
  110. SYMBOL *MakeCommonSymbol (PROGRAM *Program, const char *SymName, SIZE Size, BOOLEAN Initialize, const char *FileName);
  111. // Try to find and import a symbol with a given name in some archive.
  112. BOOLEAN ImportSymbolFromArchive (PROGRAM *Program, const char *SymName);
  113. // Create marker symbols at the beginning and end of the section, and write
  114. // them to Marker. Returns NULL on error.
  115. SECTION_MARKERS *CreateSectionMarkers (SECTION_MARKERS *Marker, SECTION *Section);
  116. // Get the object file at the specified position in the archive.
  117. ARCHIVE_OBJECT *GetArchiveObject (ARCHIVE *Archive, FILE_PTR FileOffset);
  118. // Get a reference to the library identified in the string. The library is
  119. // added to the program's used libraries if necessary.
  120. LIBRARY *GetLibrary (PROGRAM *Program, const char *LibName);
  121. // Add a global import. This means that all archive members which export this
  122. // symbol should be imported (unlike the import done by a reloc, which only
  123. // imports the first member exporting the symbol).
  124. // If no member was imported because of this, a warning will be displayed at
  125. // the end.
  126. // This calls CreateGlobalImport and ResolveGlobalImport.
  127. GLOBAL_IMPORT *AddGlobalImport (PROGRAM *Program, const char *SymName);
  128. // First part of AddGlobalImport. Add a global import to the list.
  129. GLOBAL_IMPORT *CreateGlobalImport (PROGRAM *Program, const char *SymName);
  130. // Second part of AddGlobalImport. Try to resolve the newly added global
  131. // import against already available archives.
  132. void ResolveGlobalImport (PROGRAM *Program, GLOBAL_IMPORT *Import);
  133. // Check whether the symbol matches any global import,
  134. // performing the appropriate actions if necessary.
  135. GLOBAL_IMPORT *CheckGlobalImports (PROGRAM *Program, ARCHIVE_SYMBOL *Symbol);
  136. // Check whether the symbol matches the specified global import,
  137. // performing the appropriate actions if necessary.
  138. BOOLEAN CheckGlobalImport (GLOBAL_IMPORT *Import, ARCHIVE_SYMBOL *Symbol);
  139. // Check whether all conditions are met for an archive symbol with multiple
  140. // or inverted conditions. If they are, import the appropriate file, and
  141. // increment the counters of all global imports fulfilling non-inverted
  142. // conditions.
  143. BOOLEAN CheckMultiConditionSymbol (PROGRAM *Program, ARCHIVE_SYMBOL *Symbol);
  144. // Resolve all remaining global imports. Usually, global imports are
  145. // processed directly, but if a symbol contains an inverted condition, we
  146. // have to wait until we really know that no such global import exists.
  147. void ResolveRemainingGlobalImports (PROGRAM *Program);
  148. // Check whether all global imports have succeeded at least once.
  149. BOOLEAN CheckAllGlobalImports (PROGRAM *Program);
  150. // Find the first segment that overlaps with the specified range.
  151. SEGMENT *FindSegment (const SECTION *Section, OFFSET Start, OFFSET End);
  152. // Check whether the specified range is declared to contain code.
  153. BOOLEAN IsCodeRange (const SECTION *Section, OFFSET Start, OFFSET End);
  154. // Check whether the section data in the specified range is zero. This only
  155. // checks the actual data, not the relocs, ROM calls, etc.
  156. BOOLEAN IsZeroDataRange (const SECTION *Section, OFFSET Start, OFFSET End);
  157. // Check whether the specified range contains only binary data, without
  158. // relocs, ROM calls, or anything similar. The range includes Start, but not
  159. // End.
  160. // The Exception parameter specifies an item to skip when searching for
  161. // possible problems.
  162. BOOLEAN IsBinaryDataRange (const SECTION *Section, OFFSET Start, OFFSET End, const void *Exception);
  163. // Check whether there is a reloc or symbol or something similar which
  164. // prevents us from optimizing away some code at the end of the section.
  165. // The Exception parameter specifies an item to skip when searching for
  166. // possible problems.
  167. BOOLEAN CanShrinkSection (const SECTION *Section, OFFSET Location, const void *Exception);
  168. // Cut the section off at the specified location. All items behind this
  169. // location are removed.
  170. void CutSection (SECTION *Section, OFFSET Location);
  171. // Allocate space at the end of the section and return a pointer to it (NULL
  172. // in case of error, or if Size is 0). The data is initialized to zero.
  173. I1 *AllocateSpaceInSection (SECTION *Section, SIZE Size);
  174. // Apply general architecture-specific code fixes and optimizations to the
  175. // program.
  176. void FixCode (PROGRAM *Program);
  177. // Disable range cutting for an entire section.
  178. void DisableRangeCutting (SECTION *Section);
  179. #endif