ELFObjectWriter.cpp revision d0fbbb227051be16931a1aa9b4a7722ac039c698
1//===- ELFObjectWriter.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/ELFObjectWriter.h>
10
11#include <mcld/Module.h>
12#include <mcld/LinkerConfig.h>
13#include <mcld/Target/GNULDBackend.h>
14#include <mcld/Support/MemoryArea.h>
15
16#include <llvm/Support/system_error.h>
17
18using namespace llvm;
19using namespace mcld;
20
21//===----------------------------------------------------------------------===//
22// ELFObjectWriter
23//===----------------------------------------------------------------------===//
24ELFObjectWriter::ELFObjectWriter(GNULDBackend& pBackend,
25                                 const LinkerConfig& pConfig)
26  : ObjectWriter(pBackend), ELFWriter(pBackend),
27    m_Config(pConfig) {
28}
29
30ELFObjectWriter::~ELFObjectWriter()
31{
32}
33
34llvm::error_code ELFObjectWriter::writeObject(Module& pModule,
35                                              MemoryArea& pOutput)
36{
37  // Write out name pool sections: .symtab, .strtab
38  target().emitRegNamePools(pModule, pOutput);
39
40  // Write out regular ELF sections
41  Module::iterator sect, sectEnd = pModule.end();
42  for (sect = pModule.begin(); sect != sectEnd; ++sect) {
43    MemoryRegion* region = NULL;
44    // request output region
45    switch((*sect)->kind()) {
46      case LDFileFormat::Note:
47        if ((*sect)->getSectionData() == NULL)
48          continue;
49        // Fall through
50      case LDFileFormat::Regular:
51      case LDFileFormat::Relocation:
52      case LDFileFormat::Target:
53      case LDFileFormat::Debug:
54      case LDFileFormat::GCCExceptTable:
55      case LDFileFormat::EhFrame: {
56        region = pOutput.request((*sect)->offset(), (*sect)->size());
57        if (NULL == region) {
58          llvm::report_fatal_error(llvm::Twine("cannot get enough memory region for output section `") +
59                                   llvm::Twine((*sect)->name()) +
60                                   llvm::Twine("'.\n"));
61        }
62        break;
63      }
64      case LDFileFormat::Null:
65      case LDFileFormat::NamePool:
66      case LDFileFormat::BSS:
67      case LDFileFormat::MetaData:
68      case LDFileFormat::Version:
69      case LDFileFormat::EhFrameHdr:
70      case LDFileFormat::StackNote:
71        // ignore these sections
72        continue;
73      default: {
74        llvm::errs() << "WARNING: unsupported section kind: "
75                     << (*sect)->kind()
76                     << " of section "
77                     << (*sect)->name()
78                     << ".\n";
79        continue;
80      }
81    }
82
83    // write out sections with data
84    switch((*sect)->kind()) {
85      case LDFileFormat::Regular:
86      case LDFileFormat::Debug:
87      case LDFileFormat::GCCExceptTable:
88      case LDFileFormat::Note:
89      case LDFileFormat::EhFrame: {
90        // FIXME: if optimization of exception handling sections is enabled,
91        // then we should emit these sections by the other way.
92        emitSectionData(**sect, *region);
93        break;
94      }
95      case LDFileFormat::Relocation:
96        emitRelocation(m_Config, **sect, *region);
97        break;
98      case LDFileFormat::Target:
99        target().emitSectionData(**sect, *region);
100        break;
101      default:
102        continue;
103    }
104  } // end of for loop
105
106  emitELFShStrTab(target().getOutputFormat()->getShStrTab(),
107                  pModule,
108                  pOutput);
109
110  if (m_Config.targets().is32Bits()) {
111    // Write out ELF header
112    // Write out section header table
113    writeELF32Header(m_Config,
114                     pModule,
115                     pOutput);
116
117    emitELF32SectionHeader(pModule, m_Config, pOutput);
118  }
119  else if (m_Config.targets().is64Bits()) {
120    // Write out ELF header
121    // Write out section header table
122    writeELF64Header(m_Config,
123                     pModule,
124                     pOutput);
125
126    emitELF64SectionHeader(pModule, m_Config, pOutput);
127  }
128  else
129    return make_error_code(errc::not_supported);
130
131  pOutput.clear();
132  return llvm::make_error_code(llvm::errc::success);
133}
134
135