1 /* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef X64_ASSEMBLER_ELF_FILE_H 17 #define X64_ASSEMBLER_ELF_FILE_H 18 19 #include <vector> 20 #include "elf_types.h" 21 #include "operand.h" 22 23 namespace assembler { 24 using namespace maplebe; 25 26 class Alignment { 27 public: 28 template <typename T> Align(T offset,T align)29 static T Align(T offset, T align) 30 { 31 if (align <= 1) { 32 return offset; 33 } 34 return (offset + align - 1) & (~(align - 1)); 35 } 36 }; /* class Alignment */ 37 38 class Section { 39 public: Section(const std::string & name,Word type,Xword flags,Xword align)40 Section(const std::string &name, Word type, Xword flags, Xword align) : name(name) 41 { 42 sectionHeader.sh_type = type; 43 sectionHeader.sh_flags = flags; 44 sectionHeader.sh_addralign = align; 45 } 46 47 virtual ~Section() = default; 48 virtual void GenerateData() = 0; 49 virtual void WriteSection(std::ofstream &outStream) = 0; 50 ClearData()51 virtual void ClearData() 52 { 53 return; 54 } 55 SetIndex(SectionIndex idx)56 void SetIndex(SectionIndex idx) 57 { 58 index = idx; 59 } 60 GetIndex()61 SectionIndex GetIndex() const 62 { 63 return index; 64 } 65 SetInfo(Word value)66 void SetInfo(Word value) 67 { 68 sectionHeader.sh_info = value; 69 } 70 SetLink(const Section & section)71 void SetLink(const Section §ion) 72 { 73 sectionHeader.sh_link = static_cast<Word>(section.GetIndex()); 74 } 75 SetEntSize(Xword value)76 void SetEntSize(Xword value) 77 { 78 sectionHeader.sh_entsize = value; 79 } 80 SetSectionSize(Xword size)81 void SetSectionSize(Xword size) 82 { 83 sectionHeader.sh_size = size; 84 } 85 GetSectionSize()86 virtual Xword GetSectionSize() 87 { 88 return sectionHeader.sh_size; 89 } 90 SetAddr(Address addr)91 void SetAddr(Address addr) 92 { 93 sectionHeader.sh_addr = addr; 94 } 95 GetAddr()96 Address GetAddr() const 97 { 98 return sectionHeader.sh_addr; 99 } 100 GetFlags()101 Xword GetFlags() const 102 { 103 return sectionHeader.sh_flags; 104 } 105 SetOffset(Offset value)106 void SetOffset(Offset value) 107 { 108 sectionHeader.sh_offset = value; 109 } 110 GetOffset()111 Offset GetOffset() const 112 { 113 return sectionHeader.sh_offset; 114 } 115 GetAlign()116 Xword GetAlign() const 117 { 118 return sectionHeader.sh_addralign; 119 } 120 GetName()121 const std::string &GetName() const 122 { 123 return name; 124 } 125 SetSectionHeaderNameIndex(Word index)126 void SetSectionHeaderNameIndex(Word index) 127 { 128 sectionHeader.sh_name = index; 129 } 130 GetType()131 Word GetType() const 132 { 133 return sectionHeader.sh_type; 134 } 135 GetSectionHeader()136 const SectionHeader &GetSectionHeader() const 137 { 138 return sectionHeader; 139 } 140 141 private: 142 std::string name; 143 SectionIndex index {}; 144 SectionHeader sectionHeader {}; 145 }; /* class Section */ 146 147 class DataSection : public Section { 148 public: DataSection(const std::string & name,Word type,Xword flags,Xword align)149 DataSection(const std::string &name, Word type, Xword flags, Xword align) : Section(name, type, flags, align) {} 150 151 ~DataSection() = default; 152 GenerateData()153 virtual void GenerateData() override 154 { 155 SetSectionSize(data.size()); 156 } 157 WriteSection(std::ofstream & outStream)158 virtual void WriteSection(std::ofstream &outStream) override 159 { 160 outStream.write(reinterpret_cast<const char *>(data.data()), data.size()); 161 } 162 AppendData(const void * value,size_t size)163 void AppendData(const void *value, size_t size) 164 { 165 auto pdata = reinterpret_cast<const uint8 *>(value); 166 data.insert(data.end(), pdata, pdata + size); 167 } 168 AppendData(int64 value,size_t size)169 void AppendData(int64 value, size_t size) 170 { 171 for (size_t i = 0; i < size; i++) { 172 auto pdata = static_cast<uint8>(static_cast<uint64>(value) >> (i * k8Bits)); 173 data.push_back(pdata); 174 } 175 } 176 ClearData()177 void ClearData() override 178 { 179 data.clear(); 180 } 181 GetDataSize()182 uint32 GetDataSize() const 183 { 184 return data.size(); 185 } 186 GetData()187 const std::vector<uint8> &GetData() const 188 { 189 return data; 190 } 191 192 protected: 193 std::vector<uint8> data; 194 }; /* class DataSection */ 195 196 class StringSection : public DataSection { 197 public: StringSection(const std::string & name,Word type,Xword flags,Xword align)198 StringSection(const std::string &name, Word type, Xword flags, Xword align) : DataSection(name, type, flags, align) 199 { 200 AddString("\0"); 201 } 202 203 ~StringSection() = default; 204 AddString(const std::string & str)205 size_t AddString(const std::string &str) 206 { 207 size_t pos = data.size(); 208 AppendData(str.c_str(), str.size() + 1); 209 return pos; 210 } 211 }; /* class StringSection */ 212 213 class RelaSection : public Section { 214 public: RelaSection(const std::string & name,Word type,Xword flags,Word info,Xword align,const Section & link)215 RelaSection(const std::string &name, Word type, Xword flags, Word info, Xword align, const Section &link) 216 : Section(name, type, flags, align) 217 { 218 SetEntSize(sizeof(Rela)); 219 SetInfo(info); 220 SetLink(link); 221 } 222 223 ~RelaSection() = default; 224 GenerateData()225 void GenerateData() override 226 { 227 SetSectionSize(relas.size() * sizeof(Rela)); 228 } 229 WriteSection(std::ofstream & outStream)230 void WriteSection(std::ofstream &outStream) override 231 { 232 outStream.write(reinterpret_cast<const char *>(relas.data()), relas.size() * sizeof(Rela)); 233 } 234 AppendRela(Rela rela)235 void AppendRela(Rela rela) 236 { 237 relas.push_back(rela); 238 } 239 240 private: 241 std::vector<Rela> relas; 242 }; /* class RelaSection */ 243 244 class SymbolSection : public Section { 245 public: SymbolSection(const std::string & name,Word type,Xword flags,Xword align,const Section & link)246 SymbolSection(const std::string &name, Word type, Xword flags, Xword align, const Section &link) 247 : Section(name, type, flags, align) 248 { 249 SetEntSize(sizeof(Symbol)); 250 SetLink(link); 251 SetInfo(1); 252 AppendSymbol({0, 0, 0, 0, 0, 0}); 253 } 254 255 ~SymbolSection() = default; 256 GenerateData()257 void GenerateData() override 258 { 259 SetSectionSize(symbols.size() * sizeof(Symbol)); 260 } 261 WriteSection(std::ofstream & outStream)262 void WriteSection(std::ofstream &outStream) override 263 { 264 outStream.write(reinterpret_cast<const char *>(symbols.data()), symbols.size() * sizeof(Symbol)); 265 } 266 AppendSymbol(const Symbol & symbol)267 void AppendSymbol(const Symbol &symbol) 268 { 269 symbols.push_back(symbol); 270 } 271 GetSymbolsSize()272 uint32 GetSymbolsSize() const 273 { 274 return symbols.size(); 275 } 276 GetIdxInSymbols(int64 symIdx)277 uint64 GetIdxInSymbols(int64 symIdx) const 278 { 279 return symbolIdxMap.at(symIdx); 280 } 281 AppendIdxInSymbols(int64 symIdx)282 void AppendIdxInSymbols(int64 symIdx) 283 { 284 CHECK_FATAL(GetSymbolsSize() > 0, "must not be zero"); 285 symbolIdxMap[symIdx] = static_cast<uint64>(GetSymbolsSize() - 1); 286 } 287 ExistSymInSymbols(int64 symIdx)288 bool ExistSymInSymbols(int64 symIdx) 289 { 290 return symbolIdxMap.count(symIdx) != 0; 291 } 292 GetDataSize()293 uint32 GetDataSize() const 294 { 295 return symbols.size() * sizeof(Symbol); 296 } 297 GetAddr()298 const char *GetAddr() 299 { 300 return reinterpret_cast<const char*>(symbols.data()); 301 } 302 303 private: 304 std::vector<Symbol> symbols; 305 std::unordered_map<int64, uint64> symbolIdxMap; 306 }; /* class SymbolSection */ 307 } /* namespace assembler */ 308 309 #endif /* X64_ASSEMBLER_ELF_FILE_H */ 310