1 //===- ELFDynObjWriter.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/ELFDynObjWriter.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 // ELFDynObjWriter
ELFDynObjWriter(GNULDBackend & pBackend,MCLinker & pLinker)25 ELFDynObjWriter::ELFDynObjWriter(GNULDBackend& pBackend, MCLinker& pLinker)
26 : DynObjWriter(pBackend),
27 ELFWriter(pBackend),
28 m_Backend(pBackend),
29 m_Linker(pLinker) {
30
31 }
32
~ELFDynObjWriter()33 ELFDynObjWriter::~ELFDynObjWriter()
34 {
35 }
36
writeDynObj(Output & pOutput)37 llvm::error_code ELFDynObjWriter::writeDynObj(Output& pOutput)
38 {
39 // Write out name pool sections: .dynsym, .dynstr, .hash
40 target().emitDynNamePools(pOutput,
41 m_Linker.getOutputSymbols(),
42 m_Linker.getLayout(),
43 m_Linker.getLDInfo());
44
45 // Write out name pool sections: .symtab, .strtab
46 target().emitRegNamePools(pOutput,
47 m_Linker.getOutputSymbols(),
48 m_Linker.getLayout(),
49 m_Linker.getLDInfo());
50
51 // Write out regular ELF sections
52 unsigned int secIdx = 0;
53 unsigned int secEnd = pOutput.context()->numOfSections();
54 for (secIdx = 0; secIdx < secEnd; ++secIdx) {
55 LDSection* sect = pOutput.context()->getSection(secIdx);
56 MemoryRegion* region = NULL;
57 // request output region
58 switch(sect->kind()) {
59 case LDFileFormat::Regular:
60 case LDFileFormat::Relocation:
61 case LDFileFormat::Target:
62 case LDFileFormat::Debug:
63 case LDFileFormat::GCCExceptTable:
64 case LDFileFormat::EhFrame: {
65 region = pOutput.memArea()->request(sect->offset(), sect->size());
66 if (NULL == region) {
67 llvm::report_fatal_error(llvm::Twine("cannot get enough memory region for output section[") +
68 llvm::Twine(secIdx) +
69 llvm::Twine("] - `") +
70 sect->name() +
71 llvm::Twine("'.\n"));
72 }
73 break;
74 }
75 case LDFileFormat::Null:
76 case LDFileFormat::NamePool:
77 case LDFileFormat::BSS:
78 case LDFileFormat::Note:
79 case LDFileFormat::MetaData:
80 case LDFileFormat::Version:
81 case LDFileFormat::EhFrameHdr:
82 // ignore these sections
83 continue;
84 default: {
85 llvm::errs() << "WARNING: unsupported section kind: "
86 << sect->kind()
87 << " of section "
88 << sect->name()
89 << ".\n";
90 continue;
91 }
92 }
93
94 // write out sections with data
95 switch(sect->kind()) {
96 case LDFileFormat::Regular:
97 case LDFileFormat::Debug:
98 case LDFileFormat::GCCExceptTable:
99 case LDFileFormat::EhFrame: {
100 // FIXME: if optimization of exception handling sections is enabled,
101 // then we should emit these sections by the other way.
102 emitSectionData(m_Linker.getLayout(), *sect, *region);
103 break;
104 }
105 case LDFileFormat::Relocation:
106 emitRelocation(m_Linker.getLayout(), pOutput, *sect, *region);
107 break;
108 case LDFileFormat::Target:
109 target().emitSectionData(pOutput,
110 *sect,
111 m_Linker.getLDInfo(),
112 m_Linker.getLayout(),
113 *region);
114 break;
115 default:
116 continue;
117 }
118
119 } // end of for loop
120
121 if (32 == target().bitclass()) {
122 // Write out ELF header
123 // Write out section header table
124 emitELF32ShStrTab(pOutput, m_Linker);
125
126 writeELF32Header(m_Linker.getLDInfo(),
127 m_Linker.getLayout(),
128 target(),
129 pOutput);
130
131 emitELF32ProgramHeader(pOutput, target());
132
133 emitELF32SectionHeader(pOutput, m_Linker);
134 }
135 else if (64 == target().bitclass()) {
136 // Write out ELF header
137 // Write out section header table
138 emitELF64ShStrTab(pOutput, m_Linker);
139
140 writeELF64Header(m_Linker.getLDInfo(),
141 m_Linker.getLayout(),
142 target(),
143 pOutput);
144
145 emitELF64ProgramHeader(pOutput, target());
146
147 emitELF64SectionHeader(pOutput, m_Linker);
148 }
149 else
150 return make_error_code(errc::not_supported);
151 pOutput.memArea()->clear();
152 return llvm::make_error_code(llvm::errc::success);
153 }
154
155