Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(293)

Side by Side Diff: src/IceELFSection.cpp

Issue 678533005: Subzero: Add basic ELFObjectWriter (text section, symtab, strtab, headers) (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: minor cleanup Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceELFSection.h ('k') | src/IceELFStreamer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 //===- subzero/src/IceELFSection.cpp - Representation of ELF sections -----===//
2 //
3 // The Subzero Code Generator
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines how ELF sections are represented.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "IceDefs.h"
15 #include "IceELFSection.h"
16 #include "IceELFStreamer.h"
17
18 using namespace llvm::ELF;
19
20 namespace Ice {
21
22 // Text sections.
23
24 void ELFTextSection::appendData(ELFStreamer &Str,
25 const llvm::StringRef MoreData) {
26 Str.writeBytes(MoreData);
27 Header.sh_size += MoreData.size();
28 }
29
30 // Data sections.
31
32 void ELFDataSection::appendData(ELFStreamer &Str,
33 const llvm::StringRef MoreData) {
34 Str.writeBytes(MoreData);
35 Header.sh_size += MoreData.size();
36 }
37
38 // Relocation sections.
39
40 // Symbol tables.
41
42 void ELFSymbolTableSection::createDefinedSym(const IceString &Name,
43 uint8_t Type, uint8_t Binding,
44 ELFSection *Section,
45 RelocOffsetT Offset, SizeT Size) {
46 ELFSym NewSymbol = ELFSym();
47 NewSymbol.Sym.setBindingAndType(Binding, Type);
48 NewSymbol.Sym.st_value = Offset;
49 NewSymbol.Sym.st_size = Size;
50 NewSymbol.Number = ELFSym::UnknownNumber;
51 SymtabKey Key = {Name, Section};
52 bool Unique;
53 if (Type == STB_LOCAL)
54 Unique = LocalSymbols.insert(std::make_pair(Key, NewSymbol)).second;
55 else
56 Unique = GlobalSymbols.insert(std::make_pair(Key, NewSymbol)).second;
57 assert(Unique);
58 }
59
60 void ELFSymbolTableSection::noteUndefinedSym(const IceString &Name,
61 ELFSection *NullSection) {
62 ELFSym NewSymbol = ELFSym();
63 NewSymbol.Sym.setBindingAndType(STB_GLOBAL, STT_NOTYPE);
64 NewSymbol.Number = ELFSym::UnknownNumber;
65 SymtabKey Key = {Name, NullSection};
66 GlobalSymbols.insert(std::make_pair(Key, NewSymbol));
67 }
68
69 void ELFSymbolTableSection::updateIndices(const ELFStringTableSection *StrTab) {
70 SizeT SymNumber = 0;
71 for (auto &KeyValue : LocalSymbols) {
72 const IceString &Name = KeyValue.first.first;
73 ELFSection *Section = KeyValue.first.second;
74 Elf64_Sym &SymInfo = KeyValue.second.Sym;
75 if (!Name.empty())
76 SymInfo.st_name = StrTab->getIndex(Name);
77 SymInfo.st_shndx = Section->getNumber();
78 KeyValue.second.setNumber(SymNumber++);
79 }
80 for (auto &KeyValue : GlobalSymbols) {
81 const IceString &Name = KeyValue.first.first;
82 ELFSection *Section = KeyValue.first.second;
83 Elf64_Sym &SymInfo = KeyValue.second.Sym;
84 if (!Name.empty())
85 SymInfo.st_name = StrTab->getIndex(Name);
86 SymInfo.st_shndx = Section->getNumber();
87 KeyValue.second.setNumber(SymNumber++);
88 }
89 }
90
91 void ELFSymbolTableSection::writeData(ELFStreamer &Str, bool IsELF64) {
92 if (IsELF64) {
93 writeSymbolMap<true>(Str, LocalSymbols);
94 writeSymbolMap<true>(Str, GlobalSymbols);
95 } else {
96 writeSymbolMap<false>(Str, LocalSymbols);
97 writeSymbolMap<false>(Str, GlobalSymbols);
98 }
99 }
100
101 // String tables.
102
103 void ELFStringTableSection::add(const IceString &Str) {
104 assert(!isLaidOut());
105 assert(!Str.empty());
106 StringToIndexMap.insert(std::make_pair(Str, UnknownIndex));
107 }
108
109 size_t ELFStringTableSection::getIndex(const IceString &Str) const {
110 assert(isLaidOut());
111 StringToIndexType::const_iterator It = StringToIndexMap.find(Str);
112 if (It == StringToIndexMap.end()) {
113 llvm_unreachable("String index not found");
114 return UnknownIndex;
115 }
116 return It->second;
117 }
118
119 bool ELFStringTableSection::SuffixComparator::
120 operator()(const IceString &StrA, const IceString &StrB) const {
121 size_t LenA = StrA.size();
122 size_t LenB = StrB.size();
123 size_t CommonLen = std::min(LenA, LenB);
124 // If there is a difference in the common suffix, use that diff to sort.
125 for (size_t i = 0; i < CommonLen; ++i) {
126 char a = StrA[LenA - i - 1];
127 char b = StrB[LenB - i - 1];
128 if (a != b)
129 return a > b;
130 }
131 // If the common suffixes are completely equal, let the longer one come
132 // first, so that it can be laid out first and its characters shared.
133 return LenA > LenB;
134 }
135
136 void ELFStringTableSection::doLayout() {
137 assert(!isLaidOut());
138 llvm::StringRef Prev;
139
140 // String table starts with 0 byte.
141 StringData.push_back(0);
142
143 for (auto &StringIndex : StringToIndexMap) {
144 assert(StringIndex.second == UnknownIndex);
145 llvm::StringRef Cur = llvm::StringRef(StringIndex.first);
146 if (Prev.endswith(Cur)) {
147 // Prev is already in the StringData, and Cur is shorter than Prev
148 // based on the sort.
149 StringIndex.second = StringData.size() - Cur.size() - 1;
150 continue;
151 }
152 StringIndex.second = StringData.size();
153 std::copy(Cur.begin(), Cur.end(), back_inserter(StringData));
154 StringData.push_back(0);
155 Prev = Cur;
156 }
157 }
158
159 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceELFSection.h ('k') | src/IceELFStreamer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698