| //===- ELFBinaryReader.cpp ------------------------------------------------===// |
| // |
| // The MCLinker Project |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| #include "mcld/LD/ELFBinaryReader.h" |
| |
| #include "mcld/IRBuilder.h" |
| #include "mcld/LinkerConfig.h" |
| #include "mcld/MC/Input.h" |
| #include "mcld/Support/MemoryArea.h" |
| |
| #include <llvm/Support/ELF.h> |
| |
| #include <cctype> |
| |
| namespace mcld { |
| |
| //===----------------------------------------------------------------------===// |
| // ELFBinaryReader |
| //===----------------------------------------------------------------------===// |
| /// constructor |
| ELFBinaryReader::ELFBinaryReader(IRBuilder& pBuilder, |
| const LinkerConfig& pConfig) |
| : m_Builder(pBuilder), m_Config(pConfig) { |
| } |
| |
| /// destructor |
| ELFBinaryReader::~ELFBinaryReader() { |
| } |
| |
| bool ELFBinaryReader::isMyFormat(Input& pInput, bool& pContinue) const { |
| pContinue = true; |
| return m_Config.options().isBinaryInput(); |
| } |
| |
| bool ELFBinaryReader::readBinary(Input& pInput) { |
| // section: NULL |
| m_Builder.CreateELFHeader( |
| pInput, "", LDFileFormat::Null, llvm::ELF::SHT_NULL, 0x0); |
| |
| // section: .data |
| LDSection* data_sect = |
| m_Builder.CreateELFHeader(pInput, |
| ".data", |
| LDFileFormat::DATA, |
| llvm::ELF::SHF_WRITE | llvm::ELF::SHF_ALLOC, |
| 0x1); |
| |
| SectionData* data = m_Builder.CreateSectionData(*data_sect); |
| size_t data_size = pInput.memArea()->size(); |
| Fragment* frag = m_Builder.CreateRegion(pInput, 0x0, data_size); |
| m_Builder.AppendFragment(*frag, *data); |
| |
| // section: .shstrtab |
| m_Builder.CreateELFHeader( |
| pInput, ".shstrtab", LDFileFormat::NamePool, llvm::ELF::SHT_STRTAB, 0x1); |
| |
| // section: .symtab |
| m_Builder.CreateELFHeader(pInput, |
| ".symtab", |
| LDFileFormat::NamePool, |
| llvm::ELF::SHT_SYMTAB, |
| m_Config.targets().bitclass() / 8); |
| |
| // symbol: .data |
| m_Builder.AddSymbol(pInput, |
| ".data", |
| ResolveInfo::Section, |
| ResolveInfo::Define, |
| ResolveInfo::Local, |
| 0x0, |
| 0x0, |
| data_sect); |
| |
| // Note: in Win32, the filename is wstring. Is it correct to convert |
| // filename to std::string? |
| std::string mangled_name = pInput.path().filename().native(); |
| for (std::string::iterator it = mangled_name.begin(), ie = mangled_name.end(); |
| it != ie; |
| ++it) { |
| if (isalnum(*it) == 0) |
| *it = '_'; |
| } |
| |
| // symbol: _start |
| m_Builder.AddSymbol(pInput, |
| "_binary_" + mangled_name + "_start", |
| ResolveInfo::NoType, |
| ResolveInfo::Define, |
| ResolveInfo::Global, |
| 0x0, |
| 0x0, |
| data_sect); |
| |
| // symbol: _end |
| m_Builder.AddSymbol(pInput, |
| "_binary_" + mangled_name + "_end", |
| ResolveInfo::NoType, |
| ResolveInfo::Define, |
| ResolveInfo::Global, |
| 0x0, |
| data_size, |
| data_sect); |
| |
| // symbol: _size |
| m_Builder.AddSymbol(pInput, |
| "_binary_" + mangled_name + "_size", |
| ResolveInfo::NoType, |
| ResolveInfo::Define, |
| ResolveInfo::Global, |
| 0x0, |
| data_size, |
| data_sect); |
| |
| // section: .strtab |
| m_Builder.CreateELFHeader( |
| pInput, ".strtab", LDFileFormat::NamePool, llvm::ELF::SHT_STRTAB, 0x1); |
| |
| return true; |
| } |
| |
| } // namespace mcld |