1d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//===- ELFBinaryReader.cpp ------------------------------------------------===//
2d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//
3d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//                     The MCLinker Project
4d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//
5d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao// This file is distributed under the University of Illinois Open Source
6d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao// License. See LICENSE.TXT for details.
7d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//
8d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFBinaryReader.h"
10d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/IRBuilder.h"
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerConfig.h"
1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/MC/Input.h"
1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MemoryArea.h"
15d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
16d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <llvm/Support/ELF.h>
17d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <cctype>
196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld {
21d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
22d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//===----------------------------------------------------------------------===//
23d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao// ELFBinaryReader
24d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//===----------------------------------------------------------------------===//
25d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// constructor
2687f34658dec9097d987d254a990ea7f311bfc95fStephen HinesELFBinaryReader::ELFBinaryReader(IRBuilder& pBuilder,
27d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                                 const LinkerConfig& pConfig)
2837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    : m_Builder(pBuilder), m_Config(pConfig) {
29d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
30d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
31d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao/// destructor
3237b74a387bb3993387029859c2d9d051c41c724eStephen HinesELFBinaryReader::~ELFBinaryReader() {
33d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
34d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
3537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ELFBinaryReader::isMyFormat(Input& pInput, bool& pContinue) const {
3687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  pContinue = true;
3787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return m_Config.options().isBinaryInput();
3887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
3987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
4037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ELFBinaryReader::readBinary(Input& pInput) {
41d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // section: NULL
4237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  m_Builder.CreateELFHeader(
4337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pInput, "", LDFileFormat::Null, llvm::ELF::SHT_NULL, 0x0);
44d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
45d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // section: .data
46d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  LDSection* data_sect =
4737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_Builder.CreateELFHeader(pInput,
4837b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                ".data",
4937b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                LDFileFormat::DATA,
5037b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC,
5137b74a387bb3993387029859c2d9d051c41c724eStephen Hines                                0x1);
52d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
53d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  SectionData* data = m_Builder.CreateSectionData(*data_sect);
5487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  size_t data_size = pInput.memArea()->size();
55d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  Fragment* frag = m_Builder.CreateRegion(pInput, 0x0, data_size);
56d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  m_Builder.AppendFragment(*frag, *data);
57d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
58d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // section: .shstrtab
5937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  m_Builder.CreateELFHeader(
6037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pInput, ".shstrtab", LDFileFormat::NamePool, llvm::ELF::SHT_STRTAB, 0x1);
61d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
62d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // section: .symtab
63d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  m_Builder.CreateELFHeader(pInput,
64d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                            ".symtab",
65d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                            LDFileFormat::NamePool,
66d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                            llvm::ELF::SHT_SYMTAB,
67d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                            m_Config.targets().bitclass() / 8);
68d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
69d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // symbol: .data
70d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  m_Builder.AddSymbol(pInput,
71d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      ".data",
72d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      ResolveInfo::Section,
73d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      ResolveInfo::Define,
74d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      ResolveInfo::Local,
75d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      0x0,
76d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      0x0,
77d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      data_sect);
78d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
79f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  // Note: in Win32, the filename is wstring. Is it correct to convert
80f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  // filename to std::string?
81f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines  std::string mangled_name = pInput.path().filename().native();
8237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  for (std::string::iterator it = mangled_name.begin(), ie = mangled_name.end();
8337b74a387bb3993387029859c2d9d051c41c724eStephen Hines       it != ie;
8437b74a387bb3993387029859c2d9d051c41c724eStephen Hines       ++it) {
856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (isalnum(*it) == 0)
866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      *it = '_';
876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
89d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // symbol: _start
90d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  m_Builder.AddSymbol(pInput,
916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      "_binary_" + mangled_name + "_start",
92d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      ResolveInfo::NoType,
93d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      ResolveInfo::Define,
94d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      ResolveInfo::Global,
95d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      0x0,
96d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      0x0,
97d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      data_sect);
98d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
99d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // symbol: _end
100d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  m_Builder.AddSymbol(pInput,
1016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      "_binary_" + mangled_name + "_end",
102d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      ResolveInfo::NoType,
103d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      ResolveInfo::Define,
104d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      ResolveInfo::Global,
105d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      0x0,
106d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      data_size,
107d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      data_sect);
108d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
109d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // symbol: _size
110d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  m_Builder.AddSymbol(pInput,
1116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                      "_binary_" + mangled_name + "_size",
112d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      ResolveInfo::NoType,
113d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      ResolveInfo::Define,
114d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      ResolveInfo::Global,
115d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      0x0,
116d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      data_size,
117d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao                      data_sect);
118d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
119d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  // section: .strtab
12037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  m_Builder.CreateELFHeader(
12137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      pInput, ".strtab", LDFileFormat::NamePool, llvm::ELF::SHT_STRTAB, 0x1);
122d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
123d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  return true;
124d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
12537b74a387bb3993387029859c2d9d051c41c724eStephen Hines
12637b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
127