ELFObjectWriter.cpp revision 22add6ff3426df1a85089fe6a6e1597ee3b6f300
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>
1222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Target/GNULDBackend.h>
1322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Fragment/FragmentLinker.h>
1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MemoryArea.h>
1522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <llvm/Support/system_error.h>
1722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace llvm;
185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld;
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// ELFObjectWriter
2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoELFObjectWriter::ELFObjectWriter(GNULDBackend& pBackend,
2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                 FragmentLinker& pLinker)
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  : ObjectWriter(pBackend), ELFWriter(pBackend), m_Linker(pLinker) {
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFObjectWriter::~ELFObjectWriter()
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaollvm::error_code ELFObjectWriter::writeObject(Module& pModule,
3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                              MemoryArea& pOutput)
3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{
3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // Write out name pool sections: .symtab, .strtab
3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  target().emitRegNamePools(pModule, pOutput);
3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // Write out regular ELF sections
3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Module::iterator sect, sectEnd = pModule.end();
4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (sect = pModule.begin(); sect != sectEnd; ++sect) {
4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    MemoryRegion* region = NULL;
4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // request output region
4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    switch((*sect)->kind()) {
4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Regular:
4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Relocation:
4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Target:
4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Debug:
4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::GCCExceptTable:
4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::EhFrame: {
5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        region = pOutput.request((*sect)->offset(), (*sect)->size());
5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        if (NULL == region) {
5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao          llvm::report_fatal_error(llvm::Twine("cannot get enough memory region for output section `") +
5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                   llvm::Twine((*sect)->name()) +
5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                                   llvm::Twine("'.\n"));
5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        }
5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Null:
5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::NamePool:
6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::BSS:
6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Note:
6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::MetaData:
6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Version:
6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::EhFrameHdr:
6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::StackNote:
6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // ignore these sections
6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        continue;
6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      default: {
6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        llvm::errs() << "WARNING: unsupported section kind: "
7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     << (*sect)->kind()
7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     << " of section "
7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     << (*sect)->name()
7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     << ".\n";
7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        continue;
7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // write out sections with data
7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    switch((*sect)->kind()) {
8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Regular:
8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Debug:
8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::GCCExceptTable:
8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::EhFrame: {
8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // FIXME: if optimization of exception handling sections is enabled,
8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        // then we should emit these sections by the other way.
8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        emitSectionData(**sect, *region);
8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      }
8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Relocation:
9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        emitRelocation(m_Linker.getLDInfo(), **sect, *region);
9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      case LDFileFormat::Target:
9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        target().emitSectionData(**sect, *region);
9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        break;
9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      default:
9622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao        continue;
9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    }
9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  } // end of for loop
9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  emitELFShStrTab(target().getOutputFormat()->getShStrTab(),
10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                  pModule,
10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                  pOutput);
10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (32 == target().bitclass()) {
10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // Write out ELF header
10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // Write out section header table
10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    writeELF32Header(m_Linker.getLDInfo(),
10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     pModule,
10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     pOutput);
11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    emitELF32SectionHeader(pModule, m_Linker.getLDInfo(), pOutput);
11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else if (64 == target().bitclass()) {
11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // Write out ELF header
11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    // Write out section header table
11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    writeELF64Header(m_Linker.getLDInfo(),
11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     pModule,
11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                     pOutput);
11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    emitELF64SectionHeader(pModule, m_Linker.getLDInfo(), pOutput);
12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else
12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return make_error_code(errc::not_supported);
12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  pOutput.clear();
12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  return llvm::make_error_code(llvm::errc::success);
12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao}
1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
129