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