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//===----------------------------------------------------------------------===//
987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#ifndef MCLD_LD_ELFOBJWRITER_H
1087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#define MCLD_LD_ELFOBJWRITER_H
115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ObjectWriter.h>
126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <cassert>
135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Support/FileOutputBuffer.h>
15d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
1622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaonamespace mcld {
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1887f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass EhFrame;
1922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass Module;
20d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaoclass LinkerConfig;
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass GNULDBackend;
226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass FragmentLinker;
236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass Relocation;
246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass LDSection;
256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass SectionData;
266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass RelocData;
276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass Output;
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/** \class ELFObjectWriter
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  \brief ELFObjectWriter writes the target-independent parts of object files.
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  ELFObjectWriter reads a MCLDFile and writes into raw_ostream
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */
346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass ELFObjectWriter : public ObjectWriter
355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaopublic:
37f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  ELFObjectWriter(GNULDBackend& pBackend, const LinkerConfig& pConfig);
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ~ELFObjectWriter();
405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
41a790f0a8f3175183bea088389b3e4ae41813e192Stephen Hines  std::error_code writeObject(Module& pModule, FileOutputBuffer& pOutput);
4287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
4387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  size_t getOutputSize(const Module& pModule) const;
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
4687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void writeSection(Module& pModule,
4787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                    FileOutputBuffer& pOutput, LDSection *section);
486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  GNULDBackend&       target()        { return m_Backend; }
506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const GNULDBackend& target() const  { return m_Backend; }
526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // writeELFHeader - emit ElfXX_Ehdr
546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void writeELFHeader(const LinkerConfig& pConfig,
566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      const Module& pModule,
5787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      FileOutputBuffer& pOutput) const;
586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t getEntryPoint(const LinkerConfig& pConfig,
606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                         const Module& pModule) const;
616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emitSectionHeader - emit ElfXX_Shdr
636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitSectionHeader(const Module& pModule,
656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                         const LinkerConfig& pConfig,
6687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                         FileOutputBuffer& pOutput) const;
676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emitProgramHeader - emit ElfXX_Phdr
696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
7087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void emitProgramHeader(FileOutputBuffer& pOutput) const;
716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emitShStrTab - emit .shstrtab
736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitShStrTab(const LDSection& pShStrTab,
746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                    const Module& pModule,
7587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                    FileOutputBuffer& pOutput);
7687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
7787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void emitSectionData(const LDSection& pSection, MemoryRegion& pRegion) const;
786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void emitEhFrame(Module& pModule,
8087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                   EhFrame& pFrame, MemoryRegion& pRegion) const;
816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitRelocation(const LinkerConfig& pConfig,
836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      const LDSection& pSection,
846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      MemoryRegion& pRegion) const;
856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emitRel - emit ElfXX_Rel
876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitRel(const LinkerConfig& pConfig,
896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines               const RelocData& pRelocData,
906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines               MemoryRegion& pRegion) const;
916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emitRela - emit ElfXX_Rela
936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitRela(const LinkerConfig& pConfig,
956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                const RelocData& pRelocData,
966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                MemoryRegion& pRegion) const;
976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // getSectEntrySize - compute ElfXX_Shdr::sh_entsize
996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
1006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t getSectEntrySize(const LDSection& pSection) const;
1016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // getSectLink - compute ElfXX_Shdr::sh_link
1036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t getSectLink(const LDSection& pSection,
1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                       const LinkerConfig& pConfig) const;
1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // getSectInfo - compute ElfXX_Shdr::sh_info
1076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t getSectInfo(const LDSection& pSection) const;
1086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
1106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t getLastStartOffset(const Module& pModule) const
1116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  {
1126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    assert(0 && "Call invalid ELFObjectWriter::getLastStartOffset");
1136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return 0;
1146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
1156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitSectionData(const SectionData& pSD, MemoryRegion& pRegion) const;
1176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesprivate:
1196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  GNULDBackend& m_Backend;
1206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
121d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  const LinkerConfig& m_Config;
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<>
1256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFObjectWriter::getLastStartOffset<32>(const Module& pModule) const;
1266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<>
1286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFObjectWriter::getLastStartOffset<64>(const Module& pModule) const;
1296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
133affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
134