ELFObjectWriter.cpp revision d0fbbb227051be16931a1aa9b4a7722ac039c698
15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- ELFObjectWriter.cpp ------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ELFObjectWriter.h>
105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Module.h>
12d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LinkerConfig.h>
1322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Target/GNULDBackend.h>
1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MemoryArea.h>
1522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <llvm/Support/system_error.h>
17d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace llvm;
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// ELFObjectWriter
2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoELFObjectWriter::ELFObjectWriter(GNULDBackend& pBackend,
25d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                 const LinkerConfig& pConfig)
26d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  : ObjectWriter(pBackend), ELFWriter(pBackend),
27d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    m_Config(pConfig) {
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFObjectWriter::~ELFObjectWriter()
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaollvm::error_code ELFObjectWriter::writeObject(Module& pModule,
3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                              MemoryArea& pOutput)
3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // Write out name pool sections: .symtab, .strtab
3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  target().emitRegNamePools(pModule, pOutput);
3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // Write out regular ELF sections
4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::iterator sect, sectEnd = pModule.end();
4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (sect = pModule.begin(); sect != sectEnd; ++sect) {
4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    MemoryRegion* region = NULL;
4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // request output region
4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    switch((*sect)->kind()) {
46d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      case LDFileFormat::Note:
47d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        if ((*sect)->getSectionData() == NULL)
48d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao          continue;
49d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        // Fall through
5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Regular:
5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Relocation:
5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Target:
5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Debug:
5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::GCCExceptTable:
5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::EhFrame: {
5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        region = pOutput.request((*sect)->offset(), (*sect)->size());
5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (NULL == region) {
5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          llvm::report_fatal_error(llvm::Twine("cannot get enough memory region for output section `") +
5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                   llvm::Twine((*sect)->name()) +
6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                   llvm::Twine("'.\n"));
6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Null:
6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::NamePool:
6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::BSS:
6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::MetaData:
6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Version:
6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::EhFrameHdr:
7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::StackNote:
7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // ignore these sections
7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        continue;
7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      default: {
7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        llvm::errs() << "WARNING: unsupported section kind: "
7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     << (*sect)->kind()
7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     << " of section "
7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     << (*sect)->name()
7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     << ".\n";
7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        continue;
8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // write out sections with data
8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    switch((*sect)->kind()) {
8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Regular:
8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Debug:
8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::GCCExceptTable:
88d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      case LDFileFormat::Note:
8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::EhFrame: {
9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // FIXME: if optimization of exception handling sections is enabled,
9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // then we should emit these sections by the other way.
9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        emitSectionData(**sect, *region);
9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Relocation:
96d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        emitRelocation(m_Config, **sect, *region);
9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Target:
9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        target().emitSectionData(**sect, *region);
10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      default:
10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        continue;
10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  } // end of for loop
10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  emitELFShStrTab(target().getOutputFormat()->getShStrTab(),
10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                  pModule,
10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                  pOutput);
10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
110d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (m_Config.targets().is32Bits()) {
11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // Write out ELF header
11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // Write out section header table
113d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    writeELF32Header(m_Config,
11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     pModule,
11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     pOutput);
11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
117d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    emitELF32SectionHeader(pModule, m_Config, pOutput);
11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
119d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  else if (m_Config.targets().is64Bits()) {
12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // Write out ELF header
12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // Write out section header table
122d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    writeELF64Header(m_Config,
12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     pModule,
12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     pOutput);
12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
126d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    emitELF64SectionHeader(pModule, m_Config, pOutput);
12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else
12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return make_error_code(errc::not_supported);
13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pOutput.clear();
13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return llvm::make_error_code(llvm::errc::success);
13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
135