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