manip.h 10 KB

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