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