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