1affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===- ELFExecWriter.cpp --------------------------------------------------===//
2affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//
3affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//                     The MCLinker Project
4affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//
5affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// This file is distributed under the University of Illinois Open Source
6affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// License. See LICENSE.TXT for details.
7affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//
8affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//===----------------------------------------------------------------------===//
9affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/ELFExecWriter.h>
10affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/LDSymbol.h>
11affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Target/GNULDBackend.h>
12affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/MC/MCLDInput.h>
13affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/MC/MCLDOutput.h>
14affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/MC/MCLDInfo.h>
15affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/MC/MCLinker.h>
16affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <llvm/Support/ELF.h>
17affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <vector>
18affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
19affc150dc44fab1911775a49636d0ce85333b634Zonr Changusing namespace llvm;
20affc150dc44fab1911775a49636d0ce85333b634Zonr Changusing namespace mcld;
21affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
22affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
23affc150dc44fab1911775a49636d0ce85333b634Zonr Chang//==========================
24affc150dc44fab1911775a49636d0ce85333b634Zonr Chang// ELFExecWriter
25affc150dc44fab1911775a49636d0ce85333b634Zonr ChangELFExecWriter::ELFExecWriter(GNULDBackend& pBackend, MCLinker& pLinker)
26affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  : ExecWriter(pBackend),
27affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    ELFWriter(pBackend),
28affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_Backend(pBackend),
29affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    m_Linker(pLinker) {
30affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
31affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
32affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
33affc150dc44fab1911775a49636d0ce85333b634Zonr ChangELFExecWriter::~ELFExecWriter()
34affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
35affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
36affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
37affc150dc44fab1911775a49636d0ce85333b634Zonr Changllvm::error_code ELFExecWriter::writeExecutable(Output& pOutput)
38affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{
39affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // write out the interpreter section: .interp
40affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  target().emitInterp(pOutput, m_Linker.getLDInfo());
41affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
42affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Write out name pool sections: .dynsym, .dynstr, .hash
43affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  target().emitDynNamePools(pOutput,
44affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            m_Linker.getOutputSymbols(),
45affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            m_Linker.getLayout(),
46affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            m_Linker.getLDInfo());
47affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
48affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Write out name pool sections: .symtab, .strtab
49affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  target().emitRegNamePools(pOutput,
50affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            m_Linker.getOutputSymbols(),
51affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            m_Linker.getLayout(),
52affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                            m_Linker.getLDInfo());
53affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
54affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  // Write out regular ELF sections
55affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  unsigned int secIdx = 0;
56affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  unsigned int secEnd = pOutput.context()->numOfSections();
57affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  for (secIdx = 0; secIdx < secEnd; ++secIdx) {
58affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    LDSection* sect = pOutput.context()->getSection(secIdx);
59affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    MemoryRegion* region = NULL;
60affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // request output region
61affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    switch(sect->kind()) {
62affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::Regular:
63affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::Relocation:
64affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::Target:
65affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::Debug:
66affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::GCCExceptTable:
67affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::EhFrame: {
68affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        region = pOutput.memArea()->request(sect->offset(), sect->size());
69affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        if (NULL == region) {
70affc150dc44fab1911775a49636d0ce85333b634Zonr Chang          llvm::report_fatal_error(llvm::Twine("cannot get enough memory region for output section[") +
71affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   llvm::Twine(secIdx) +
72affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   llvm::Twine("] - `") +
73affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   sect->name() +
74affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                   llvm::Twine("'.\n"));
75affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        }
76affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        break;
77affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
78affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::Null:
79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::NamePool:
80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::BSS:
81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::Note:
82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::MetaData:
83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::Version:
84affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::EhFrameHdr:
85affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // ignore these sections
86affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        continue;
87affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      default: {
88affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        llvm::errs() << "WARNING: unsupported section kind: "
89affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     << sect->kind()
90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     << " of section "
91affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     << sect->name()
92affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     << ".\n";
93affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        continue;
94affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
95affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
96affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
97affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // write out sections with data
98affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    switch(sect->kind()) {
99affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::Regular:
100affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::Debug:
101affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::GCCExceptTable:
102affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::EhFrame: {
103affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // FIXME: if optimization of exception handling sections is enabled,
104affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        // then we should emit these sections by the other way.
105affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        emitSectionData(m_Linker.getLayout(), *sect, *region);
106affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        break;
107affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      }
108affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::Relocation:
109affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        emitRelocation(m_Linker.getLayout(), pOutput, *sect, *region);
110affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        break;
111affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      case LDFileFormat::Target:
112affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        target().emitSectionData(pOutput,
113affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                 *sect,
114affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                 m_Linker.getLDInfo(),
115affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                 m_Linker.getLayout(),
116affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                                 *region);
117affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        break;
118affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      default:
119affc150dc44fab1911775a49636d0ce85333b634Zonr Chang        continue;
120affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    }
121affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  } // end of for loop
122affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
123affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  if (32 == target().bitclass()) {
124affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // Write out ELF header
125affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // Write out section header table
126affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    emitELF32ShStrTab(pOutput, m_Linker);
127affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
128affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    writeELF32Header(m_Linker.getLDInfo(),
129affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     m_Linker.getLayout(),
130affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     target(),
131affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     pOutput);
132affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
133affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    emitELF32ProgramHeader(pOutput, target());
134affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
135affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    emitELF32SectionHeader(pOutput, m_Linker);
136affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
137affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else if (64 == target().bitclass()) {
138affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // Write out ELF header
139affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    // Write out section header table
140affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    emitELF64ShStrTab(pOutput, m_Linker);
141affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
142affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    writeELF64Header(m_Linker.getLDInfo(),
143affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     m_Linker.getLayout(),
144affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     target(),
145affc150dc44fab1911775a49636d0ce85333b634Zonr Chang                     pOutput);
146affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
147affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    emitELF64ProgramHeader(pOutput, target());
148affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
149affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    emitELF64SectionHeader(pOutput, m_Linker);
150affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
151affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  else
152affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    return make_error_code(errc::not_supported);
153affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
154affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  pOutput.memArea()->clear();
155affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  return llvm::make_error_code(llvm::errc::success);
156affc150dc44fab1911775a49636d0ce85333b634Zonr Chang}
157affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
158