ELFObjectWriter.h revision 6f75755c9204b1d8817ae5a65a2f7e5af0ec3f70
15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- ELFObjectWriter.h --------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#ifndef MCLD_ELF_OBJECT_WRITER_H
105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#define MCLD_ELF_OBJECT_WRITER_H
115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#ifdef ENABLE_UNITTEST
125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <gtest.h>
135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ObjectWriter.h>
156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <cassert>
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
17d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <llvm/Support/system_error.h>
18d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaonamespace mcld {
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass Module;
22d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaoclass LinkerConfig;
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass GNULDBackend;
246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass FragmentLinker;
256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass Relocation;
266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass LDSection;
276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass SectionData;
286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass RelocData;
296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass Output;
306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass MemoryRegion;
316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass MemoryArea;
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/** \class ELFObjectWriter
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  \brief ELFObjectWriter writes the target-independent parts of object files.
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  ELFObjectWriter reads a MCLDFile and writes into raw_ostream
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */
386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass ELFObjectWriter : public ObjectWriter
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef uint64_t FileOffset;
426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinespublic:
44d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  ELFObjectWriter(GNULDBackend& pBackend,
45d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                  const LinkerConfig& pConfig);
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ~ELFObjectWriter();
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  llvm::error_code writeObject(Module& pModule, MemoryArea& pOutput);
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void writeSection(MemoryArea& pOutput, LDSection *section);
536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  GNULDBackend&       target()        { return m_Backend; }
556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const GNULDBackend& target() const  { return m_Backend; }
576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // writeELFHeader - emit ElfXX_Ehdr
596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void writeELFHeader(const LinkerConfig& pConfig,
616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      const Module& pModule,
626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      MemoryArea& pOutput) const;
636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t getEntryPoint(const LinkerConfig& pConfig,
656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                         const Module& pModule) const;
666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emitSectionHeader - emit ElfXX_Shdr
686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitSectionHeader(const Module& pModule,
706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                         const LinkerConfig& pConfig,
716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                         MemoryArea& pOutput) const;
726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emitProgramHeader - emit ElfXX_Phdr
746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitProgramHeader(MemoryArea& pOutput) const;
766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emitShStrTab - emit .shstrtab
786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitShStrTab(const LDSection& pShStrTab,
796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                    const Module& pModule,
806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                    MemoryArea& pOutput);
816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitSectionData(const LDSection& pSection,
836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                       MemoryRegion& pRegion) const;
846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitRelocation(const LinkerConfig& pConfig,
866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      const LDSection& pSection,
876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      MemoryRegion& pRegion) const;
886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emitRel - emit ElfXX_Rel
906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitRel(const LinkerConfig& pConfig,
926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines               const RelocData& pRelocData,
936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines               MemoryRegion& pRegion) const;
946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emitRela - emit ElfXX_Rela
966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitRela(const LinkerConfig& pConfig,
986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                const RelocData& pRelocData,
996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                MemoryRegion& pRegion) const;
1006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // getSectEntrySize - compute ElfXX_Shdr::sh_entsize
1026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
1036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t getSectEntrySize(const LDSection& pSection) const;
1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // getSectLink - compute ElfXX_Shdr::sh_link
1066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t getSectLink(const LDSection& pSection,
1076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                       const LinkerConfig& pConfig) const;
1086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // getSectInfo - compute ElfXX_Shdr::sh_info
1106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t getSectInfo(const LDSection& pSection) const;
1116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
1136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t getLastStartOffset(const Module& pModule) const
1146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  {
1156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    assert(0 && "Call invalid ELFObjectWriter::getLastStartOffset");
1166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return 0;
1176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
1186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitSectionData(const SectionData& pSD, MemoryRegion& pRegion) const;
1206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesprivate:
1226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  GNULDBackend& m_Backend;
1236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
124d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  const LinkerConfig& m_Config;
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<>
1286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFObjectWriter::getLastStartOffset<32>(const Module& pModule) const;
1296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<>
1316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFObjectWriter::getLastStartOffset<64>(const Module& pModule) const;
1326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
136affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
137