127 lines
3.9 KiB
C++
127 lines
3.9 KiB
C++
//===- 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
|