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 MAPLEBE_INCLUDE_CG_IFILE_H 17 #define MAPLEBE_INCLUDE_CG_IFILE_H 18 19 #include <fstream> 20 #include <sstream> 21 #include "elf_types.h" 22 #include "types_def.h" 23 #include "common_utils.h" 24 #include "mempool.h" 25 #include "mempool_allocator.h" 26 #include "maple_string.h" 27 #include "mir_symbol.h" 28 #include "cg.h" 29 30 namespace maplebe { 31 class ObjEmitter; 32 class Fixup; 33 34 class Alignment { 35 public: 36 template <typename T> Align(T offset,T align)37 static T Align(T offset, T align) 38 { 39 if (align <= 1) { 40 return offset; 41 } 42 return (offset + align - 1) & (~(align - 1)); 43 } 44 }; /* class Alignment */ 45 46 struct ObjLabel { 47 Offset offset; 48 size_t size; 49 }; 50 51 enum LabelFixupKind : uint8 { 52 kLabelFixupDirect, 53 kLabelFixupInDirect, 54 kLabelFixupInDirectAdd, 55 kLabelFixupSize, 56 kLabelFixupDirect64, 57 kLabelFixupInDirect64, 58 kLabelFixupInDirectAdd64, 59 kLabelFixupSize64, 60 kLabelFixupGctib, 61 }; 62 63 enum IFileClassStatus : uint32 { kIFileClassResolved, kIFileClassUnresolved, kIFileClassUnknown }; 64 65 class LabelFixup { 66 public: LabelFixup(const std::string & label,uint32 offset,LabelFixupKind kind)67 LabelFixup(const std::string &label, uint32 offset, LabelFixupKind kind) : label(label), offset(offset), kind(kind) 68 { 69 } 70 ~LabelFixup() = default; 71 GetLabel()72 const std::string GetLabel() const 73 { 74 return label; 75 } 76 GetOffset()77 uint32 GetOffset() const 78 { 79 return offset; 80 } 81 GetFixupKind()82 LabelFixupKind GetFixupKind() const 83 { 84 return kind; 85 } 86 87 private: 88 std::string label; 89 uint32 offset; 90 LabelFixupKind kind; 91 }; 92 93 using Label2OffsetMap = std::unordered_map<std::string, ObjLabel>; 94 using LabelFixupVec = MapleVector<LabelFixup *>; 95 96 struct SectionDesc { 97 uint32 sectionOffset = 0; 98 uint32 sectionSize = 0; 99 }; 100 101 class Section { 102 public: 103 Section(std::string name, Word type, Word flags, uint32 align, ObjEmitter &emitter, MemPool &memPool); 104 105 virtual ~Section() = default; 106 virtual void GenerateData() = 0; 107 virtual void WriteSection(std::ostringstream &outStream) = 0; ClearData()108 virtual void ClearData() 109 { 110 return; 111 } 112 HandleGlobalFixup(const Label2OffsetMap & globalLabel2Offset)113 virtual void HandleGlobalFixup(const Label2OffsetMap &globalLabel2Offset) 114 { 115 (void)globalLabel2Offset; 116 return; 117 } 118 HandleLocalFixup()119 virtual void HandleLocalFixup() {} 120 121 virtual void Layout(); 122 SetIndex(uint32 idx)123 void SetIndex(uint32 idx) 124 { 125 index = idx; 126 } 127 SetInfo(uint32 value)128 void SetInfo(uint32 value) 129 { 130 secHeader.sh_info = value; 131 } 132 SetLink(const Section & section)133 void SetLink(const Section §ion) 134 { 135 secHeader.sh_link = section.GetIndex(); 136 } 137 SetEntSize(uint32 value)138 void SetEntSize(uint32 value) 139 { 140 secHeader.sh_entsize = value; 141 } 142 SetDataSize(Word size)143 void SetDataSize(Word size) 144 { 145 secHeader.sh_size = size; 146 } 147 GetDataSize()148 virtual uint32 GetDataSize() 149 { 150 return secHeader.sh_size; 151 } 152 SetAddr(Address addr)153 void SetAddr(Address addr) 154 { 155 secHeader.sh_addr = addr; 156 } 157 GetAddr()158 Address GetAddr() const 159 { 160 return secHeader.sh_addr; 161 } 162 GetFlags()163 Word GetFlags() const 164 { 165 return secHeader.sh_flags; 166 } 167 SetOffset(Offset value)168 void SetOffset(Offset value) 169 { 170 secHeader.sh_offset = value; 171 } 172 GetOffset()173 Offset GetOffset() const 174 { 175 return secHeader.sh_offset; 176 } 177 GetIndex()178 SectionIndex GetIndex() const 179 { 180 return index; 181 } 182 GetAlign()183 Word GetAlign() const 184 { 185 return secHeader.sh_addralign; 186 } 187 GetName()188 const MapleString &GetName() const 189 { 190 return name; 191 } 192 SetSectionHeaderNameIndex(size_t index)193 void SetSectionHeaderNameIndex(size_t index) 194 { 195 secHeader.sh_name = index; 196 } 197 GetType()198 Word GetType() const 199 { 200 return secHeader.sh_type; 201 } 202 GetSectionHeader()203 const SectionHeader &GetSectionHeader() const 204 { 205 return secHeader; 206 } 207 208 protected: 209 ObjEmitter &emitter; 210 211 private: 212 MapleString name; 213 SectionIndex index {}; 214 SectionHeader secHeader {}; 215 }; 216 217 class DataSection : public Section { 218 public: DataSection(const std::string & name,Word type,Word flags,Word align,ObjEmitter & emitter,MemPool & inputMemPool)219 DataSection(const std::string &name, Word type, Word flags, Word align, ObjEmitter &emitter, MemPool &inputMemPool) 220 : Section(name, type, flags, align, emitter, inputMemPool), 221 memPool(inputMemPool), 222 alloc(&memPool), 223 data(alloc.Adapter()) 224 { 225 } 226 227 ~DataSection() = default; 228 GenerateData()229 virtual void GenerateData() override 230 { 231 SetDataSize(data.size()); 232 if (GetName() == ".ifile.hex") { 233 SetDataSize(k8BitSize); 234 } 235 } 236 ClearData()237 virtual void ClearData() override 238 { 239 data.clear(); 240 } 241 HandleGlobalFixup(const Label2OffsetMap & globalLabel2Offset)242 virtual void HandleGlobalFixup(const Label2OffsetMap &globalLabel2Offset) override 243 { 244 (void)globalLabel2Offset; 245 return; 246 } 247 WriteSection(std::ostringstream & outStream)248 virtual void WriteSection(std::ostringstream &outStream) override 249 { 250 outStream.write(reinterpret_cast<const char *>(data.data()), data.size()); 251 } 252 AppendData(const void * value,size_t size)253 void AppendData(const void *value, size_t size) 254 { 255 auto pdata = reinterpret_cast<const uint8 *>(value); 256 data.insert(data.end(), pdata, pdata + size); 257 } 258 AppendData(MapleVector<uint8> value)259 void AppendData(MapleVector<uint8> value) 260 { 261 data.insert(data.end(), value.begin(), value.end()); 262 } 263 GetDataSize()264 uint32 GetDataSize() override 265 { 266 return data.size(); 267 } 268 FillPadding(uint32 paddingNum)269 void FillPadding(uint32 paddingNum) 270 { 271 if (paddingNum == 0) { 272 return; 273 } 274 std::vector<uint8> paddingData(paddingNum, 0); 275 auto pdata = reinterpret_cast<const uint8 *>(paddingData.data()); 276 data.insert(data.end(), pdata, pdata + paddingNum); 277 } 278 GetDataElem32(size_t index)279 uint32 GetDataElem32(size_t index) 280 { 281 uint32 value = 0; 282 errno_t res = memcpy_s(&value, sizeof(uint32), data.data() + index, sizeof(uint32)); 283 CHECK_FATAL(res == EOK, "call memcpy_s failed"); 284 return value; 285 } 286 GetDataElem64(size_t index)287 uint64 GetDataElem64(size_t index) 288 { 289 uint64 value = 0; 290 errno_t res = memcpy_s(&value, sizeof(uint64), data.data() + index, sizeof(uint64)); 291 CHECK_FATAL(res == EOK, "call memcpy_s failed"); 292 return value; 293 } 294 GetData()295 const MapleVector<uint8> &GetData() const 296 { 297 return data; 298 } 299 Swap(const void * value,size_t index,size_t size)300 void Swap(const void *value, size_t index, size_t size) 301 { 302 errno_t res = memcpy_s(data.data() + index, size, value, size); 303 CHECK_FATAL(res == EOK, "call memcpy_s failed"); 304 } 305 AddLabel2Offset(Label2OffsetMap & label2Offsets,const std::string & name,ObjLabel & objLabel)306 static void AddLabel2Offset(Label2OffsetMap &label2Offsets, const std::string &name, ObjLabel &objLabel) 307 { 308 label2Offsets.insert(std::make_pair(name, objLabel)); 309 } 310 AddLabelFixup(LabelFixupVec & labelFixups,LabelFixup & labelFixup)311 static void AddLabelFixup(LabelFixupVec &labelFixups, LabelFixup &labelFixup) 312 { 313 labelFixups.emplace_back(&labelFixup); 314 } 315 316 protected: 317 MemPool &memPool; 318 MapleAllocator alloc; 319 MapleVector<uint8> data; 320 }; 321 322 struct MethodHeader { 323 uint32 methodMetaOffset = 0; 324 uint16 localRefOffset = 0; 325 uint16 localRefNumber = 0; 326 uint32 codeInfoOffset = 0; 327 uint32 codeSize = 0; 328 }; 329 330 class StringSection : public DataSection { 331 public: StringSection(const std::string & name,Word type,Word flags,Word align,ObjEmitter & emitter,MemPool & memPool)332 StringSection(const std::string &name, Word type, Word flags, Word align, ObjEmitter &emitter, MemPool &memPool) 333 : DataSection(name, type, flags, align, emitter, memPool) 334 { 335 AddString("\0"); 336 } 337 338 ~StringSection() = default; 339 AddString(const std::string & str)340 size_t AddString(const std::string &str) 341 { 342 size_t pos = data.size(); 343 AppendData(str.c_str(), str.size() + 1); 344 return pos; 345 } 346 AddString(const MapleString & str)347 size_t AddString(const MapleString &str) 348 { 349 size_t pos = data.size(); 350 AppendData(str.c_str(), str.length() + 1); 351 return pos; 352 } 353 }; 354 355 class SymbolSection : public Section { 356 public: SymbolSection(const std::string & name,Word type,Word flags,Word align,ObjEmitter & emitter,MemPool & memPool,const Section & link)357 SymbolSection(const std::string &name, Word type, Word flags, Word align, ObjEmitter &emitter, MemPool &memPool, 358 const Section &link) 359 : Section(name, type, flags, align, emitter, memPool), alloc(&memPool), symbols(alloc.Adapter()) 360 { 361 SetEntSize(sizeof(Symbol)); 362 SetLink(link); 363 SetInfo(1); 364 AppendSymbol({0, 0, 0, 0, 0, 0}); 365 } 366 367 ~SymbolSection() = default; 368 GenerateData()369 void GenerateData() override 370 { 371 SetDataSize(symbols.size() * sizeof(Symbol)); 372 } 373 WriteSection(std::ostringstream & outStream)374 void WriteSection(std::ostringstream &outStream) override 375 { 376 outStream.write(reinterpret_cast<const char *>(symbols.data()), symbols.size() * sizeof(Symbol)); 377 } 378 AppendSymbol(Symbol symbol)379 void AppendSymbol(Symbol symbol) 380 { 381 symbols.push_back(symbol); 382 } 383 GetSymbolsSize()384 uint32 GetSymbolsSize() const 385 { 386 return symbols.size(); 387 } 388 GetIdxInSymbols(int64 symIdx)389 uint64 GetIdxInSymbols(int64 symIdx) const 390 { 391 return symbolIdxMap.at(symIdx); 392 } 393 AppendIdxInSymbols(int64 symIdx)394 void AppendIdxInSymbols(int64 symIdx) 395 { 396 CHECK_FATAL(GetSymbolsSize() > 0, "must not be zero"); 397 symbolIdxMap[symIdx] = static_cast<uint64>(GetSymbolsSize() - 1); 398 } 399 ExistSymInSymbols(int64 symIdx)400 bool ExistSymInSymbols(int64 symIdx) 401 { 402 return symbolIdxMap.count(symIdx) != 0; 403 } 404 GetAddr()405 const char *GetAddr() 406 { 407 return reinterpret_cast<const char*>(symbols.data()); 408 } 409 private: 410 MapleAllocator alloc; 411 MapleVector<Symbol> symbols; 412 std::unordered_map<int64, uint64> symbolIdxMap; 413 }; 414 415 class RelaSection : public Section { 416 public: RelaSection(const std::string & name,Word type,Word flags,Word info,Word align,const Section & link,ObjEmitter & emitter,MemPool & memPool)417 RelaSection(const std::string &name, Word type, Word flags, Word info, Word align, const Section &link, 418 ObjEmitter &emitter, MemPool &memPool) 419 : Section(name, type, flags, align, emitter, memPool), alloc(&memPool), relas(alloc.Adapter()) 420 { 421 SetEntSize(sizeof(Rela)); 422 SetInfo(info); 423 SetLink(link); 424 } 425 426 ~RelaSection() = default; 427 GenerateData()428 void GenerateData() override 429 { 430 SetDataSize(relas.size() * sizeof(Rela)); 431 } 432 WriteSection(std::ostringstream & outStream)433 void WriteSection(std::ostringstream &outStream) override 434 { 435 outStream.write(reinterpret_cast<const char *>(relas.data()), relas.size() * sizeof(Rela)); 436 } 437 AppendRela(Rela rela)438 void AppendRela(Rela rela) 439 { 440 relas.push_back(rela); 441 } 442 443 private: 444 MapleAllocator alloc; 445 MapleVector<Rela> relas; 446 }; /* class RelaSection */ 447 448 struct EmitInfo { 449 MIRConst &elemConst; 450 Offset &offset; 451 Label2OffsetMap &label2Offsets; 452 LabelFixupVec &labelFixups; 453 }; 454 } /* namespace maplebe */ 455 456 #endif /* MAPLEBE_INCLUDE_CG_IFILE_H */ 457