• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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