ELFObjectWriter.h revision 87f34658dec9097d987d254a990ea7f311bfc95f
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#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
1787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines#include <mcld/Support/FileOutputBuffer.h>
18d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <llvm/Support/system_error.h>
19d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaonamespace mcld {
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2287f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesclass EhFrame;
2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass Module;
24d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaoclass LinkerConfig;
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass GNULDBackend;
266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass FragmentLinker;
276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass Relocation;
286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass LDSection;
296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass SectionData;
306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass RelocData;
316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass Output;
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
4587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  llvm::error_code writeObject(Module& pModule, FileOutputBuffer& pOutput);
4687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
4787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  size_t getOutputSize(const Module& pModule) const;
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoprivate:
5087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void writeSection(Module& pModule,
5187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                    FileOutputBuffer& pOutput, LDSection *section);
526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  GNULDBackend&       target()        { return m_Backend; }
546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  const GNULDBackend& target() const  { return m_Backend; }
566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // writeELFHeader - emit ElfXX_Ehdr
586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void writeELFHeader(const LinkerConfig& pConfig,
606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      const Module& pModule,
6187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                      FileOutputBuffer& pOutput) const;
626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t getEntryPoint(const LinkerConfig& pConfig,
646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                         const Module& pModule) const;
656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emitSectionHeader - emit ElfXX_Shdr
676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitSectionHeader(const Module& pModule,
696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                         const LinkerConfig& pConfig,
7087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                         FileOutputBuffer& pOutput) const;
716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emitProgramHeader - emit ElfXX_Phdr
736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
7487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void emitProgramHeader(FileOutputBuffer& pOutput) const;
756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emitShStrTab - emit .shstrtab
776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitShStrTab(const LDSection& pShStrTab,
786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                    const Module& pModule,
7987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                    FileOutputBuffer& pOutput);
8087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
8187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void emitSectionData(const LDSection& pSection, MemoryRegion& pRegion) const;
826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
8387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  void emitEhFrame(Module& pModule,
8487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines                   EhFrame& pFrame, MemoryRegion& pRegion) const;
856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitRelocation(const LinkerConfig& pConfig,
876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      const LDSection& pSection,
886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      MemoryRegion& pRegion) const;
896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emitRel - emit ElfXX_Rel
916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitRel(const LinkerConfig& pConfig,
936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines               const RelocData& pRelocData,
946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines               MemoryRegion& pRegion) const;
956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // emitRela - emit ElfXX_Rela
976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitRela(const LinkerConfig& pConfig,
996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                const RelocData& pRelocData,
1006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                MemoryRegion& pRegion) const;
1016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // getSectEntrySize - compute ElfXX_Shdr::sh_entsize
1036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t getSectEntrySize(const LDSection& pSection) const;
1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // getSectLink - compute ElfXX_Shdr::sh_link
1076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t getSectLink(const LDSection& pSection,
1086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                       const LinkerConfig& pConfig) const;
1096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // getSectInfo - compute ElfXX_Shdr::sh_info
1116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t getSectInfo(const LDSection& pSection) const;
1126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  template<size_t SIZE>
1146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t getLastStartOffset(const Module& pModule) const
1156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  {
1166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    assert(0 && "Call invalid ELFObjectWriter::getLastStartOffset");
1176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    return 0;
1186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
1196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  void emitSectionData(const SectionData& pSD, MemoryRegion& pRegion) const;
1216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesprivate:
1236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  GNULDBackend& m_Backend;
1246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
125d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  const LinkerConfig& m_Config;
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<>
1296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFObjectWriter::getLastStartOffset<32>(const Module& pModule) const;
1306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<>
1326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFObjectWriter::getLastStartOffset<64>(const Module& pModule) const;
1336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#endif
137affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
138