| Index: src/IceELFSection.cpp
|
| diff --git a/src/IceELFSection.cpp b/src/IceELFSection.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f01793eecdca437527a82b890504ca3b83ada371
|
| --- /dev/null
|
| +++ b/src/IceELFSection.cpp
|
| @@ -0,0 +1,174 @@
|
| +//===- subzero/src/IceELFSection.cpp - Representation of ELF sections -----===//
|
| +//
|
| +// The Subzero Code Generator
|
| +//
|
| +// This file is distributed under the University of Illinois Open Source
|
| +// License. See LICENSE.TXT for details.
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +//
|
| +// This file defines how ELF sections are represented.
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| +
|
| +#include "IceDefs.h"
|
| +#include "IceELFSection.h"
|
| +#include "IceELFStreamer.h"
|
| +
|
| +using namespace llvm::ELF;
|
| +
|
| +namespace Ice {
|
| +
|
| +// The dummy NULL section will be assigned number 0, and it is referenced
|
| +// by the dummy 0-th symbol in the symbol table, so we can't use that.
|
| +const SizeT ELFSection::NoSectionNumber = std::numeric_limits<SizeT>::max();
|
| +
|
| +// Text sections.
|
| +
|
| +void ELFTextSection::appendData(ELFStreamer &Str,
|
| + const llvm::StringRef MoreData) {
|
| + Str.writeBytes(MoreData);
|
| + Header.sh_size += MoreData.size();
|
| +}
|
| +
|
| +// Data sections.
|
| +
|
| +void ELFDataSection::appendData(ELFStreamer &Str,
|
| + const llvm::StringRef MoreData) {
|
| + Str.writeBytes(MoreData);
|
| + Header.sh_size += MoreData.size();
|
| +}
|
| +
|
| +// Relocation sections.
|
| +
|
| +
|
| +
|
| +
|
| +// Symbol tables.
|
| +
|
| +// The dummy 0-th symbol will be assigned number 0, so don't use that.
|
| +const SizeT ELFSym::UnknownNumber = std::numeric_limits<SizeT>::max();
|
| +
|
| +void ELFSymbolTableSection::createDefinedSym(const IceString &Name,
|
| + uint8_t Type, uint8_t Binding,
|
| + ELFSection *Section,
|
| + RelocOffsetT Offset, SizeT Size) {
|
| + ELFSym NewSymbol = ELFSym();
|
| + NewSymbol.Sym.setBindingAndType(Binding, Type);
|
| + NewSymbol.Sym.st_value = Offset;
|
| + NewSymbol.Sym.st_size = Size;
|
| + NewSymbol.Number = ELFSym::UnknownNumber;
|
| + SymtabKey Key = {Name, Section};
|
| + bool Unique;
|
| + if (Type == STB_LOCAL)
|
| + Unique = LocalSymbols.insert(std::make_pair(Key, NewSymbol)).second;
|
| + else
|
| + Unique = GlobalSymbols.insert(std::make_pair(Key, NewSymbol)).second;
|
| + assert(Unique);
|
| +}
|
| +
|
| +void ELFSymbolTableSection::noteUndefinedSym(const IceString &Name,
|
| + ELFSection *NullSection) {
|
| + ELFSym NewSymbol = ELFSym();
|
| + NewSymbol.Sym.setBindingAndType(STB_GLOBAL, STT_NOTYPE);
|
| + NewSymbol.Number = ELFSym::UnknownNumber;
|
| + SymtabKey Key = {Name, NullSection};
|
| + GlobalSymbols.insert(std::make_pair(Key, NewSymbol));
|
| +}
|
| +
|
| +void ELFSymbolTableSection::updateIndices(
|
| + const ELFStringTableSection *StrTab) {
|
| + SizeT SymNumber = 0;
|
| + for (auto &KeyValue : LocalSymbols) {
|
| + const IceString &Name = KeyValue.first.first;
|
| + ELFSection *Section = KeyValue.first.second;
|
| + Elf64_Sym &SymInfo = KeyValue.second.Sym;
|
| + if (!Name.empty())
|
| + SymInfo.st_name = StrTab->getIndex(Name);
|
| + SymInfo.st_shndx = Section->getNumber();
|
| + KeyValue.second.setNumber(SymNumber++);
|
| + }
|
| + for (auto &KeyValue : GlobalSymbols) {
|
| + const IceString &Name = KeyValue.first.first;
|
| + ELFSection *Section = KeyValue.first.second;
|
| + Elf64_Sym &SymInfo = KeyValue.second.Sym;
|
| + if (!Name.empty())
|
| + SymInfo.st_name = StrTab->getIndex(Name);
|
| + SymInfo.st_shndx = Section->getNumber();
|
| + KeyValue.second.setNumber(SymNumber++);
|
| + }
|
| +}
|
| +
|
| +void ELFSymbolTableSection::writeData(ELFStreamer &Str, bool IsELF64) {
|
| + if (IsELF64) {
|
| + writeSymbolMap<true>(Str, LocalSymbols);
|
| + writeSymbolMap<true>(Str, GlobalSymbols);
|
| + } else {
|
| + writeSymbolMap<false>(Str, LocalSymbols);
|
| + writeSymbolMap<false>(Str, GlobalSymbols);
|
| + }
|
| +}
|
| +
|
| +// String tables.
|
| +
|
| +// The first byte of the string table should be \00, so it is an
|
| +// invalid index. Indices start out as unknown until layout is complete.
|
| +const size_t ELFStringTableSection::UnknownIndex = 0;
|
| +
|
| +void ELFStringTableSection::add(const IceString &Str) {
|
| + assert(!isLaidOut());
|
| + assert(!Str.empty());
|
| + StringToIndexMap.insert(std::make_pair(Str, UnknownIndex));
|
| +}
|
| +
|
| +size_t ELFStringTableSection::getIndex(const IceString &Str) const {
|
| + assert(isLaidOut());
|
| + StringToIndexType::const_iterator It = StringToIndexMap.find(Str);
|
| + if (It == StringToIndexMap.end()) {
|
| + llvm_unreachable("String index not found");
|
| + return UnknownIndex;
|
| + }
|
| + return It->second;
|
| +}
|
| +
|
| +bool ELFStringTableSection::SuffixComparator::
|
| +operator()(const IceString &StrA, const IceString &StrB) const {
|
| + size_t LenA = StrA.size();
|
| + size_t LenB = StrB.size();
|
| + size_t CommonLen = std::min(LenA, LenB);
|
| + // If there is a difference in the common suffix, use that diff to sort.
|
| + for (size_t i = 0; i < CommonLen; ++i) {
|
| + char a = StrA[LenA - i - 1];
|
| + char b = StrB[LenB - i - 1];
|
| + if (a != b)
|
| + return a > b;
|
| + }
|
| + // If the common suffixes are completely equal, let the longer one come
|
| + // first, so that it can be laid out first and its characters shared.
|
| + return LenA > LenB;
|
| +}
|
| +
|
| +void ELFStringTableSection::doLayout() {
|
| + assert(!isLaidOut());
|
| + llvm::StringRef Prev;
|
| +
|
| + // String table starts with 0 byte.
|
| + StringData.push_back(0);
|
| +
|
| + for (auto &StringIndex : StringToIndexMap) {
|
| + assert(StringIndex.second == UnknownIndex);
|
| + llvm::StringRef Cur = llvm::StringRef(StringIndex.first);
|
| + if (Prev.endswith(Cur)) {
|
| + // Prev is already in the StringData, and Cur is shorter than Prev
|
| + // based on the sort.
|
| + StringIndex.second = StringData.size() - Cur.size() - 1;
|
| + continue;
|
| + }
|
| + StringIndex.second = StringData.size();
|
| + std::copy(Cur.begin(), Cur.end(), back_inserter(StringData));
|
| + StringData.push_back(0);
|
| + Prev = Cur;
|
| + }
|
| +}
|
| +
|
| +} // end of namespace Ice
|
|
|