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 ELF_ASSEMBLER_H 17 #define ELF_ASSEMBLER_H 18 19 #include "assembler.h" 20 #include "elf_file.h" 21 #include "cg_option.h" 22 23 namespace assembler { 24 const uint8 kLeftShift6Bits = 6; 25 const uint8 kLeftShift3Bits = 3; 26 const uint8 kGetLow3Bits = 0b111; 27 const uint8 kLeftShift32Bits = 32; 28 const uint8 kLeftShift4Bits = 4; 29 30 class ElfAssembler : public Assembler { 31 public: ElfAssembler(const std::string & outputFileName)32 ElfAssembler(const std::string &outputFileName) : Assembler() 33 { 34 const auto &emitMemoryManager = maplebe::CGOptions::GetInstance().GetEmitMemoryManager(); 35 if (emitMemoryManager.codeSpace == nullptr) { 36 outStream.open(outputFileName, std::ios::trunc | std::ios::binary); 37 } 38 } 39 40 ~ElfAssembler() = default; 41 42 /* override function in base class */ 43 void InitialFileInfo(const std::string &inputFileName) override; 44 void EmitVariable(int64 symIdx, uint64 sizeInByte, uint8 alignInByte, SymbolAttr symAttr, 45 SectionKind sectionKind) override; 46 void EmitFunctionHeader(int64 symIdx, SymbolAttr funcAttr, const std::string *secName) override; 47 void EmitBBLabel(int64 labelSymIdx, bool genVerboseInfo, uint32 freq, const std::string *mirName) override; 48 void EmitJmpTableElem(int64 jmpLabelIdx, const std::vector<int64> &labelSymIdxs) override; 49 void EmitFunctionFoot(int64 symIdx, SymbolAttr funcAttr) override; 50 void EmitDirectString(const std::string &ustr, bool belongsToDataSec, int64 strSymIdx, bool emitAscii) override; 51 void EmitIndirectString(int64 strSymIdx, bool belongsToDataSec) override; 52 void EmitIntValue(int64 value, size_t valueSize, bool belongsToDataSec) override; 53 void EmitFloatValue(int64 symIdx, int64 value, size_t valueSize) override; 54 void EmitAddrValue(int64 symIdx, int32 symAddrOfs, int32 structFieldOfs, bool belongsToDataSec) override; 55 void EmitAddrOfFuncValue(int64 symIdx, bool belongsToDataSec) override; 56 void EmitLabelValue(int64 symIdx, bool belongsToDataSec) override; 57 void EmitBitFieldValue(uint64 combineBitFieldValue, bool belongsToDataSec) override; 58 void EmitNull(uint64 sizeInByte) override; 59 void PostEmitVariable(int64 symIdx, SymbolAttr symAttr, uint64 sizeInByte, bool belongsToTextSec) override; 60 void FinalizeFileInfo() override; 61 void EmitBssSectionVar(int64 symIdx, uint64 sizeInByte, uint8 alignInByte, SymbolAttr symAttr); 62 void EmitDataSectionVar(int64 symIdx); 63 64 /* emit debug info */ EmitDIHeader()65 void EmitDIHeader() override {}; EmitDIFooter()66 void EmitDIFooter() override {}; EmitDIHeaderFileInfo()67 void EmitDIHeaderFileInfo() override {}; 68 void EmitDIDebugInfoSectionHeader(uint64 debugInfoLength) override; 69 void EmitDIDebugInfoSectionAbbrevId(bool verbose, uint32 abbrevId, const std::string &dieTagName, uint32 offset, 70 uint32 size) override; 71 /* nothing to do in ElfAssembler. */ EmitDIFormSpecification(unsigned int dwform)72 void EmitDIFormSpecification(unsigned int dwform) override {}; 73 /* EmitDIAttrValue */ 74 void EmitDwFormString(const std::string &name) override; 75 void EmitDwFormStrp(uint32 strLabelId, size_t strTableSize) override; 76 void EmitDwFormData(int32 attrValue, uint8 sizeInByte) override; 77 void EmitDwFormData8() override; 78 void EmitDwFormData8(uint32 endLabelFuncPuIdx, uint32 startLabelFuncPuIdx, uint32 endLabelIdx, 79 uint32 startLabelIdx) override; 80 void EmitLabel(uint32 funcPuIdx, uint32 labIdx) override; 81 void EmitDwFormSecOffset() override; 82 void EmitDwFormAddr(bool emitTextBegin) override; 83 void EmitDwFormRef4(uint64 offsetOrValue, bool unknownType, bool emitOffset) override; 84 void EmitDwFormExprlocCfa(uint32 dwOp) override; 85 void EmitDwFormExprlocAddr(uint32 dwOp, const std::string &addrStr) override; 86 void EmitDwFormExprlocFbreg(uint32 dwOp, int fboffset, size_t sleb128Size) override; 87 void EmitDwFormExprlocBregn(uint32 dwOp, const std::string &dwOpName) override; /* n=0~7 */ 88 void EmitDwFormExprloc(uintptr elp) override; 89 EmitDIDwName(const std::string & dwAtName,const std::string & dwForName)90 void EmitDIDwName(const std::string &dwAtName, const std::string &dwForName) override {}; EmitDIDWFormStr(const std::string & formStr)91 void EmitDIDWFormStr(const std::string &formStr) override {}; EmitDIDWDataMemberLocaltion(unsigned int lableIdx,uintptr_t attr)92 void EmitDIDWDataMemberLocaltion(unsigned int lableIdx, uintptr_t attr) override {}; EmitDIDebugAbbrevSectionHeader()93 void EmitDIDebugAbbrevSectionHeader() override {}; 94 void EmitDIDebugAbbrevDiae(bool verbose, uint32 abbrevId, uint32 tag, const std::string &dwTagName, 95 bool withChildren) override; 96 void EmitDIDebugAbbrevDiaePairItem(bool verbose, uint32 aplAt, uint32 aplFrom, const std::string &dwAtName, 97 const std::string &dwFromName) override; 98 void EmitDIDebugSectionEnd(SectionKind secKind) override; EmitDIDebugARangesSection()99 void EmitDIDebugARangesSection() override 100 { 101 debugARangesSection = new DataSection(".debug_aranges", SHT_PROGBITS, 0, 1); 102 RegisterSection(*debugARangesSection); 103 } 104 EmitDIDebugRangesSection()105 void EmitDIDebugRangesSection() override 106 { 107 debugRangesSection = new DataSection(".debug_ranges", SHT_PROGBITS, 0, 1); 108 RegisterSection(*debugRangesSection); 109 } 110 EmitDIDebugLineSection()111 void EmitDIDebugLineSection() override {}; 112 void EmitDIDebugStrSection(const std::vector<uint32> &strps, const std::vector<std::string> &debugStrs, uint64 size, 113 size_t strTableSize) override; EmitLine()114 void EmitLine() override {}; 115 void HandleDebugInfoSectionFixup(); 116 EncodeULEB128(uint64 value)117 const std::vector<uint8> &EncodeULEB128(uint64 value) 118 { 119 static std::vector<uint8> uleb128Value; 120 if (value == 0) { 121 uleb128Value.push_back(0); 122 } 123 int rightShift7Bits = 7; 124 while (value != 0) { 125 uint8 byte = value & 0x7F; 126 value >>= rightShift7Bits; 127 byte = value != 0 ? byte |= 0x80 : byte; 128 uleb128Value.push_back(byte); 129 } 130 return uleb128Value; 131 } 132 EncodeSLEB128(int64 value)133 const std::vector<uint8> &EncodeSLEB128(int64 value) 134 { 135 static std::vector<uint8> sleb128Value; 136 int more = 1; 137 int rightShift7Bits = 7; 138 while (more != 0) { 139 uint8 byte = value & 0x7F; 140 uint8 sign = value & 0x40; 141 value >>= rightShift7Bits; 142 if ((value == 0 && sign == 0) || (value == -1 && sign != 0)) { 143 more = 0; 144 } else { 145 byte |= 0x80; 146 } 147 sleb128Value.push_back(byte); 148 } 149 return sleb128Value; 150 } 151 152 /* start of X64 instructions */ 153 /* mov */ 154 void Mov(InsnSize insnSize, Reg srcReg, Reg destReg) override; 155 void Mov(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg) override; 156 void Mov(InsnSize insnSize, const Mem &mem, Reg reg) override; 157 void Mov(InsnSize insnSize, Reg reg, const Mem &mem) override; 158 void Mov(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem) override; 159 /* floating point mov */ 160 void Mov(Reg srcReg, Reg destReg, bool isMovD) override; 161 void MovF(const Mem &mem, Reg reg, bool isSingle) override; 162 void MovF(Reg reg, const Mem &mem, bool isSingle) override; 163 /* movabs */ 164 void Movabs(const ImmOpnd &immOpnd, Reg reg) override; 165 void Movabs(int64 symIdx, Reg reg) override; 166 /* push */ 167 void Push(InsnSize insnSize, Reg reg) override; 168 /* pop */ 169 void Pop(InsnSize insnSize, Reg reg) override; 170 /* lea */ 171 void Lea(InsnSize insnSize, const Mem &mem, Reg reg) override; 172 /* movzx */ 173 void MovZx(InsnSize sSize, InsnSize dSize, Reg srcReg, Reg destReg) override; 174 void MovZx(InsnSize sSize, InsnSize dSize, const Mem &mem, Reg reg) override; 175 /* movsx */ 176 void MovSx(InsnSize sSize, InsnSize dSize, Reg srcReg, Reg destReg) override; 177 void MovSx(InsnSize sSize, InsnSize dSize, const Mem &mem, Reg reg) override; 178 /* add */ 179 void Add(InsnSize insnSize, Reg srcReg, Reg destReg) override; 180 void Add(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg) override; 181 void Add(InsnSize insnSize, const Mem &mem, Reg reg) override; 182 void Add(InsnSize insnSize, Reg reg, const Mem &mem) override; 183 void Add(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem) override; 184 /* add floating point */ 185 void Add(Reg srcReg, Reg destReg, bool isSingle) override; 186 void Add(const Mem &mem, Reg reg, bool isSingle) override; 187 /* sub */ 188 void Sub(InsnSize insnSize, Reg srcReg, Reg destReg) override; 189 void Sub(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg) override; 190 void Sub(InsnSize insnSize, const Mem &mem, Reg reg) override; 191 void Sub(InsnSize insnSize, Reg reg, const Mem &mem) override; 192 void Sub(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem) override; 193 /* sub floating point */ 194 void Sub(Reg srcReg, Reg destReg, bool isSingle) override; 195 void Sub(const Mem &mem, Reg reg, bool isSingle) override; 196 /* and */ 197 void And(InsnSize insnSize, Reg srcReg, Reg destReg) override; 198 void And(InsnSize insnSize, const Mem &mem, Reg reg) override; 199 void And(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg) override; 200 void And(InsnSize insnSize, Reg reg, const Mem &mem) override; 201 void And(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem) override; 202 /* or */ 203 void Or(InsnSize insnSize, Reg srcReg, Reg destReg) override; 204 void Or(InsnSize insnSize, const Mem &mem, Reg reg) override; 205 void Or(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg) override; 206 void Or(InsnSize insnSize, Reg reg, const Mem &mem) override; 207 void Or(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem) override; 208 /* xor */ 209 void Xor(InsnSize insnSize, Reg srcReg, Reg destReg) override; 210 void Xor(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg) override; 211 void Xor(InsnSize insnSize, const Mem &mem, Reg reg) override; 212 void Xor(InsnSize insnSize, Reg reg, const Mem &mem) override; 213 void Xor(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem) override; 214 /* not */ 215 void Not(InsnSize insnSize, Reg reg) override; 216 void Not(InsnSize insnSize, const Mem &mem) override; 217 /* neg */ 218 void Neg(InsnSize insnSize, Reg reg) override; 219 void Neg(InsnSize insnSize, const Mem &mem) override; 220 /* div & cwd, cdq, cqo */ 221 void Idiv(InsnSize insnSize, Reg reg) override; 222 void Idiv(InsnSize insnSize, const Mem &mem) override; 223 void Div(InsnSize insnSize, Reg reg) override; 224 void Div(InsnSize insnSize, const Mem &mem) override; 225 void Cwd() override; 226 void Cdq() override; 227 void Cqo() override; 228 /* shl */ 229 void Shl(InsnSize insnSize, Reg srcReg, Reg destReg) override; 230 void Shl(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg) override; 231 void Shl(InsnSize insnSize, Reg reg, const Mem &mem) override; 232 void Shl(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem) override; 233 /* sar */ 234 void Sar(InsnSize insnSize, Reg srcReg, Reg destReg) override; 235 void Sar(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg) override; 236 void Sar(InsnSize insnSize, Reg reg, const Mem &mem) override; 237 void Sar(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem) override; 238 /* shr */ 239 void Shr(InsnSize insnSize, Reg srcReg, Reg destReg) override; 240 void Shr(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg) override; 241 void Shr(InsnSize insnSize, Reg reg, const Mem &mem) override; 242 void Shr(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem) override; 243 /* jmp */ 244 void Jmp(Reg reg) override; 245 void Jmp(const Mem &mem) override; 246 void Jmp(int64 symIdx) override; 247 /* jump condition */ 248 void Je(int64 symIdx) override; 249 void Ja(int64 symIdx) override; 250 void Jae(int64 symIdx) override; 251 void Jne(int64 symIdx) override; 252 void Jb(int64 symIdx) override; 253 void Jbe(int64 symIdx) override; 254 void Jg(int64 symIdx) override; 255 void Jge(int64 symIdx) override; 256 void Jl(int64 symIdx) override; 257 void Jle(int64 symIdx) override; 258 /* cmp */ 259 void Cmp(InsnSize insnSize, Reg srcReg, Reg destReg) override; 260 void Cmp(InsnSize insnSize, const Mem &mem, Reg reg) override; 261 void Cmp(InsnSize insnSize, Reg reg, const Mem &mem) override; 262 void Cmp(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg) override; 263 void Cmp(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem) override; 264 /* test */ 265 void Test(InsnSize insnSize, Reg srcReg, Reg destReg) override; 266 /* set */ 267 void Setbe(Reg reg) override; 268 void Setbe(const Mem &mem) override; 269 void Setle(Reg reg) override; 270 void Setle(const Mem &mem) override; 271 void Setae(Reg reg) override; 272 void Setae(const Mem &mem) override; 273 void Setge(Reg reg) override; 274 void Setge(const Mem &mem) override; 275 void Setne(Reg reg) override; 276 void Setne(const Mem &mem) override; 277 void Setb(Reg reg) override; 278 void Setb(const Mem &mem) override; 279 void Setl(Reg reg) override; 280 void Setl(const Mem &mem) override; 281 void Seta(Reg reg) override; 282 void Seta(const Mem &mem) override; 283 void Setg(Reg reg) override; 284 void Setg(const Mem &mem) override; 285 void Sete(Reg reg) override; 286 void Sete(const Mem &mem) override; 287 void Seto(Reg reg) override; 288 void Seto(const Mem &mem) override; 289 /* cmov */ 290 void Cmova(InsnSize insnSize, Reg srcReg, Reg destReg) override; 291 void Cmova(InsnSize insnSize, const Mem &mem, Reg reg) override; 292 void Cmovae(InsnSize insnSize, Reg srcReg, Reg destReg) override; 293 void Cmovae(InsnSize insnSize, const Mem &mem, Reg reg) override; 294 void Cmovb(InsnSize insnSize, Reg srcReg, Reg destReg) override; 295 void Cmovb(InsnSize insnSize, const Mem &mem, Reg reg) override; 296 void Cmovbe(InsnSize insnSize, Reg srcReg, Reg destReg) override; 297 void Cmovbe(InsnSize insnSize, const Mem &mem, Reg reg) override; 298 void Cmove(InsnSize insnSize, Reg srcReg, Reg destReg) override; 299 void Cmove(InsnSize insnSize, const Mem &mem, Reg reg) override; 300 void Cmovg(InsnSize insnSize, Reg srcReg, Reg destReg) override; 301 void Cmovg(InsnSize insnSize, const Mem &mem, Reg reg) override; 302 void Cmovge(InsnSize insnSize, Reg srcReg, Reg destReg) override; 303 void Cmovge(InsnSize insnSize, const Mem &mem, Reg reg) override; 304 void Cmovl(InsnSize insnSize, Reg srcReg, Reg destReg) override; 305 void Cmovl(InsnSize insnSize, const Mem &mem, Reg reg) override; 306 void Cmovle(InsnSize insnSize, Reg srcReg, Reg destReg) override; 307 void Cmovle(InsnSize insnSize, const Mem &mem, Reg reg) override; 308 void Cmovne(InsnSize insnSize, Reg srcReg, Reg destReg) override; 309 void Cmovne(InsnSize insnSize, const Mem &mem, Reg reg) override; 310 void Cmovo(InsnSize insnSize, Reg srcReg, Reg destReg) override; 311 /* call */ 312 void Call(InsnSize insnSize, Reg reg) override; 313 void Call(InsnSize insnSize, const Mem &mem) override; 314 void Call(InsnSize insnSize, int64 symIdx) override; 315 /* ret */ 316 void Ret() override; 317 /* leave */ 318 void Leave() override; 319 /* imul */ 320 void Imul(InsnSize insnSize, Reg srcReg, Reg destReg) override; 321 /* mul float */ 322 void Mul(Reg srcReg, Reg destReg, bool isSingle) override; 323 void Mul(const Mem &mem, Reg reg, bool isSingle) override; 324 /* nop */ 325 void Nop(InsnSize insnSize, const Mem &mem) override; 326 void Nop() override; 327 /* byte swap */ 328 void Bswap(InsnSize insnSize, Reg reg) override; 329 void Xchg(InsnSize insnSize, Reg srcReg, Reg destReg) override; 330 /* pseudo insn */ DealWithPseudoInst(const std::string & insn)331 void DealWithPseudoInst(const std::string &insn) override {} 332 /* floating point */ 333 void MovF(Reg srcReg, Reg destReg, bool isSingle) override; 334 /* floating point and */ 335 void And(Reg srcReg, Reg destReg, bool isSingle) override; 336 void And(const Mem &mem, Reg reg, bool isSingle) override; 337 /* floating div */ 338 void Divsd(Reg srcReg, Reg destReg) override; 339 void Divsd(const Mem &mem, Reg reg) override; 340 /* convert int2float */ 341 void Cvtsi2ss(InsnSize insnSize, Reg srcReg, Reg destReg) override; 342 void Cvtsi2sd(InsnSize insnSize, Reg srcReg, Reg destReg) override; 343 /*convert float2int */ 344 void Cvttsd2si(InsnSize insnSize, Reg srcReg, Reg destReg) override; 345 void Cvttss2si(InsnSize insnSize, Reg srcReg, Reg destReg) override; 346 /* convert float2float */ 347 void Cvtss2sd(Reg srcReg, Reg destReg) override; 348 void Cvtsd2ss(Reg srcReg, Reg destReg) override; 349 /* unordered compare */ 350 void Ucomisd(Reg srcReg, Reg destReg) override; 351 void Ucomiss(Reg srcReg, Reg destReg) override; 352 void Cmpsd(Reg srcReg, Reg destReg, uint8 imm); 353 void Cmpeqsd(Reg srcReg, Reg destReg) override; 354 /* float sqrt*/ 355 void Sqrtss_r(Reg srcReg, Reg destReg) override; 356 void Sqrtsd_r(Reg srcReg, Reg destReg) override; 357 /* end of X64 instructions */ 358 /* process stackmap */ 359 void RecordStackmap(const std::vector<uint64> &referenceMap, 360 const std::vector<uint64> &deoptVreg2LocationInfo) override; 361 uint32 GetCurModulePC() override; 362 void SetLastModulePC(uint32 pc) override; 363 364 private: 365 /* insn encode function */ Encodeb(uint64 code)366 void Encodeb(uint64 code) 367 { 368 codeBuff.push_back(static_cast<uint8>(code)); 369 } 370 Encodeb(const uint8 * code,size_t codeSize)371 void Encodeb(const uint8 *code, size_t codeSize) 372 { 373 for (size_t i = 0; i < codeSize; i++) { 374 Encodeb(code[i]); 375 } 376 } 377 Encodeb(uint64 code,size_t codeSize)378 void Encodeb(uint64 code, size_t codeSize) 379 { 380 for (size_t i = 0; i < codeSize; i++) { 381 /* Use little endian for immediate value or displacement. */ 382 Encodeb(static_cast<uint8>(code >> (i * k8Bits))); 383 } 384 } 385 Encodew(uint64 code)386 void Encodew(uint64 code) 387 { 388 Encodeb(code, k16Bits / k8Bits); /* 2bytes, 16bits */ 389 } 390 Encoded(uint64 code)391 void Encoded(uint64 code) 392 { 393 Encodeb(code, k32Bits / k8Bits); /* 4bytes, 32bits */ 394 } 395 Encodeq(uint64 code)396 void Encodeq(uint64 code) 397 { 398 Encodeb(code, k64Bits / k8Bits); /* 8bytes, 64bits */ 399 } 400 FixupEncode(size_t position,uint32 relOffset,size_t codeSize)401 void FixupEncode(size_t position, uint32 relOffset, size_t codeSize) 402 { 403 uint64 code = static_cast<uint64>(relOffset - position - codeSize); 404 for (size_t i = 0; i < codeSize; i++) { 405 codeBuff[position + i] = static_cast<uint8>(code >> (i * k8Bits)); 406 } 407 } 408 GetRegSize(Reg reg)409 uint8 GetRegSize(Reg reg) const 410 { 411 const uint8 kRegSizeBits = 8; /* The high 8 bits is register's size. */ 412 return reg >> kRegSizeBits; 413 } 414 GetRegId(Reg reg)415 uint8 GetRegId(Reg reg) const 416 { 417 return static_cast<uint8_t>(reg & 0xF); 418 } 419 IsRegExt(Reg reg)420 bool IsRegExt(Reg reg) const 421 { 422 /* 0xF is 4 bits, the lower 4 bits represent the id of the register. */ 423 uint8 regId = reg & 0xF; 424 const uint8 kStartExtId = 8; 425 return (regId & kStartExtId) == kStartExtId; 426 } 427 GetRegCodeId(Reg reg)428 uint8 GetRegCodeId(Reg reg) const 429 { 430 /* The lower 3 bits are used to store the encoding id of the register. */ 431 return reg & kGetLow3Bits; 432 } 433 Need8BitRegPrefix(Reg reg)434 bool Need8BitRegPrefix(Reg reg) const 435 { 436 if (reg == ERR || GetRegSize(reg) != k8Bits) { 437 return false; 438 } 439 uint8 regCodeId = GetRegCodeId(reg); 440 /* From right to left, the eighth bit in reg equals 1 represents the lower 8-bit register. */ 441 const int kEighthBit = 8; 442 bool isLow8BitReg = ((((reg & 0xFF) >> (kEighthBit - 1)) & 1) == 1); 443 const uint8 kMinHigh8BitRegId = 4; 444 const uint8 kMaxHigh8BitRegId = 7; 445 return isLow8BitReg && (regCodeId >= kMinHigh8BitRegId && regCodeId <= kMaxHigh8BitRegId); 446 } 447 HasOpndSizePrefix(Reg reg)448 bool HasOpndSizePrefix(Reg reg) const 449 { 450 return GetRegSize(reg) == k16Bits ? true : false; 451 } 452 HasOpndSizePrefix(const Mem & mem)453 bool HasOpndSizePrefix(const Mem &mem) const 454 { 455 return mem.size == k16Bits ? true : false; 456 } 457 HasAddrSizePrefix(const Mem & mem)458 bool HasAddrSizePrefix(const Mem &mem) const 459 { 460 Reg reg = mem.base != ERR ? mem.base : (mem.index != ERR ? mem.index : ERR); 461 uint8 regSize = reg == ERR ? k64Bits : GetRegSize(reg); 462 return regSize == k32Bits ? true : false; 463 } 464 GetRex(Reg reg)465 uint8 GetRex(Reg reg) const 466 { 467 uint8 rexW = GetRegSize(reg) == k64Bits ? 8 : 0; 468 uint8 rexB = IsRegExt(reg) ? 1 : 0; 469 uint8 rex = rexW | rexB; 470 if (rex || Need8BitRegPrefix(reg)) { 471 rex |= 0x40; /* 0x40 is rex fixed prefix. */ 472 } 473 return rex; 474 } 475 GetRex(Reg reg1,Reg reg2)476 uint8 GetRex(Reg reg1, Reg reg2) const 477 { 478 uint8 rexW = GetRegSize(reg1) == k64Bits || GetRegSize(reg2) == k64Bits ? 8 : 0; 479 uint8 rexR = IsRegExt(reg1) ? 4 : 0; 480 uint8 rexB = IsRegExt(reg2) ? 1 : 0; 481 uint8 rex = rexW | rexR | rexB; 482 if (rex || Need8BitRegPrefix(reg1) || Need8BitRegPrefix(reg2)) { 483 rex |= 0x40; /* 0x40 is rex fixed prefix. */ 484 } 485 return rex; 486 } 487 488 uint8 GetRex(const Mem &mem, Reg reg = ERR) const 489 { 490 uint8 rexW = (reg != ERR && GetRegSize(reg) == k64Bits) || mem.size == k64Bits ? 8 : 0; 491 uint8 rexR = reg != ERR && IsRegExt(reg) ? 4 : 0; 492 uint8 rexX = mem.index != ERR && IsRegExt(mem.index) ? 2 : 0; 493 uint8 rexB = mem.base != ERR && IsRegExt(mem.base) ? 1 : 0; 494 uint8 rex = rexW | rexR | rexX | rexB; 495 if (rex || Need8BitRegPrefix(reg)) { 496 rex |= 0x40; /* 0x40 is rex fixed prefix. */ 497 } 498 return rex; 499 } 500 GetMod(Reg reg)501 uint8 GetMod(Reg reg) const 502 { 503 return 0b11; 504 } /* mod=b11, register direct addressing. */ 505 GetMod(const Mem & mem)506 uint8 GetMod(const Mem &mem) const 507 { 508 int64 symIdx = mem.disp.first; 509 int64 offset = mem.disp.second; 510 if ((symIdx == 0 && offset != 0 && Is8Bits(offset) && mem.base != RIP) || 511 (mem.memType == kOnlyBase && (mem.base == RBP || mem.base == R13))) { 512 return 0b01; /* mod=b01, ModRM=b01 Reg r/m */ 513 } else if (symIdx != 0 || (offset != 0 && Is32Bits(offset))) { 514 if (mem.base == ERR || mem.base == RIP) { 515 return 0b00; /* mod=b00, ModRM=b00 Reg r/m */ 516 } else { 517 return 0b10; /* mod=b10, ModRM=b01 Reg r/m */ 518 } 519 } 520 return 0b00; /* mod=b00, ModRM=b00 Reg r/m */ 521 } 522 GetModRM(Reg reg1,Reg reg2)523 uint8 GetModRM(Reg reg1, Reg reg2) const 524 { 525 uint8 modReg = GetRegCodeId(reg1); 526 uint8 mod = GetMod(reg1); 527 uint8 modrm = GetRegCodeId(reg2); 528 return ((mod << kLeftShift6Bits) | (modReg << kLeftShift3Bits) | (modrm & kGetLow3Bits)); 529 } 530 GetModRM(Reg reg,const Mem & mem)531 uint8 GetModRM(Reg reg, const Mem &mem) const 532 { 533 uint8 modReg = GetRegCodeId(reg); 534 uint8 mod = GetMod(mem); 535 uint8 modrm = !HasSIB(mem) ? GetRegCodeId(mem.base) : 0b100; /* r/m=b100, use SIB */ 536 return ((mod << kLeftShift6Bits) | (modReg << kLeftShift3Bits) | (modrm & kGetLow3Bits)); 537 } 538 SetModRM(uint8 mod,uint8 modReg,uint8 modrm)539 void SetModRM(uint8 mod, uint8 modReg, uint8 modrm) 540 { 541 uint8 modRM = (mod << kLeftShift6Bits) | (modReg << kLeftShift3Bits) | (modrm & kGetLow3Bits); 542 Encodeb(modRM); 543 } 544 HasSIB(const Mem & mem)545 bool HasSIB(const Mem &mem) const 546 { 547 if (mem.memType == kBaseAndDisp || mem.memType == kOnlyBase) { 548 return GetRegCodeId(mem.base) == 0b100; 549 } 550 return mem.memType != kBaseAndDisp && mem.memType != kOnlyBase && mem.memType != kNone; 551 } 552 GetSIB(const Mem & mem)553 uint8 GetSIB(const Mem &mem) const 554 { 555 std::unordered_map<uint8, uint8> log2Map = {{1, 0}, {2, 1}, {4, 2}, {8, 3}}; 556 uint8 scale = log2Map[mem.s]; 557 uint8 index = mem.index != ERR ? GetRegCodeId(mem.index) : 0b100; 558 uint8 base = mem.base != ERR ? GetRegCodeId(mem.base) : 0b101; 559 return ((scale << kLeftShift6Bits) | ((index & kGetLow3Bits) << kLeftShift3Bits) | (base & kGetLow3Bits)); 560 } 561 562 void OpReg(Reg reg, uint8 opCode1, uint8 opCode2, uint8 modReg); 563 void OpMem(const Mem &mem, uint8 opCode1, uint8 opCode2, uint8 modReg); 564 void OpDisp(const Mem &mem); 565 void OpRR(Reg reg1, Reg reg2, uint8 opCode1, uint8 opCode2 = 0, bool extInsn = false); 566 void OpRM(Reg reg, const Mem &mem, uint8 opCode1, uint8 opCode2 = 0, bool extInsn = false); 567 void OpImmAndReg(const ImmOpnd &immOpnd, Reg reg, uint8 opCode, uint8 modReg); 568 void OpImmAndMem(const ImmOpnd &immOpnd, const Mem &mem, uint8 modReg); 569 void MovRegAndDisp(Reg reg, const Mem &mem, uint8 opCode); 570 void OpPushPop(Reg reg, uint8 opCode); 571 void JmpToLabel(int64 labelIdx, uint8 opCode1, uint8 opCode2 = 0, size_t offsetSize = 4); 572 void OpCmovcc(Reg srcReg, Reg dstReg, uint8 opCode1, uint8 opCode2); 573 void UpdateLabel(int64 labelIdx, LabelType type = LabelType::kLNone, uint32 relOffset = 0xFFFFFFFFU); 574 bool CanEncodeLabel(int64 labelIdx); 575 uint32 GetLabelSize(int64 labelIdx) const; 576 uint32 GetLabelRelOffset(int64 labelIdx) const; 577 void AppendFixup(int64 labelIdx, FixupKind kind, const std::pair<uint32, size_t> &offsetPair, 578 std::vector<Fixup *> &tmpFixups, int64 disp = 0); 579 /* elf file */ 580 void InitElfHeader(); 581 void RegisterSection(Section §ion); 582 void LayoutSections(); 583 void UpdateSectionOffset(Section §ion); 584 void UpdateGlobalOffset(Section §ion); 585 void SetFileOffset(uint64 offset); 586 /* symIdx is the key used to get symbol's index in .symtab */ 587 void AddSymToSymTab(const Symbol &symbol, int64 symIdx); 588 void AppendRela(const Label &label, const std::pair<uint32, size_t> &offsetPair, uint64 type, Sxword addend); 589 uint64 GetRelaType(FixupKind kind) const; 590 void HandleTextSectionFixup(); 591 void HandleDataSectionFixup(); 592 void HandleRodataSectionFixup(); 593 void WriteElfFile(); 594 void AppendSecSymsToSymTabSec(); 595 void AppendSymsToSymTabSec(); 596 597 private: 598 std::vector<uint8> codeBuff; 599 std::unordered_map<int64, Label *> labelManager; 600 std::vector<std::pair<Symbol, int64>> localSymTab; 601 std::vector<std::pair<Symbol, int64>> symTab; 602 std::vector<Fixup *> fixups; 603 std::vector<Fixup *> dataFixups; 604 std::vector<Fixup *> rodataFixups; 605 std::vector<Fixup *> debugInfoFixups; 606 std::vector<Section *> sections; 607 Offset globalOffset = 0; /* global offset of the elf file */ 608 FileHeader header {}; 609 DataSection *textSection = nullptr; 610 DataSection *rodataSection = nullptr; 611 DataSection *dataSection = nullptr; 612 DataSection *bssSection = nullptr; 613 RelaSection *relaSection = nullptr; 614 RelaSection *relaDataSection = nullptr; 615 RelaSection *relaRodataSection = nullptr; 616 StringSection *strTabSection = nullptr; 617 SymbolSection *symbolTabSection = nullptr; 618 /* debug section */ 619 DataSection *debugInfoSection = nullptr; 620 RelaSection *relaDebugInfoSection = nullptr; 621 DataSection *debugAbbrevSection = nullptr; 622 DataSection *debugStrSection = nullptr; 623 DataSection *debugARangesSection = nullptr; 624 DataSection *debugRangesSection = nullptr; 625 DataSection *debugLineSection = nullptr; 626 uint64_t lastModulePC; 627 }; /* class ElfAssembler */ 628 } /* namespace assembler */ 629 630 #endif /* ELF_ASSEMBLER_H */