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:
41f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  ELFObjectWriter(GNULDBackend& pBackend, const LinkerConfig& pConfig);
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ~ELFObjectWriter();
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  llvm::error_code writeObject(Module& pModule, MemoryArea& pOutput);
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void writeSection(MemoryArea& pOutput, LDSection *section);
496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  GNULDBackend&       target()        { return m_Backend; }
516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const GNULDBackend& target() const  { return m_Backend; }
536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // writeELFHeader - emit ElfXX_Ehdr
556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void writeELFHeader(const LinkerConfig& pConfig,
576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      const Module& pModule,
586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      MemoryArea& pOutput) const;
596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t getEntryPoint(const LinkerConfig& pConfig,
616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                         const Module& pModule) const;
626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emitSectionHeader - emit ElfXX_Shdr
646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitSectionHeader(const Module& pModule,
666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                         const LinkerConfig& pConfig,
676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                         MemoryArea& pOutput) const;
686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emitProgramHeader - emit ElfXX_Phdr
706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitProgramHeader(MemoryArea& pOutput) const;
726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emitShStrTab - emit .shstrtab
746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitShStrTab(const LDSection& pShStrTab,
756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                    const Module& pModule,
766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                    MemoryArea& pOutput);
776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitSectionData(const LDSection& pSection,
796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                       MemoryRegion& pRegion) const;
806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitRelocation(const LinkerConfig& pConfig,
826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      const LDSection& pSection,
836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      MemoryRegion& pRegion) const;
846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emitRel - emit ElfXX_Rel
866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitRel(const LinkerConfig& pConfig,
886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines               const RelocData& pRelocData,
896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines               MemoryRegion& pRegion) const;
906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emitRela - emit ElfXX_Rela
926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitRela(const LinkerConfig& pConfig,
946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                const RelocData& pRelocData,
956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                MemoryRegion& pRegion) const;
966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // getSectEntrySize - compute ElfXX_Shdr::sh_entsize
986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t getSectEntrySize(const LDSection& pSection) const;
1006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // getSectLink - compute ElfXX_Shdr::sh_link
1026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t getSectLink(const LDSection& pSection,
1036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                       const LinkerConfig& pConfig) const;
1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // getSectInfo - compute ElfXX_Shdr::sh_info
1066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t getSectInfo(const LDSection& pSection) const;
1076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
1096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t getLastStartOffset(const Module& pModule) const
1106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  {
1116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    assert(0 && "Call invalid ELFObjectWriter::getLastStartOffset");
1126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return 0;
1136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
1146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitSectionData(const SectionData& pSD, MemoryRegion& pRegion) const;
1166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesprivate:
1186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  GNULDBackend& m_Backend;
1196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
120d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  const LinkerConfig& m_Config;
1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<>
1246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFObjectWriter::getLastStartOffset<32>(const Module& pModule) const;
1256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<>
1276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFObjectWriter::getLastStartOffset<64>(const Module& pModule) const;
1286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
132affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
133