• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <climits>
17 #include "assembler/elf_assembler.h"
18 
19 namespace assembler {
20 /* These used in ModRM mode when an instruction is encoded. */
21 const uint8 kSubModReg = 5;
22 const uint8 kAndModReg = 4;
23 const uint8 kOrModReg = 1;
24 const uint8 kXorModReg = 6;
25 const uint8 kNotModReg = 2;
26 const uint8 kNegModReg = 3;
27 const uint8 kIdivModReg = 7;
28 const uint8 kDivModReg = 6;
29 const uint8 kShlModReg = 4;
30 const uint8 kSarModReg = 7;
31 const uint8 kShrModReg = 5;
32 const uint8 kJmpModReg = 4;
33 const uint8 kCmpModReg = 7;
34 const uint8 kCallModReg = 2;
35 
36 /* override function in base class */
InitialFileInfo(const std::string & inputFileName)37 void ElfAssembler::InitialFileInfo(const std::string &inputFileName)
38 {
39     /* Initialize some sections that must be used. */
40     DataSection *nullDataSection = new DataSection(" ", SHT_NULL, 0, 0);
41     RegisterSection(*nullDataSection);
42     strTabSection = new StringSection(".strtab", SHT_STRTAB, 0, 1);
43     RegisterSection(*strTabSection);
44     textSection = new DataSection(".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, k8Bits);
45     RegisterSection(*textSection);
46     symbolTabSection = new SymbolSection(".symtab", SHT_SYMTAB, 0, k8Bits, *strTabSection);
47     RegisterSection(*symbolTabSection);
48 }
49 
EmitVariable(int64 symIdx,uint64 sizeInByte,uint8 alignInByte,SymbolAttr symAttr,SectionKind sectionKind)50 void ElfAssembler::EmitVariable(int64 symIdx, uint64 sizeInByte, uint8 alignInByte, SymbolAttr symAttr,
51                                 SectionKind sectionKind)
52 {
53     switch (sectionKind) {
54         case kSBss:
55         case kSComm:
56         case kSTbss:
57             EmitBssSectionVar(symIdx, sizeInByte, alignInByte, symAttr);
58             break;
59         case kSTdata:
60         case kSData:
61             EmitDataSectionVar(symIdx);
62             break;
63         case kSRodata:
64             if (rodataSection == nullptr) {
65                 rodataSection = new DataSection(".rodata", SHT_PROGBITS, SHF_ALLOC, k8Bits);
66                 RegisterSection(*rodataSection);
67             }
68             UpdateLabel(symIdx, LabelType::kConst, rodataSection->GetDataSize());
69             break;
70         case kSText:
71             UpdateLabel(symIdx);
72             break;
73         case kSDebugInfo:
74         case kSDebugAbbrev:
75         case kSDebugStr:
76         default:
77             assert(false && "unprocessed Section in EmitVariable");
78             break;
79     }
80 }
81 
EmitFloatValue(int64 symIdx,int64 value,size_t valueSize)82 void ElfAssembler::EmitFloatValue(int64 symIdx, int64 value, size_t valueSize)
83 {
84     auto reloffset = codeBuff.size();
85     Encodeb(value, valueSize);
86 
87     if (valueSize == maplebe::k4ByteSize) {
88         UpdateLabel(symIdx, LabelType::kFloatLabel, reloffset);
89     } else if (valueSize == maplebe::k8ByteSize) {
90         UpdateLabel(symIdx, LabelType::kDoubleLabel, reloffset);
91     } else {
92         CHECK_FATAL(false, "--Err: EmitFloatValue only handle float and double value");
93     }
94 }
95 
EmitBssSectionVar(int64 symIdx,uint64 sizeInByte,uint8 alignInByte,SymbolAttr symAttr)96 void ElfAssembler::EmitBssSectionVar(int64 symIdx, uint64 sizeInByte, uint8 alignInByte, SymbolAttr symAttr)
97 {
98     if (bssSection == nullptr) {
99         bssSection = new DataSection(".bss", SHT_NOBITS, SHF_WRITE | SHF_ALLOC, k8Bits);
100         RegisterSection(*bssSection);
101     }
102     uint64 bssCurSize = bssSection->GetSectionSize();
103     bssSection->SetSectionSize(static_cast<Xword>(bssCurSize + sizeInByte));
104     if (symAttr == kSALocal) {
105         const std::string &symbolName = GetNameFromSymMap(symIdx, true);
106         auto nameIndex = strTabSection->AddString(symbolName);
107         AddSymToSymTab({static_cast<Word>(nameIndex), static_cast<uint8>((STB_LOCAL << 4) + (STT_OBJECT & 0xf)), 0,
108                         bssSection->GetIndex(), bssCurSize, sizeInByte},
109                        symIdx);
110         UpdateLabel(symIdx, LabelType::kLocalUninitialized, static_cast<uint32>(bssCurSize));
111     } else {
112         const std::string &symbolName = GetNameFromSymMap(symIdx);
113         auto nameIndex = strTabSection->AddString(symbolName);
114         AddSymToSymTab({static_cast<Word>(nameIndex), static_cast<uint8>((STB_GLOBAL << 4) + (STT_OBJECT & 0xf)), 0,
115                         SHN_COMMON, static_cast<Address>(alignInByte), sizeInByte},
116                        symIdx);
117         UpdateLabel(symIdx, LabelType::kGlobalUninitialized, static_cast<uint32>(bssCurSize));
118     }
119 }
120 
EmitDataSectionVar(int64 symIdx)121 void ElfAssembler::EmitDataSectionVar(int64 symIdx)
122 {
123     if (dataSection == nullptr) {
124         dataSection = new DataSection(".data", SHT_PROGBITS, SHF_WRITE | SHF_ALLOC, k8Bits);
125         RegisterSection(*dataSection);
126     }
127     uint32 pos = dataSection->GetDataSize();
128     UpdateLabel(symIdx, LabelType::kStatic, pos);
129 }
130 
EmitFunctionHeader(int64 symIdx,SymbolAttr funcAttr,const std::string * secName)131 void ElfAssembler::EmitFunctionHeader(int64 symIdx, SymbolAttr funcAttr, const std::string *secName)
132 {
133     const auto &emitMemoryManager = maplebe::CGOptions::GetInstance().GetEmitMemoryManager();
134     if (emitMemoryManager.funcAddressSaver != nullptr) {
135         const std::string &funcName = GetNameFromSymMap(symIdx);
136         emitMemoryManager.funcAddressSaver(emitMemoryManager.codeSpace, funcName,
137             static_cast<uint32>(lastModulePC + codeBuff.size()));
138     }
139     UpdateLabel(symIdx, LabelType::kFunc, static_cast<uint32>(codeBuff.size()));
140 }
141 
EmitBBLabel(int64 labelSymIdx,bool genVerboseInfo,uint32 freq,const std::string * mirName)142 void ElfAssembler::EmitBBLabel(int64 labelSymIdx, bool genVerboseInfo, uint32 freq, const std::string *mirName)
143 {
144     UpdateLabel(labelSymIdx, LabelType::kBBLabel, static_cast<uint32>(codeBuff.size()));
145 }
146 
EmitJmpTableElem(int64 jmpLabelIdx,const std::vector<int64> & labelSymIdxs)147 void ElfAssembler::EmitJmpTableElem(int64 jmpLabelIdx, const std::vector<int64> &labelSymIdxs)
148 {
149     UpdateLabel(jmpLabelIdx, LabelType::kJmpLabel, static_cast<uint32>(codeBuff.size()));
150     const size_t kLabelSize = 8;
151     for (auto labelSymIdx : labelSymIdxs) {
152         AppendFixup(labelSymIdx, kAbsolute64, {static_cast<uint32>(codeBuff.size()), kLabelSize}, fixups);
153         uint8 imm = 0;
154         Encodeb(imm, kLabelSize);
155     }
156 }
157 
EmitFunctionFoot(int64 symIdx,SymbolAttr funcAttr)158 void ElfAssembler::EmitFunctionFoot(int64 symIdx, SymbolAttr funcAttr)
159 {
160     uint64 funcSymValue = static_cast<uint64>(GetLabelRelOffset(symIdx));
161     uint64 funcSymSize = static_cast<uint64>(GetLabelSize(symIdx));
162     uint8 funcSymType = STB_GLOBAL;
163     switch (funcAttr) {
164         case kSALocal:
165             funcSymType = STB_LOCAL;
166             break;
167         case kSAGlobal:
168             funcSymType = STB_GLOBAL;
169             break;
170         case kSAWeak:
171             funcSymType = STB_WEAK;
172             break;
173         case kSAStatic:
174         case kSAHidden:
175         default:
176             assert(false && "unkonwn/unsupport SymbolAttr in EmitFunctionFoot");
177             break;
178     }
179     const std::string &symbolName = GetNameFromSymMap(symIdx);
180     auto nameIndex = strTabSection->AddString(symbolName);
181     AddSymToSymTab({static_cast<Word>(nameIndex),
182                     static_cast<uint8>((funcSymType << kLeftShift4Bits) + (STT_FUNC & 0xf)), 0, textSection->GetIndex(),
183                     funcSymValue, funcSymSize},
184                    symIdx);
185 }
186 
EmitDirectString(const std::string & str,bool belongsToDataSec,int64 strSymIdx,bool emitAscii)187 void ElfAssembler::EmitDirectString(const std::string &str, bool belongsToDataSec, int64 strSymIdx, bool emitAscii)
188 {
189     /* Add a terminator to a string. */
190     std::string ustr = str;
191     ustr += '\0';
192     if (strSymIdx != 0) {
193         if (dataSection == nullptr) {
194             dataSection = new DataSection(".data", SHT_PROGBITS, SHF_WRITE | SHF_ALLOC, k8Bits);
195             RegisterSection(*dataSection);
196         }
197         uint32 pos = dataSection->GetDataSize();
198         UpdateLabel(strSymIdx, LabelType::kStrLabel, pos);
199         dataSection->AppendData(ustr.data(), ustr.size());
200         const size_t kStrAlignSize = 8;
201         /* append size, append 0 when align need. */
202         size_t appendSize = kStrAlignSize - ustr.size() % kStrAlignSize;
203         int64 appendData = 0;
204         dataSection->AppendData(appendData, appendSize);
205     } else {
206         if (belongsToDataSec) {
207             dataSection->AppendData(ustr.data(), ustr.size());
208         } else {
209             rodataSection->AppendData(ustr.data(), ustr.size());
210         }
211     }
212 }
213 
EmitIndirectString(int64 strSymIdx,bool belongsToDataSec)214 void ElfAssembler::EmitIndirectString(int64 strSymIdx, bool belongsToDataSec)
215 {
216     const size_t kStrAddrSize = 8;
217     uint32 pos = 0;
218     int64 addr = 0;
219     if (belongsToDataSec) {
220         pos = dataSection->GetDataSize();
221         dataSection->AppendData(addr, kStrAddrSize);
222         AppendFixup(strSymIdx, kAbsolute64, {pos, kStrAddrSize}, dataFixups);
223     } else {
224         pos = rodataSection->GetDataSize();
225         rodataSection->AppendData(addr, kStrAddrSize);
226         AppendFixup(strSymIdx, kAbsolute64, {pos, kStrAddrSize}, rodataFixups);
227     }
228 }
229 
EmitIntValue(int64 value,size_t valueSize,bool belongsToDataSec)230 void ElfAssembler::EmitIntValue(int64 value, size_t valueSize, bool belongsToDataSec)
231 {
232     if (belongsToDataSec) {
233         dataSection->AppendData(value, valueSize);
234     } else {
235         rodataSection->AppendData(value, valueSize);
236     }
237 }
238 
EmitAddrValue(int64 symIdx,int32 symAddrOfs,int32 structFieldOfs,bool belongsToDataSec)239 void ElfAssembler::EmitAddrValue(int64 symIdx, int32 symAddrOfs, int32 structFieldOfs, bool belongsToDataSec)
240 {
241     const size_t kAddrSize = 8;
242     uint32 pos = 0;
243     int64 addr = 0;
244     if (belongsToDataSec) {
245         pos = dataSection->GetDataSize();
246         dataSection->AppendData(addr, kAddrSize);
247         AppendFixup(symIdx, kAbsolute64, {pos, kAddrSize}, dataFixups, symAddrOfs);
248     } else {
249         pos = rodataSection->GetDataSize();
250         rodataSection->AppendData(addr, kAddrSize);
251         AppendFixup(symIdx, kAbsolute64, {pos, kAddrSize}, rodataFixups, symAddrOfs);
252     }
253 }
254 
EmitAddrOfFuncValue(int64 symIdx,bool belongsToDataSec)255 void ElfAssembler::EmitAddrOfFuncValue(int64 symIdx, bool belongsToDataSec)
256 {
257     EmitLabelValue(symIdx, belongsToDataSec);
258 }
259 
EmitLabelValue(int64 symIdx,bool belongsToDataSec)260 void ElfAssembler::EmitLabelValue(int64 symIdx, bool belongsToDataSec)
261 {
262     const size_t kAddrSize = 8;
263     uint32 pos = 0;
264     int64 addr = 0;
265     if (belongsToDataSec) {
266         pos = dataSection->GetDataSize();
267         dataSection->AppendData(addr, kAddrSize);
268         AppendFixup(symIdx, kAbsolute64, {pos, kAddrSize}, dataFixups);
269     } else {
270         pos = rodataSection->GetDataSize();
271         rodataSection->AppendData(addr, kAddrSize);
272         AppendFixup(symIdx, kAbsolute64, {pos, kAddrSize}, rodataFixups);
273     }
274 }
275 
EmitBitFieldValue(uint64 combineBitFieldValue,bool belongsToDataSec)276 void ElfAssembler::EmitBitFieldValue(uint64 combineBitFieldValue, bool belongsToDataSec)
277 {
278     if (belongsToDataSec) {
279         dataSection->AppendData(static_cast<int64>(combineBitFieldValue), 1);
280     } else {
281         rodataSection->AppendData(static_cast<int64>(combineBitFieldValue), 1);
282     }
283 }
284 
EmitNull(uint64 sizeInByte)285 void ElfAssembler::EmitNull(uint64 sizeInByte)
286 {
287     int64 data = 0;
288     dataSection->AppendData(data, static_cast<size_t>(sizeInByte));
289 }
290 
PostEmitVariable(int64 symIdx,SymbolAttr symAttr,uint64 sizeInByte,bool belongsToTextSec)291 void ElfAssembler::PostEmitVariable(int64 symIdx, SymbolAttr symAttr, uint64 sizeInByte, bool belongsToTextSec)
292 {
293     Label *label = labelManager.at(symIdx);
294     uint64 pos = static_cast<uint64>(label->GetRelOffset());
295     auto secIdx = belongsToTextSec ? textSection->GetIndex() : dataSection->GetIndex();
296     if (symAttr == kSALocal) {
297         const std::string &symbolName = GetNameFromSymMap(symIdx, true);
298         auto index = strTabSection->AddString(symbolName);
299         AddSymToSymTab({static_cast<Word>(index), static_cast<uint8>((STB_LOCAL << 4) + (STT_OBJECT & 0xf)), 0, secIdx,
300             pos, sizeInByte}, symIdx);
301     } else {
302         const std::string &symbolName = GetNameFromSymMap(symIdx);
303         auto index = strTabSection->AddString(symbolName);
304         uint8 symInfo = symAttr == kSAGlobal ? STB_GLOBAL : STB_WEAK;
305         AddSymToSymTab({static_cast<Word>(index), static_cast<uint8>((symInfo << 4) + (STT_OBJECT & 0xf)), 0, secIdx,
306             pos, sizeInByte}, symIdx);
307     }
308 }
309 
FinalizeFileInfo()310 void ElfAssembler::FinalizeFileInfo()
311 {
312     AppendSymsToSymTabSec();
313     HandleTextSectionFixup();
314     HandleDataSectionFixup();
315     HandleRodataSectionFixup();
316     HandleDebugInfoSectionFixup();
317     WriteElfFile();
318 }
319 
320 /* encode function */
OpReg(Reg reg,uint8 opCode1,uint8 opCode2,uint8 modReg)321 void ElfAssembler::OpReg(Reg reg, uint8 opCode1, uint8 opCode2, uint8 modReg)
322 {
323     if (HasOpndSizePrefix(reg)) {
324         Encodeb(0x66);
325     }
326     uint8 rex = GetRex(reg);
327     if (rex != 0) {
328         Encodeb(rex);
329     }
330     Encodeb(opCode1 | (GetRegSize(reg) == k8Bits ? 0 : 1));
331     if (opCode2 != 0) {
332         Encodeb(opCode2);
333     }
334     uint8 modrm = GetRegCodeId(reg);
335     SetModRM(GetMod(reg), modReg, modrm);
336 }
337 
OpMem(const Mem & mem,uint8 opCode1,uint8 opCode2,uint8 modReg)338 void ElfAssembler::OpMem(const Mem &mem, uint8 opCode1, uint8 opCode2, uint8 modReg)
339 {
340     if (HasOpndSizePrefix(mem)) {
341         Encodeb(0x66);
342     }
343 
344     if (HasAddrSizePrefix(mem)) {
345         Encodeb(0x67);
346     }
347 
348     uint8 rex = GetRex(mem);
349     if (rex != 0) {
350         Encodeb(rex);
351     }
352     Encodeb(opCode1 | (mem.size == k8Bits ? 0 : 1));
353     if (opCode2 != 0) {
354         Encodeb(opCode2);
355     }
356     uint8 modrm = 0;
357     if (!HasSIB(mem)) {
358         modrm = GetRegCodeId(mem.base);
359     } else {
360         modrm = 0b100; /* r/m=b100, use SIB */
361     }
362     SetModRM(GetMod(mem), modReg, modrm);
363     if (HasSIB(mem)) {
364         Encodeb(GetSIB(mem));
365     }
366     OpDisp(mem);
367 }
368 
OpDisp(const Mem & mem)369 void ElfAssembler::OpDisp(const Mem &mem)
370 {
371     int64 symIdx = mem.disp.first;
372     uint64 offset = static_cast<uint64>(mem.disp.second);
373     if (symIdx != 0) {
374         if (!CanEncodeLabel(symIdx)) {
375             size_t offsetSize = 4;
376             UpdateLabel(symIdx);
377             AppendFixup(symIdx, kRelative, {static_cast<uint32>(codeBuff.size()), offsetSize}, fixups, mem.disp.second);
378             uint8 imm = 0;
379             Encodeb(imm, offsetSize);
380         }
381     } else if (offset == 0) {
382         if (mem.memType == kOnlyBase && (mem.base == RBP || mem.base == R13)) {
383             Encodeb(offset);
384         } else if (mem.base == RIP) {
385             Encoded(offset);
386         } else {
387             return;
388         }
389     } else {
390         if (mem.base != RIP && Is8Bits(offset)) {
391             Encodeb(offset); /* 8-bit displacement */
392         } else {
393             Encoded(offset); /* 32-bit displacement */
394         }
395     }
396 }
397 
OpRR(Reg reg1,Reg reg2,uint8 opCode1,uint8 opCode2,bool extInsn)398 void ElfAssembler::OpRR(Reg reg1, Reg reg2, uint8 opCode1, uint8 opCode2, bool extInsn)
399 {
400     if (!extInsn && (HasOpndSizePrefix(reg1) || HasOpndSizePrefix(reg2))) {
401         Encodeb(0x66);
402     }
403     uint8 rex = extInsn ? GetRex(reg2, reg1) : GetRex(reg1, reg2);
404     if (rex != 0) {
405         Encodeb(rex);
406     }
407     Encodeb(opCode1 | (GetRegSize(reg1) == k8Bits ? 0 : 1));
408     if (opCode2 != 0) {
409         Encodeb(opCode2);
410     }
411     uint8 modrm = extInsn ? GetModRM(reg2, reg1) : GetModRM(reg1, reg2);
412     if (modrm != 0) {
413         Encodeb(modrm);
414     }
415 }
416 
OpRM(Reg reg,const Mem & mem,uint8 opCode1,uint8 opCode2,bool extInsn)417 void ElfAssembler::OpRM(Reg reg, const Mem &mem, uint8 opCode1, uint8 opCode2, bool extInsn)
418 {
419     if (!extInsn && HasOpndSizePrefix(reg)) {
420         Encodeb(0x66);
421     }
422     if (!extInsn && HasAddrSizePrefix(mem)) {
423         Encodeb(0x67);
424     }
425     uint8 rex = GetRex(mem, reg);
426     if (rex != 0) {
427         Encodeb(rex);
428     }
429     Encodeb(opCode1 | (GetRegSize(reg) == k8Bits ? 0 : 1));
430     if (opCode2 != 0) {
431         Encodeb(opCode2);
432     }
433     uint8 modrm = GetModRM(reg, mem);
434     Encodeb(modrm);
435     if (HasSIB(mem)) {
436         Encodeb(GetSIB(mem));
437     }
438     OpDisp(mem);
439 }
440 
OpImmAndReg(const ImmOpnd & immOpnd,Reg reg,uint8 opCode,uint8 modReg)441 void ElfAssembler::OpImmAndReg(const ImmOpnd &immOpnd, Reg reg, uint8 opCode, uint8 modReg)
442 {
443     bool isSymbol = immOpnd.second;
444     uint32 imm = static_cast<uint32>(immOpnd.first); /* When isSymbol is true, this is index. */
445     uint8 immBit = Is8Bits(imm) ? k8Bits : (Is16Bits(imm) ? k16Bits : k32Bits);
446     uint8 regSize = GetRegSize(reg);
447     if (regSize == k8Bits) {
448         immBit = k8Bits;
449     }
450     if (immBit == k16Bits && (regSize == k64Bits || regSize == k32Bits)) {
451         immBit = k32Bits; /* if 32/64bit mode, imm val can not use 16-bit. */
452     }
453     immBit = isSymbol ? k32Bits : immBit;
454     if (GetRegId(reg) == 0 && (regSize == immBit || (regSize == k64Bits && immBit == k32Bits))) {
455         if (HasOpndSizePrefix(reg)) {
456             Encodeb(0x66);
457         }
458         if (GetRex(reg)) {
459             Encodeb(GetRex(reg));
460         }
461         Encodeb(opCode | 0x4 | (immBit == k8Bits ? 0 : 1));
462     } else {
463         uint8 tmp = immBit < std::min(static_cast<uint32>(regSize), 32U) ? 2 : 0;
464         OpReg(reg, 0x80 | tmp, 0, modReg);
465     }
466     if (isSymbol) {
467         if (!CanEncodeLabel(immOpnd.first)) {
468             UpdateLabel(immOpnd.first);
469             AppendFixup(immOpnd.first, kRelative, {static_cast<uint32>(codeBuff.size()), immBit / k8Bits}, fixups);
470             imm = 0;
471             Encodeb(imm, immBit / k8Bits);
472         }
473     } else {
474         Encodeb(imm, immBit / k8Bits);
475     }
476 }
477 
OpImmAndMem(const ImmOpnd & immOpnd,const Mem & mem,uint8 modReg)478 void ElfAssembler::OpImmAndMem(const ImmOpnd &immOpnd, const Mem &mem, uint8 modReg)
479 {
480     bool isSymbol = immOpnd.second;
481     uint32 imm = static_cast<uint32>(immOpnd.first); /* When isSymbol is true, this is index. */
482     if (isSymbol) {
483         if (!CanEncodeLabel(immOpnd.first)) {
484             size_t offsetSize = 4;
485             UpdateLabel(immOpnd.first);
486             AppendFixup(immOpnd.first, kRelative, {static_cast<uint32>(codeBuff.size()), offsetSize}, fixups);
487             imm = 0;
488             OpMem(mem, 0x80, 0, modReg);
489             Encodeb(imm, offsetSize);
490         }
491     } else {
492         uint8 immBit = Is8Bits(imm) ? k8Bits : (Is16Bits(imm) ? k16Bits : k32Bits);
493         if (mem.size == k8Bits) {
494             immBit = k8Bits;
495         }
496         if (immBit == k16Bits && (mem.size == k64Bits || mem.size == k32Bits)) {
497             immBit = k32Bits; /* if 32/64bit mode, imm val can not use 16-bit. */
498         }
499         uint8 tmp = immBit < std::min(static_cast<uint32>(mem.size), 32U) ? 2 : 0;
500         OpMem(mem, 0x80 | tmp, 0, modReg);
501         Encodeb(imm, immBit / k8Bits);
502     }
503 }
504 
MovRegAndDisp(Reg reg,const Mem & mem,uint8 opCode)505 void ElfAssembler::MovRegAndDisp(Reg reg, const Mem &mem, uint8 opCode)
506 {
507     if (HasOpndSizePrefix(reg)) {
508         Encodeb(0x66);
509     }
510     if (HasAddrSizePrefix(mem)) {
511         Encodeb(0x67);
512     }
513     uint8 rex = GetRex(mem, reg);
514     if (rex != 0) {
515         Encodeb(rex);
516     }
517     Encodeb(opCode | (GetRegSize(reg) == k8Bits ? 0 : 1));
518     int64 symIdx = mem.disp.first;
519     uint64 offset = static_cast<uint64>(mem.disp.second);
520     if (symIdx != 0) {
521         size_t offsetSize = k8Bits;
522         Encodeb(static_cast<uint8>(0), offsetSize);
523         UpdateLabel(symIdx);
524         AppendFixup(symIdx, kAbsolute64, {static_cast<uint32>(codeBuff.size()), offsetSize}, fixups);
525     }
526     if (Is64Bits(offset)) {
527         Encodeq(offset);
528     } else {
529         Encoded(offset);
530     }
531 }
532 
OpPushPop(Reg reg,uint8 code)533 void ElfAssembler::OpPushPop(Reg reg, uint8 code)
534 {
535     if (HasOpndSizePrefix(reg)) {
536         Encodeb(0x66);
537     }
538     if (IsRegExt(reg)) {
539         Encodeb(0x41); /* Rex prefix */
540     }
541     Encodeb(code | GetRegCodeId(reg));
542 }
543 
JmpToLabel(int64 labelIdx,uint8 opCode1,uint8 opCode2,size_t offsetSize)544 void ElfAssembler::JmpToLabel(int64 labelIdx, uint8 opCode1, uint8 opCode2, size_t offsetSize)
545 {
546     Encodeb(opCode1);
547     if (opCode2 != 0) {
548         Encodeb(opCode2);
549     }
550     if (!CanEncodeLabel(labelIdx)) {
551         UpdateLabel(labelIdx);
552         AppendFixup(labelIdx, kRelative, {static_cast<uint32>(codeBuff.size()), offsetSize}, fixups);
553         uint8 imm = 0;
554         Encodeb(imm, offsetSize);
555     }
556 }
557 
OpCmovcc(Reg srcReg,Reg dstReg,uint8 opCode1,uint8 opCode2)558 void ElfAssembler::OpCmovcc(Reg srcReg, Reg dstReg, uint8 opCode1, uint8 opCode2)
559 {
560     if (HasOpndSizePrefix(srcReg) || HasOpndSizePrefix(dstReg)) {
561         Encodeb(0x66);
562     }
563     uint8 rex = GetRex(dstReg, srcReg);
564     if (rex != 0) {
565         Encodeb(rex);
566     }
567     Encodeb(opCode1);
568     Encodeb(opCode2);
569     uint8 modrm = GetModRM(dstReg, srcReg);
570     if (modrm != 0) {
571         Encodeb(modrm);
572     }
573 }
574 
UpdateLabel(int64 labelIdx,LabelType type,uint32 relOffset)575 void ElfAssembler::UpdateLabel(int64 labelIdx, LabelType type, uint32 relOffset)
576 {
577     if (labelManager.count(labelIdx) == 0) {
578         Label *label = new Label(labelIdx, relOffset, type);
579         (void)labelManager.emplace(labelIdx, label);
580     } else {
581         Label *label = labelManager.at(labelIdx);
582         if (type != LabelType::kLNone) {
583             label->SetLabelType(type);
584         }
585         if (relOffset != 0xFFFFFFFFU) {
586             label->SetRelOffset(relOffset);
587         }
588     }
589 }
590 
CanEncodeLabel(int64 labelIdx)591 bool ElfAssembler::CanEncodeLabel(int64 labelIdx)
592 {
593     if (labelManager.count(labelIdx) != 0) {
594         Label *label = labelManager.at(labelIdx);
595         uint32 relOffset = label->GetRelOffset();
596         LabelType labelType = label->GetLabelType();
597         bool canEncode = (labelType == LabelType::kBBLabel || labelType == LabelType::kFunc ||
598                           labelType == LabelType::kDoubleLabel || labelType == LabelType::kFloatLabel);
599         if (canEncode && relOffset != 0xFFFFFFFFU) {
600             size_t offsetSize = 4;
601             uint64 offset = static_cast<uint64>((relOffset - codeBuff.size()) - offsetSize);
602             Encodeb(offset, offsetSize);
603             return true;
604         }
605     }
606     return false;
607 }
608 
GetLabelSize(int64 labelIdx) const609 uint32 ElfAssembler::GetLabelSize(int64 labelIdx) const
610 {
611     return static_cast<uint32>(codeBuff.size()) - GetLabelRelOffset(labelIdx);
612 }
613 
GetLabelRelOffset(int64 labelIdx) const614 uint32 ElfAssembler::GetLabelRelOffset(int64 labelIdx) const
615 {
616     if (labelManager.count(labelIdx) != 0) {
617         Label *label = labelManager.at(labelIdx);
618         assert(label->GetRelOffset() != 0xFFFFFFFFU && "label's relOffset doesn't exist");
619         return label->GetRelOffset();
620     }
621     return 0;
622 }
623 
AppendFixup(int64 labelIdx,FixupKind kind,const std::pair<uint32,size_t> & offsetPair,std::vector<Fixup * > & tmpFixups,int64 disp)624 void ElfAssembler::AppendFixup(int64 labelIdx, FixupKind kind, const std::pair<uint32, size_t> &offsetPair,
625                                std::vector<Fixup *> &tmpFixups, int64 disp)
626 {
627     tmpFixups.push_back(new Fixup(labelIdx, kind, offsetPair, disp));
628 }
629 
630 /* elf file */
InitElfHeader()631 void ElfAssembler::InitElfHeader()
632 {
633     header.e_ident[EI_MAG0] = ELFMAG0;
634     header.e_ident[EI_MAG1] = ELFMAG1;
635     header.e_ident[EI_MAG2] = ELFMAG2;
636     header.e_ident[EI_MAG3] = ELFMAG3;
637     header.e_ident[EI_CLASS] = ELFCLASS64;
638     header.e_ident[EI_DATA] = ELFDATA2LSB;
639     header.e_ident[EI_VERSION] = EV_CURRENT;
640     header.e_ident[EI_OSABI] = ELFOSABI_NONE; /* ELFOSABI_NONE represents UNIX System V */
641     header.e_ident[EI_ABIVERSION] = 0;
642     (void)std::fill_n(&header.e_ident[EI_PAD], EI_NIDENT - EI_PAD, 0);
643     header.e_type = ET_REL;
644     header.e_machine = EM_X86_64;
645     header.e_version = EV_CURRENT;
646     header.e_entry = 0;
647     header.e_phoff = 0;
648     header.e_shoff = 0; /* later get */
649     header.e_flags = 0; /* The Intel architecture defines no flags; so this member contains zero. */
650     header.e_ehsize = sizeof(FileHeader);
651     header.e_phentsize = 0;
652     header.e_phnum = 0;
653     header.e_shentsize = sizeof(SectionHeader);
654     header.e_shnum = static_cast<uint16>(sections.size());
655     header.e_shstrndx = strTabSection->GetIndex();
656 }
657 
RegisterSection(Section & section)658 void ElfAssembler::RegisterSection(Section &section)
659 {
660     sections.push_back(&section);
661     section.SetIndex(static_cast<SectionIndex>(sections.size() - 1));
662 }
663 
LayoutSections()664 void ElfAssembler::LayoutSections()
665 {
666     globalOffset = sizeof(FileHeader);
667     globalOffset = Alignment::Align<Offset>(globalOffset, k8Bits);
668 
669     for (auto *section : sections) {
670         section->SetSectionHeaderNameIndex(static_cast<Word>(strTabSection->AddString(section->GetName())));
671     }
672 
673     for (auto *section : sections) {
674         globalOffset = Alignment::Align<Offset>(globalOffset, section->GetAlign());
675         /* lay out section */
676         UpdateSectionOffset(*section);
677         if (section->GetType() != SHT_NOBITS) {
678             section->GenerateData();
679         }
680         UpdateGlobalOffset(*section);
681     }
682 
683     globalOffset = Alignment::Align<Offset>(globalOffset, 16U);
684     header.e_shoff = globalOffset;
685     header.e_shnum = static_cast<uint16>(sections.size());
686 }
687 
UpdateSectionOffset(Section & section)688 void ElfAssembler::UpdateSectionOffset(Section &section)
689 {
690     if (section.GetType() != SHT_NOBITS) {
691         section.SetOffset(globalOffset);
692     } else {
693         section.SetOffset(0);
694     }
695 }
696 
UpdateGlobalOffset(Section & section)697 void ElfAssembler::UpdateGlobalOffset(Section &section)
698 {
699     if (section.GetType() != SHT_NOBITS) {
700         globalOffset += section.GetSectionSize();
701     }
702 }
703 
SetFileOffset(uint64 offset)704 void ElfAssembler::SetFileOffset(uint64 offset)
705 {
706     (void)outStream.seekp(offset);
707 }
708 
709 /* symIdx is the key used to get symbol's index in .symtab */
AddSymToSymTab(const Symbol & symbol,int64 symIdx)710 void ElfAssembler::AddSymToSymTab(const Symbol &symbol, int64 symIdx)
711 {
712     const int kGetHigh4Bits = 4;
713     if ((symbol.st_info >> kGetHigh4Bits) == STB_LOCAL) {
714         localSymTab.push_back(std::make_pair(symbol, symIdx));
715     } else {
716         symTab.push_back(std::make_pair(symbol, symIdx));
717     }
718 }
719 
AppendRela(const Label & label,const std::pair<uint32,size_t> & offsetPair,uint64 type,Sxword addend)720 void ElfAssembler::AppendRela(const Label &label, const std::pair<uint32, size_t> &offsetPair, uint64 type,
721                               Sxword addend)
722 {
723     LabelType labelType = label.GetLabelType();
724     int64 relOffset = static_cast<int64>(label.GetRelOffset());
725     uint64 offset = static_cast<uint64>(offsetPair.first);
726     int64 offsetSize = static_cast<int64>(offsetPair.second);
727     if (labelType == LabelType::kConst) {
728         int64 rodataSecSymIdx = ~rodataSection->GetIndex() + 1;
729         relaSection->AppendRela(
730             {offset,
731              static_cast<Xword>((symbolTabSection->GetIdxInSymbols(rodataSecSymIdx) << kLeftShift32Bits) +
732                                 (type & 0xffffffff)),
733              relOffset});
734     } else if (labelType == LabelType::kGlobal) {
735         addend -= offsetSize;
736         relaSection->AppendRela(
737             {offset,
738              static_cast<Xword>((symbolTabSection->GetIdxInSymbols(label.GetlabelIdx()) << kLeftShift32Bits) +
739                                 (type & 0xffffffff)),
740              addend});
741     } else if (labelType == LabelType::kStatic) {
742         addend += relOffset - offsetSize;
743         int64 dataSecSymIdx = ~dataSection->GetIndex() + 1;
744         relaSection->AppendRela(
745             {offset,
746              static_cast<Xword>((symbolTabSection->GetIdxInSymbols(dataSecSymIdx) << kLeftShift32Bits) +
747                                 (type & 0xffffffff)),
748              addend});
749     } else if (labelType == LabelType::kLocalUninitialized) {
750         addend = addend + relOffset - offsetSize;
751         int64 bssSecSymIdx = ~bssSection->GetIndex() + 1;
752         relaSection->AppendRela(
753             {offset,
754              static_cast<Xword>((symbolTabSection->GetIdxInSymbols(bssSecSymIdx) << kLeftShift32Bits) +
755                                 (type & 0xffffffff)),
756              addend});
757     } else if (labelType == LabelType::kGlobalUninitialized) {
758         addend = addend - offsetSize;
759         relaSection->AppendRela(
760             {offset,
761              static_cast<Xword>((symbolTabSection->GetIdxInSymbols(label.GetlabelIdx()) << kLeftShift32Bits) +
762                                 (type & 0xffffffff)),
763              addend});
764     } else if (labelType == LabelType::kJmpLabel) {
765         type = R_X86_64_32;
766         addend = relOffset;
767         int64 textSecSymIdx = ~textSection->GetIndex() + 1;
768         relaSection->AppendRela(
769             {offset,
770              static_cast<Xword>((symbolTabSection->GetIdxInSymbols(textSecSymIdx) << kLeftShift32Bits) +
771                                 (type & 0xffffffff)),
772              addend});
773     } else if (labelType == LabelType::kBBLabel) {
774         addend = relOffset;
775         int64 textSecSymIdx = ~textSection->GetIndex() + 1;
776         relaSection->AppendRela(
777             {offset,
778              static_cast<Xword>((symbolTabSection->GetIdxInSymbols(textSecSymIdx) << kLeftShift32Bits) +
779                                 (type & 0xffffffff)),
780              addend});
781     } else if (labelType == LabelType::kFunc ||
782                (label.GetRelOffset() == 0xFFFFFFFFU && labelType == LabelType::kLNone)) {
783         int64 labelIdx = label.GetlabelIdx();
784         if (!symbolTabSection->ExistSymInSymbols(labelIdx)) {
785             symbolTabSection->AppendSymbol({static_cast<Word>(strTabSection->AddString(GetNameFromSymMap(labelIdx))),
786                                             static_cast<uint8>((STB_GLOBAL << kLeftShift4Bits) + (STT_NOTYPE & 0xf)), 0,
787                                             0, 0, 0});
788             symbolTabSection->AppendIdxInSymbols(labelIdx);
789         }
790         relaSection->AppendRela({offsetPair.first,
791                                  static_cast<Xword>((symbolTabSection->GetIdxInSymbols(labelIdx) << kLeftShift32Bits) +
792                                                     (type & 0xffffffff)),
793                                  addend});
794     } else {
795         assert(false && "unsupported label type in func AddRela");
796     }
797 }
798 
GetRelaType(FixupKind kind) const799 uint64 ElfAssembler::GetRelaType(FixupKind kind) const
800 {
801     switch (kind) {
802         case kRelative:
803             return R_X86_64_PC32;
804         case kRelative64:
805             return R_X86_64_PC64;
806         case kAbsolute:
807             return R_X86_64_32;
808         case kAbsolute64:
809             return R_X86_64_64;
810         case kPLT:
811             return R_X86_64_PLT32;
812         case kFNone:
813             return R_X86_64_NONE;
814     }
815 }
816 
HandleTextSectionFixup()817 void ElfAssembler::HandleTextSectionFixup()
818 {
819     if (!fixups.empty()) {
820         relaSection =
821             new RelaSection(".rela.text", SHT_RELA, SHF_INFO_LINK, textSection->GetIndex(), k8Bits, *symbolTabSection);
822         RegisterSection(*relaSection);
823     }
824 
825     for (auto fixup : fixups) {
826         int64 labelIdx = fixup->GetlabelIdx();
827         if (labelManager.count(labelIdx) == 0) {
828             continue;
829         }
830 
831         const std::pair<uint32, size_t> &offsetPair = fixup->GetOffset();
832         Label *label = labelManager.at(labelIdx);
833         uint32 relOffset = label->GetRelOffset();
834         LabelType labelType = label->GetLabelType();
835 
836         FixupKind fixupKind = fixup->GetFixupKind();
837         if ((fixupKind == kRelative || fixupKind == kRelative64) &&
838             (labelType == LabelType::kBBLabel || labelType == LabelType::kFunc)) {
839             FixupEncode(offsetPair.first, relOffset, offsetPair.second);
840             fixup->SetFixupKind(kFNone);
841         }
842 
843         if (relOffset != 0xFFFFFFFFU && fixupKind == kPLT) {
844             FixupEncode(offsetPair.first, relOffset, offsetPair.second);
845             fixup->SetFixupKind(kFNone);
846         }
847 
848         fixupKind = fixup->GetFixupKind();
849         uint64 type = GetRelaType(fixupKind);
850         int64 addend = (fixupKind == kAbsolute || fixupKind == kAbsolute64) ? 0 : -0x4;
851         if (fixupKind != kFNone) {
852             addend = labelType == LabelType::kGlobalUninitialized || labelType == LabelType::kLocalUninitialized ||
853                              labelType == LabelType::kGlobal || labelType == LabelType::kStatic
854                          ? fixup->GetDisp()
855                          : addend;
856             AppendRela(*label, offsetPair, type, addend);
857         }
858     }
859     textSection->AppendData(codeBuff.data(), codeBuff.size());
860 }
861 
HandleDataSectionFixup()862 void ElfAssembler::HandleDataSectionFixup()
863 {
864     if (!dataFixups.empty()) {
865         relaDataSection =
866             new RelaSection(".rela.data", SHT_RELA, SHF_INFO_LINK, dataSection->GetIndex(), k8Bits, *symbolTabSection);
867         RegisterSection(*relaDataSection);
868     }
869     for (auto fixup : dataFixups) {
870         int64 labelIdx = fixup->GetlabelIdx();
871         std::pair<uint32, size_t> offset = fixup->GetOffset();
872         const uint32 relocType = R_X86_64_64;
873         if (labelManager.count(labelIdx) == 0) {
874             continue;
875         }
876         Label *label = labelManager.at(labelIdx);
877         LabelType labelType = label->GetLabelType();
878         int64 addend = 0;
879         int64 relOffset = static_cast<int64>(label->GetRelOffset());
880         if (labelType == LabelType::kGlobalUninitialized) {
881             addend = fixup->GetDisp();
882             uint64 pos = symbolTabSection->GetIdxInSymbols(labelIdx);
883             relaDataSection->AppendRela(
884                 {offset.first, static_cast<Xword>((pos << kLeftShift32Bits) + (relocType & 0xffffffff)), addend});
885         } else if (labelType == LabelType::kLocalUninitialized) {
886             addend = fixup->GetDisp();
887             int64 bssSecSymIdx = ~bssSection->GetIndex() + 1;
888             relaDataSection->AppendRela(
889                 {offset.first,
890                  static_cast<Xword>((symbolTabSection->GetIdxInSymbols(bssSecSymIdx) << kLeftShift32Bits) +
891                                     (relocType & 0xffffffff)),
892                  addend});
893         } else if (labelType == LabelType::kFunc) {
894             uint64 pos = symbolTabSection->GetIdxInSymbols(labelIdx);
895             relaDataSection->AppendRela(
896                 {offset.first, static_cast<Xword>((pos << kLeftShift32Bits) + (relocType & 0xffffffff)), addend});
897         } else if (labelType == LabelType::kStrLabel || labelType == LabelType::kGlobal ||
898                    labelType == LabelType::kStatic) {
899             uint64 pos = symbolTabSection->GetIdxInSymbols(~dataSection->GetIndex() + 1);
900             addend = (labelType == LabelType::kGlobal || labelType == LabelType::kStatic) ? fixup->GetDisp() + relOffset
901                                                                                           : relOffset;
902             relaDataSection->AppendRela(
903                 {offset.first, static_cast<Xword>((pos << kLeftShift32Bits) + (relocType & 0xffffffff)), addend});
904         } else {
905             addend = relOffset;
906             int64 textSecSymIdx = ~textSection->GetIndex() + 1;
907             relaDataSection->AppendRela(
908                 {offset.first,
909                  static_cast<Xword>((symbolTabSection->GetIdxInSymbols(textSecSymIdx) << kLeftShift32Bits) +
910                                     (relocType & 0xffffffff)),
911                  addend});
912         }
913     }
914 }
915 
HandleRodataSectionFixup()916 void ElfAssembler::HandleRodataSectionFixup()
917 {
918     if (!rodataFixups.empty()) {
919         relaRodataSection = new RelaSection(".rela.rodata", SHT_RELA, SHF_INFO_LINK, rodataSection->GetIndex(), k8Bits,
920                                             *symbolTabSection);
921         RegisterSection(*relaRodataSection);
922     }
923     for (auto fixup : rodataFixups) {
924         int64 labelIdx = fixup->GetlabelIdx();
925         std::pair<uint32, size_t> offset = fixup->GetOffset();
926         const uint32 relocType = R_X86_64_64;
927         if (labelManager.count(labelIdx) == 0) {
928             continue;
929         }
930         Label *label = labelManager.at(labelIdx);
931         LabelType labelType = label->GetLabelType();
932         int64 addend = 0;
933         int64 relOffset = static_cast<int64>(label->GetRelOffset());
934         if (labelType == LabelType::kGlobalUninitialized || labelType == LabelType::kLocalUninitialized) {
935             addend = relOffset;
936             uint64 pos = symbolTabSection->GetIdxInSymbols(~textSection->GetIndex() + 1);
937             relaRodataSection->AppendRela(
938                 {offset.first, static_cast<Xword>((pos << kLeftShift32Bits) + (relocType & 0xffffffff)), addend});
939         }
940     }
941 }
942 
WriteElfFile()943 void ElfAssembler::WriteElfFile()
944 {
945     /* Init elf file header */
946     InitElfHeader();
947 
948     LayoutSections();
949 
950     const auto &emitMemoryManager = maplebe::CGOptions::GetInstance().GetEmitMemoryManager();
951     if (emitMemoryManager.codeSpace != nullptr) {
952         DEBUG_ASSERT(textSection != nullptr, "textSection has not been initialized");
953         uint8 *memSpace = emitMemoryManager.allocateDataSection(emitMemoryManager.codeSpace,
954             textSection->GetSectionSize(), textSection->GetAlign(), textSection->GetName());
955         memcpy_s(memSpace, textSection->GetSectionSize(), textSection->GetData().data(), textSection->GetDataSize());
956         return;
957     }
958 
959     /* write header */
960     Emit(&header, sizeof(header));
961 
962     /* write sections */
963     for (auto *section : sections) {
964         if (section->GetType() == SHT_NOBITS) {
965             continue;
966         }
967         SetFileOffset(section->GetOffset());
968         section->WriteSection(outStream);
969     }
970 
971     /* write section table */
972     SetFileOffset(header.e_shoff);
973     for (auto *section : sections) {
974         Emit(&section->GetSectionHeader(), sizeof(section->GetSectionHeader()));
975     }
976 }
977 
978 /* Append the symbol of non-empty and necessary section to symbol table section. */
AppendSecSymsToSymTabSec()979 void ElfAssembler::AppendSecSymsToSymTabSec()
980 {
981     for (Section *section : sections) {
982         if (section->GetType() != SHT_PROGBITS && section->GetType() != SHT_NOBITS) {
983             continue;
984         }
985         DataSection *dataSec = static_cast<DataSection *>(section);
986         if (section->GetFlags() == (SHF_ALLOC | SHF_EXECINSTR) || section->GetSectionSize() != 0 ||
987             (dataSec != nullptr && dataSec->GetDataSize() != 0)) {
988             auto nameIndex = strTabSection->AddString(section->GetName());
989             symbolTabSection->AppendSymbol({static_cast<Word>(nameIndex),
990                                             static_cast<uint8>((STB_LOCAL << kLeftShift4Bits) + (STT_SECTION & 0xf)), 0,
991                                             section->GetIndex(), 0, 0});
992             /* Indexed by the inverse of the section index. */
993             int64 secSymIdx = ~section->GetIndex() + 1;
994             symbolTabSection->AppendIdxInSymbols(secSymIdx);
995         }
996     }
997 }
998 
AppendSymsToSymTabSec()999 void ElfAssembler::AppendSymsToSymTabSec()
1000 {
1001     /* emit local symbol */
1002     for (auto elem : localSymTab) {
1003         Symbol symbol = elem.first;
1004         int64 symIdx = elem.second;
1005         symbolTabSection->AppendSymbol(symbol);
1006         symbolTabSection->AppendIdxInSymbols(symIdx);
1007     }
1008 
1009     /* Append section symbol that may be used in relocation item, section is local. */
1010     AppendSecSymsToSymTabSec();
1011 
1012     /* set .symtab's info : index of the first non-local symbol */
1013     symbolTabSection->SetInfo(symbolTabSection->GetSymbolsSize());
1014 
1015     /* emit global and other symbol */
1016     for (auto elem : symTab) {
1017         const Symbol &symbol = elem.first;
1018         int64 symIdx = elem.second;
1019         symbolTabSection->AppendSymbol(symbol);
1020         symbolTabSection->AppendIdxInSymbols(symIdx);
1021     }
1022 }
1023 
1024 /* emit debug info */
EmitDIDebugInfoSectionHeader(uint64 debugInfoLength)1025 void ElfAssembler::EmitDIDebugInfoSectionHeader(uint64 debugInfoLength)
1026 {
1027     debugInfoSection = new DataSection(".debug_info", SHT_PROGBITS, 0, 1);
1028     RegisterSection(*debugInfoSection);
1029     /* length of .debug_info section, 4 bytes */
1030     size_t debugInfoLenSize = 4;
1031     debugInfoSection->AppendData(static_cast<int64>(debugInfoLength), debugInfoLenSize);
1032     size_t dwarfVersionSize = 2;
1033     /* DWARF version, 2 bytes */
1034     debugInfoSection->AppendData(static_cast<int64>(kDwarfVersion), dwarfVersionSize);
1035     /* debug_abbrev_offset. 4 bytes for dwarf32, 8 bytes for dwarf64 */
1036     int64 debugAbbrevOffset = 0;
1037     size_t debugAbbrevOffsetSize = 4;
1038     /* If labelSymIdx equals LLONG_MAX, there is not a real label bound to the fixup. */
1039     AppendFixup(LLONG_MAX, kAbsolute, {debugInfoSection->GetDataSize(), debugAbbrevOffsetSize}, debugInfoFixups);
1040     debugInfoSection->AppendData(debugAbbrevOffset, debugAbbrevOffsetSize);
1041     /* address size. 1 byte */
1042     size_t byteOfkSizeOfPTR = 1;
1043     debugInfoSection->AppendData(kSizeOfPTR, byteOfkSizeOfPTR);
1044 }
1045 
EmitDIDebugInfoSectionAbbrevId(bool verbose,uint32 abbrevId,const std::string & dieTagName,uint32 offset,uint32 size)1046 void ElfAssembler::EmitDIDebugInfoSectionAbbrevId(bool verbose, uint32 abbrevId, const std::string &dieTagName,
1047                                                   uint32 offset, uint32 size)
1048 {
1049     auto abbrevIdUleb128 = EncodeULEB128(abbrevId);
1050     debugInfoSection->AppendData(&abbrevIdUleb128, abbrevIdUleb128.size());
1051 }
1052 
1053 /* EmitDIAttrValue */
EmitDwFormString(const std::string & name)1054 void ElfAssembler::EmitDwFormString(const std::string &name)
1055 {
1056     debugInfoSection->AppendData(&name, name.size());
1057 }
1058 
EmitDwFormStrp(uint32 strLabelId,size_t strTableSize)1059 void ElfAssembler::EmitDwFormStrp(uint32 strLabelId, size_t strTableSize)
1060 {
1061     int64 labelSymIdx = CalculateStrLabelSymIdx(static_cast<int64>(strLabelId), static_cast<int64>(strTableSize));
1062     UpdateLabel(labelSymIdx, LabelType::kDebugStrLabel);
1063     int64 strLabelOffset = 0;
1064     size_t strLabelOffsetSize = 4;
1065     AppendFixup(labelSymIdx, kAbsolute, {debugInfoSection->GetDataSize(), strLabelOffsetSize}, debugInfoFixups);
1066     debugInfoSection->AppendData(strLabelOffset, strLabelOffsetSize);
1067 }
1068 
EmitDwFormData(int32 attrValue,uint8 sizeInByte)1069 void ElfAssembler::EmitDwFormData(int32 attrValue, uint8 sizeInByte)
1070 {
1071     debugInfoSection->AppendData(attrValue, sizeInByte);
1072 }
1073 
EmitDwFormData8()1074 void ElfAssembler::EmitDwFormData8()
1075 {
1076     int64 addr = 0;
1077     size_t addrSizeInByte = 8;
1078     debugInfoSection->AppendData(addr, addrSizeInByte);
1079 }
1080 
EmitDwFormData8(uint32 endLabelFuncPuIdx,uint32 startLabelFuncPuIdx,uint32 endLabelIdx,uint32 startLabelIdx)1081 void ElfAssembler::EmitDwFormData8(uint32 endLabelFuncPuIdx, uint32 startLabelFuncPuIdx, uint32 endLabelIdx,
1082                                    uint32 startLabelIdx)
1083 {
1084     int64 addr = 0;
1085     size_t addrSizeInByte = 8;
1086     debugInfoSection->AppendData(addr, addrSizeInByte);
1087 }
1088 
EmitLabel(uint32 funcPuIdx,uint32 labIdx)1089 void ElfAssembler::EmitLabel(uint32 funcPuIdx, uint32 labIdx)
1090 {
1091     int64 labSymIdx = CalculateLabelSymIdx(funcPuIdx, labIdx);
1092     UpdateLabel(labIdx);
1093     int64 addr = 0;
1094     size_t addrSizeInByte = 8;
1095     AppendFixup(labSymIdx, kAbsolute64, {debugInfoSection->GetDataSize(), addrSizeInByte}, debugInfoFixups);
1096     debugInfoSection->AppendData(addr, addrSizeInByte);
1097 }
1098 
EmitDwFormSecOffset()1099 void ElfAssembler::EmitDwFormSecOffset()
1100 {
1101     int64 lineLabelOffset = 0;
1102     size_t lineLabelOffsetSize = 4;
1103     /* If labelSymIdx equals  - 2, there is not a real label bound to the fixup. */
1104     AppendFixup(LLONG_MAX - 2, kAbsolute, {debugInfoSection->GetDataSize(), lineLabelOffsetSize}, debugInfoFixups);
1105     debugInfoSection->AppendData(lineLabelOffset, lineLabelOffsetSize);
1106 }
1107 
EmitDwFormAddr(bool emitTextBegin)1108 void ElfAssembler::EmitDwFormAddr(bool emitTextBegin)
1109 {
1110     if (emitTextBegin) {
1111         int64 addr = 0;
1112         size_t addrSizeInByte = 8;
1113         /* If labelSymIdx equals LLONG_MAX - 1, there is not a real label bound to the fixup. */
1114         AppendFixup(LLONG_MAX - 1, kAbsolute64, {debugInfoSection->GetDataSize(), addrSizeInByte}, debugInfoFixups);
1115         debugInfoSection->AppendData(addr, addrSizeInByte);
1116     }
1117 }
1118 
EmitDwFormRef4(uint64 offsetOrValue,bool unknownType,bool emitOffset)1119 void ElfAssembler::EmitDwFormRef4(uint64 offsetOrValue, bool unknownType, bool emitOffset)
1120 {
1121     size_t offsetOrValueSize = 4;
1122     debugInfoSection->AppendData(static_cast<int64>(offsetOrValue), offsetOrValueSize);
1123 }
1124 
EmitDwFormExprlocCfa(uint32 dwOp)1125 void ElfAssembler::EmitDwFormExprlocCfa(uint32 dwOp)
1126 {
1127     debugInfoSection->AppendData(1, 1);
1128     debugInfoSection->AppendData(static_cast<int64>(dwOp), 1);
1129 }
1130 
EmitDwFormExprlocAddr(uint32 dwOp,const std::string & addrStr)1131 void ElfAssembler::EmitDwFormExprlocAddr(uint32 dwOp, const std::string &addrStr)
1132 {
1133     debugInfoSection->AppendData(static_cast<int64>(k9ByteSize), 1);
1134     debugInfoSection->AppendData(static_cast<int64>(dwOp), 1);
1135     size_t addStrSize = 8;
1136     debugInfoSection->AppendData(&addrStr, addStrSize);
1137 }
1138 
EmitDwFormExprlocFbreg(uint32 dwOp,int fboffset,size_t sleb128Size)1139 void ElfAssembler::EmitDwFormExprlocFbreg(uint32 dwOp, int fboffset, size_t sleb128Size)
1140 {
1141     auto sleb128SizeEncode = EncodeSLEB128(1 + static_cast<int64>(sleb128Size));
1142     debugInfoSection->AppendData(&sleb128SizeEncode, sleb128SizeEncode.size());
1143     debugInfoSection->AppendData(static_cast<int64>(dwOp), 1);
1144     auto fboffsetSleb128 = EncodeSLEB128(fboffset);
1145     debugInfoSection->AppendData(&fboffsetSleb128, fboffsetSleb128.size());
1146 }
1147 
EmitDwFormExprlocBregn(uint32 dwOp,const std::string & dwOpName)1148 void ElfAssembler::EmitDwFormExprlocBregn(uint32 dwOp, const std::string &dwOpName)
1149 {
1150     debugInfoSection->AppendData(static_cast<int64>(k2Bytes), 1);
1151     debugInfoSection->AppendData(static_cast<int64>(dwOp), 1);
1152     debugInfoSection->AppendData(&dwOpName, dwOpName.size());
1153     int64 offset = 0;
1154     debugInfoSection->AppendData(offset, 1);
1155 }
1156 
EmitDwFormExprloc(uintptr elp)1157 void ElfAssembler::EmitDwFormExprloc(uintptr elp)
1158 {
1159     auto elpUleb128 = EncodeULEB128(elp);
1160     debugInfoSection->AppendData(&elpUleb128, elpUleb128.size());
1161 }
1162 
EmitDIDebugAbbrevDiae(bool verbose,uint32 abbrevId,uint32 tag,const std::string & dwTagName,bool withChildren)1163 void ElfAssembler::EmitDIDebugAbbrevDiae(bool verbose, uint32 abbrevId, uint32 tag, const std::string &dwTagName,
1164                                          bool withChildren)
1165 {
1166     debugAbbrevSection = new DataSection(".debug_abbrev", SHT_PROGBITS, 0, 1);
1167     RegisterSection(*debugAbbrevSection);
1168     /* Abbrev Entry ID */
1169     auto abbrevIdUleb128 = EncodeULEB128(abbrevId);
1170     debugAbbrevSection->AppendData(&abbrevIdUleb128, abbrevIdUleb128.size());
1171     /* TAG */
1172     auto tagUleb128 = EncodeULEB128(tag);
1173     debugAbbrevSection->AppendData(&tagUleb128, tagUleb128.size());
1174     /* children */
1175     auto childrenValue = withChildren ? 1 : 0;
1176     debugAbbrevSection->AppendData(childrenValue, 1);
1177 }
1178 
EmitDIDebugAbbrevDiaePairItem(bool verbose,uint32 aplAt,uint32 aplFrom,const std::string & dwAtName,const std::string & dwFromName)1179 void ElfAssembler::EmitDIDebugAbbrevDiaePairItem(bool verbose, uint32 aplAt, uint32 aplFrom,
1180                                                  const std::string &dwAtName, const std::string &dwFromName)
1181 {
1182     /* odd entry -- DW_AT_*, even entry -- DW_FORM_* */
1183     auto aplAtUleb128 = EncodeULEB128(aplAt);
1184     debugAbbrevSection->AppendData(&aplAtUleb128, aplAtUleb128.size());
1185     auto aplFromUleb128 = EncodeULEB128(aplFrom);
1186     debugAbbrevSection->AppendData(&aplFromUleb128, aplFromUleb128.size());
1187 }
1188 
EmitDIDebugSectionEnd(SectionKind secKind)1189 void ElfAssembler::EmitDIDebugSectionEnd(SectionKind secKind)
1190 {
1191     int64 value = 0;
1192     size_t valueSizeInByte = 1;
1193     switch (secKind) {
1194         case kSDebugInfo:
1195             debugInfoSection->AppendData(value, valueSizeInByte);
1196             break;
1197         case kSDebugAbbrev:
1198             debugAbbrevSection->AppendData(value, valueSizeInByte);
1199             break;
1200         case kSBss:
1201         case kSComm:
1202         case kSData:
1203         case kSRodata:
1204         case kSTbss:
1205         case kSTdata:
1206         case kSText:
1207         case kSDebugStr:
1208         default:
1209             assert(false && "unsupport SectionKind in EmitDIDebugSectionEnd");
1210             break;
1211     }
1212 }
1213 
EmitDIDebugStrSection(const std::vector<uint32> & strps,const std::vector<std::string> & debugStrs,uint64 size,size_t strTableSize)1214 void ElfAssembler::EmitDIDebugStrSection(const std::vector<uint32> &strps, const std::vector<std::string> &debugStrs,
1215                                          uint64 size, size_t strTableSize)
1216 {
1217     debugStrSection = new DataSection(".debug_str", SHT_PROGBITS, SHF_MASKPROC, 1);
1218     RegisterSection(*debugStrSection);
1219     for (int i = 0; i < static_cast<int>(debugStrs.size()); i++) {
1220         int64 strLabSymIdx = CalculateStrLabelSymIdx(size, strps[i], strTableSize);
1221         UpdateLabel(strLabSymIdx, LabelType::kDebugStrLabel, debugStrSection->GetDataSize());
1222         debugStrSection->AppendData(&debugStrs[i], debugStrs[i].size());
1223         EmitDIDebugSectionEnd(kSDebugStr);
1224     }
1225 }
1226 
HandleDebugInfoSectionFixup()1227 void ElfAssembler::HandleDebugInfoSectionFixup()
1228 {
1229     if (!debugInfoFixups.empty()) {
1230         relaDebugInfoSection = new RelaSection(".rela.debug_info", SHT_RELA, SHF_INFO_LINK,
1231                                                debugInfoSection->GetIndex(), k8Bits, *symbolTabSection);
1232         RegisterSection(*relaDebugInfoSection);
1233     }
1234     for (auto fixup : debugInfoFixups) {
1235         int64 labelIdx = fixup->GetlabelIdx();
1236         const std::pair<uint32, size_t> &offsetPair = fixup->GetOffset();
1237         FixupKind fixupKind = fixup->GetFixupKind();
1238         uint64 relocType = GetRelaType(fixupKind);
1239         int64 addend = fixup->GetDisp();
1240         int64 textSecSymIdx = ~textSection->GetIndex() + 1;
1241         int64 debugLineSecSymIdx = ~debugLineSection->GetIndex() + 1;
1242         int64 abbrevSecSymIdx = ~debugAbbrevSection->GetIndex() + 1;
1243         uint64 pos = labelIdx == LLONG_MAX
1244                          ? symbolTabSection->GetIdxInSymbols(debugLineSecSymIdx)
1245                          : (labelIdx == LLONG_MAX - 1 ? symbolTabSection->GetIdxInSymbols(textSecSymIdx)
1246                                                       : symbolTabSection->GetIdxInSymbols(abbrevSecSymIdx));
1247         if (!labelManager.count(labelIdx)) {
1248             relaDebugInfoSection->AppendRela(
1249                 {offsetPair.first, static_cast<Xword>((pos << kLeftShift32Bits) + (relocType & 0xffffffff)), addend});
1250             continue;
1251         }
1252         Label *label = labelManager.at(labelIdx);
1253         LabelType labelType = label->GetLabelType();
1254         addend = label->GetRelOffset();
1255         if (labelType == LabelType::kBBLabel) {
1256             pos = symbolTabSection->GetIdxInSymbols(textSecSymIdx);
1257         } else if (labelType == LabelType::kDebugStrLabel) {
1258             pos = symbolTabSection->GetIdxInSymbols(~debugStrSection->GetIndex() + 1);
1259         } else {
1260             assert(false && "unsupport label type in HandleDebugInfoSectionFixup!");
1261         }
1262         relaDebugInfoSection->AppendRela(
1263             {offsetPair.first, static_cast<Xword>((pos << kLeftShift32Bits) + (relocType & 0xffffffff)), addend});
1264     }
1265 }
1266 
1267 /* start of X64 instructions */
1268 /* mov */
Mov(InsnSize insnSize,Reg srcReg,Reg destReg)1269 void ElfAssembler::Mov(InsnSize insnSize, Reg srcReg, Reg destReg)
1270 {
1271     OpRR(srcReg, destReg, 0x88, 0);
1272 }
1273 
Mov(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1274 void ElfAssembler::Mov(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1275 {
1276     bool isSymbol = immOpnd.second;
1277     uint64 imm = static_cast<uint64>(immOpnd.first); /* When isSymbol is true, this is index. */
1278     uint8 regSize = GetRegSize(reg);
1279     uint8 regId = GetRegCodeId(reg);
1280     uint8 code = 0xB0 | ((regSize == k8Bits ? 0 : 1) << kLeftShift3Bits);
1281     if (HasOpndSizePrefix(reg)) {
1282         Encodeb(0x66);
1283     }
1284     if (GetRex(reg) != 0) {
1285         Encodeb(GetRex(reg));
1286     }
1287     if (regSize == k64Bits && (isSymbol || Is32Bits(imm))) {
1288         Encodeb(0xC7);
1289         code = 0xC0;
1290         regSize = k32Bits;
1291     }
1292     size_t offsetSize = isSymbol ? k64Bits : regSize / k8Bits;
1293     Encodeb(code | regId);
1294     if (isSymbol) {
1295         UpdateLabel(immOpnd.first);
1296         AppendFixup(immOpnd.first, kAbsolute64, {static_cast<uint32>(codeBuff.size()), offsetSize}, fixups);
1297         imm = 0;
1298     }
1299     Encodeb(imm, offsetSize);
1300 }
1301 
Mov(InsnSize insnSize,const Mem & mem,Reg reg)1302 void ElfAssembler::Mov(InsnSize insnSize, const Mem &mem, Reg reg)
1303 {
1304     if (GetRegId(reg) == 0 && mem.memType == kOnlyDisp) {
1305         MovRegAndDisp(reg, mem, 0xA0);
1306     } else {
1307         OpRM(reg, mem, 0x8A, 0);
1308     }
1309 }
1310 
Mov(InsnSize insnSize,Reg reg,const Mem & mem)1311 void ElfAssembler::Mov(InsnSize insnSize, Reg reg, const Mem &mem)
1312 {
1313     if (GetRegId(reg) == 0 && mem.memType == kOnlyDisp) {
1314         MovRegAndDisp(reg, mem, 0xA2);
1315     } else {
1316         OpRM(reg, mem, 0x88, 0);
1317     }
1318 }
1319 
Mov(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1320 void ElfAssembler::Mov(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1321 {
1322     bool isSymbol = immOpnd.second;
1323     uint32 imm = static_cast<uint32>(immOpnd.first); /* When isSymbol is true, this is index. */
1324     uint8 immBit = Is8Bits(imm) ? k8Bits : (Is16Bits(imm) ? k16Bits : k32Bits);
1325     if (mem.size == k8Bits) {
1326         immBit = k8Bits;
1327     }
1328     if (immBit == k16Bits && (mem.size == k64Bits || mem.size == k32Bits)) {
1329         immBit = k32Bits; /* if 32/64bit mode, imm val can not use 16-bit. */
1330     }
1331     immBit = isSymbol ? k64Bits : immBit;
1332     size_t immSize = immBit / k8Bits;
1333     OpMem(mem, 0xC6, 0, 0);
1334     if (isSymbol) {
1335         UpdateLabel(immOpnd.first);
1336         AppendFixup(immOpnd.first, kAbsolute64, {static_cast<uint32>(codeBuff.size()), immSize}, fixups);
1337         imm = 0;
1338     }
1339     Encodeb(imm, immSize);
1340 }
1341 
1342 /* floating point mov */
Mov(Reg srcReg,Reg destReg,bool isMovD)1343 void ElfAssembler::Mov(Reg srcReg, Reg destReg, bool isMovD)
1344 {
1345     uint8 srcRegSize = GetRegSize(srcReg);
1346     uint8 destRegSize = GetRegSize(destReg);
1347     if (srcRegSize == k128Bits || destRegSize == k128Bits) {
1348         Encodeb(0x66);
1349     }
1350     if (srcRegSize == k128Bits) {
1351         OpRR(srcReg, destReg, 0x0F, 0x7E);
1352     } else if (destRegSize == k128Bits) {
1353         OpRR(destReg, srcReg, 0x0F, 0x6E);
1354     }
1355 }
1356 
MovF(const Mem & mem,Reg reg,bool isSingle)1357 void ElfAssembler::MovF(const Mem &mem, Reg reg, bool isSingle)
1358 {
1359     if (isSingle) {
1360         Encodeb(0xF3);
1361     } else {
1362         Encodeb(0xF2);
1363     }
1364     OpRM(reg, mem, 0x0F, 0x10);
1365 }
1366 
MovF(Reg reg,const Mem & mem,bool isSingle)1367 void ElfAssembler::MovF(Reg reg, const Mem &mem, bool isSingle)
1368 {
1369     if (isSingle) {
1370         Encodeb(0xF3);
1371     } else {
1372         Encodeb(0xF2);
1373     }
1374     OpRM(reg, mem, 0x0F, 0x11);
1375 }
1376 
1377 /* movabs */
Movabs(const ImmOpnd & immOpnd,Reg reg)1378 void ElfAssembler::Movabs(const ImmOpnd &immOpnd, Reg reg)
1379 {
1380     bool isSymbol = immOpnd.second;
1381     uint64 imm = static_cast<uint64>(immOpnd.first); /* When isSymbol is true, this is index. */
1382     if (GetRex(reg) != 0) {
1383         Encodeb(GetRex(reg));
1384     }
1385     Encodeb(0xB8 | GetRegCodeId(reg));
1386     size_t offsetSize = 8;
1387     if (isSymbol) {
1388         UpdateLabel(immOpnd.first);
1389         AppendFixup(immOpnd.first, kAbsolute64, {static_cast<uint32>(codeBuff.size()), offsetSize}, fixups);
1390         imm = 0;
1391     }
1392     Encodeb(imm, offsetSize);
1393 }
1394 
Movabs(int64 symIdx,Reg reg)1395 void ElfAssembler::Movabs(int64 symIdx, Reg reg)
1396 {
1397     if (GetRex(reg) != 0) {
1398         Encodeb(GetRex(reg));
1399     }
1400     Encodeb(0xB8 | GetRegCodeId(reg));
1401     size_t offsetSize = 8;
1402     size_t offset = codeBuff.size() - offsetSize;
1403     UpdateLabel(symIdx);
1404     AppendFixup(symIdx, kAbsolute64, {offset, offsetSize}, fixups);
1405     uint8 imm = 0;
1406     Encodeb(imm, offsetSize);
1407 }
1408 
1409 /* push */
Push(InsnSize insnSize,Reg reg)1410 void ElfAssembler::Push(InsnSize insnSize, Reg reg)
1411 {
1412     OpPushPop(reg, 0x50);
1413 }
1414 
1415 /* pop */
Pop(InsnSize insnSize,Reg reg)1416 void ElfAssembler::Pop(InsnSize insnSize, Reg reg)
1417 {
1418     OpPushPop(reg, 0x58);
1419 }
1420 
1421 /* lea */
Lea(InsnSize insnSize,const Mem & mem,Reg reg)1422 void ElfAssembler::Lea(InsnSize insnSize, const Mem &mem, Reg reg)
1423 {
1424     OpRM(reg, mem, 0x8C);
1425 }
1426 
1427 /* movzx */
MovZx(InsnSize sSize,InsnSize dSize,Reg srcReg,Reg destReg)1428 void ElfAssembler::MovZx(InsnSize sSize, InsnSize dSize, Reg srcReg, Reg destReg)
1429 {
1430     OpRR(srcReg, destReg, 0x0F, 0xB6 | (GetRegSize(srcReg) == k8Bits ? 0 : 1), true);
1431 }
1432 
MovZx(InsnSize sSize,InsnSize dSize,const Mem & mem,Reg reg)1433 void ElfAssembler::MovZx(InsnSize sSize, InsnSize dSize, const Mem &mem, Reg reg)
1434 {
1435     OpRM(reg, mem, 0x0F, 0xB6 | (mem.size == k8Bits ? 0 : 1), true);
1436 }
1437 
1438 /* movsx */
MovSx(InsnSize sSize,InsnSize dSize,Reg srcReg,Reg destReg)1439 void ElfAssembler::MovSx(InsnSize sSize, InsnSize dSize, Reg srcReg, Reg destReg)
1440 {
1441     uint8 code1 = 0x0F;
1442     uint8 code2 = 0xBE | (GetRegSize(srcReg) == k8Bits ? 0 : 1);
1443     if (GetRegSize(srcReg) == k32Bits && GetRegSize(destReg) == k64Bits) {
1444         code1 = 0x63;
1445         code2 = 0;
1446     }
1447     OpRR(srcReg, destReg, code1, code2, true);
1448 }
1449 
MovSx(InsnSize sSize,InsnSize dSize,const Mem & mem,Reg reg)1450 void ElfAssembler::MovSx(InsnSize sSize, InsnSize dSize, const Mem &mem, Reg reg)
1451 {
1452     uint8 code1 = 0x0F;
1453     uint8 code2 = 0xBE | (mem.size == k8Bits ? 0 : 1);
1454     if (mem.size == k32Bits && GetRegSize(reg) == k64Bits) {
1455         code1 = 0x63;
1456         code2 = 0;
1457     }
1458     OpRM(reg, mem, code1, code2, true);
1459 }
1460 
1461 /* add */
Add(InsnSize insnSize,Reg srcReg,Reg destReg)1462 void ElfAssembler::Add(InsnSize insnSize, Reg srcReg, Reg destReg)
1463 {
1464     OpRR(srcReg, destReg, 0x00);
1465 }
1466 
Add(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1467 void ElfAssembler::Add(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1468 {
1469     OpImmAndReg(immOpnd, reg, 0x00, 0);
1470 }
1471 
Add(InsnSize insnSize,const Mem & mem,Reg reg)1472 void ElfAssembler::Add(InsnSize insnSize, const Mem &mem, Reg reg)
1473 {
1474     OpRM(reg, mem, 0x02);
1475 }
1476 
Add(InsnSize insnSize,Reg reg,const Mem & mem)1477 void ElfAssembler::Add(InsnSize insnSize, Reg reg, const Mem &mem)
1478 {
1479     OpRM(reg, mem, 0x00);
1480 }
1481 
Add(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1482 void ElfAssembler::Add(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1483 {
1484     OpImmAndMem(immOpnd, mem, 0);
1485 }
1486 
1487 /* add floating point */
Add(Reg srcReg,Reg destReg,bool isSingle)1488 void ElfAssembler::Add(Reg srcReg, Reg destReg, bool isSingle)
1489 {
1490     if (isSingle) {
1491         Encodeb(0xF3);
1492     } else {
1493         Encodeb(0xF2);
1494     }
1495     OpRR(destReg, srcReg, 0x0F, 0x58);
1496 }
1497 
Add(const Mem & mem,Reg reg,bool isSingle)1498 void ElfAssembler::Add(const Mem &mem, Reg reg, bool isSingle)
1499 {
1500     if (isSingle) {
1501         Encodeb(0xF3);
1502     } else {
1503         Encodeb(0xF2);
1504     }
1505     OpRM(reg, mem, 0x0F, 0x58);
1506 }
1507 
1508 /* sub */
Sub(InsnSize insnSize,Reg srcReg,Reg destReg)1509 void ElfAssembler::Sub(InsnSize insnSize, Reg srcReg, Reg destReg)
1510 {
1511     OpRR(srcReg, destReg, 0x28);
1512 }
1513 
Sub(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1514 void ElfAssembler::Sub(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1515 {
1516     OpImmAndReg(immOpnd, reg, 0x28, kSubModReg);
1517 }
1518 
Sub(InsnSize insnSize,const Mem & mem,Reg reg)1519 void ElfAssembler::Sub(InsnSize insnSize, const Mem &mem, Reg reg)
1520 {
1521     OpRM(reg, mem, 0x2A);
1522 }
1523 
Sub(InsnSize insnSize,Reg reg,const Mem & mem)1524 void ElfAssembler::Sub(InsnSize insnSize, Reg reg, const Mem &mem)
1525 {
1526     OpRM(reg, mem, 0x28);
1527 }
1528 
Sub(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1529 void ElfAssembler::Sub(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1530 {
1531     OpImmAndMem(immOpnd, mem, kSubModReg);
1532 }
1533 
1534 /* sub floating point */
Sub(Reg srcReg,Reg destReg,bool isSingle)1535 void ElfAssembler::Sub(Reg srcReg, Reg destReg, bool isSingle)
1536 {
1537     if (isSingle) {
1538         Encodeb(0xF3);
1539     } else {
1540         Encodeb(0xF2);
1541     }
1542     OpRR(destReg, srcReg, 0x0F, 0x5c);
1543 }
1544 
Sub(const Mem & mem,Reg reg,bool isSingle)1545 void ElfAssembler::Sub(const Mem &mem, Reg reg, bool isSingle)
1546 {
1547     if (isSingle) {
1548         Encodeb(0xF3);
1549     } else {
1550         Encodeb(0xF2);
1551     }
1552     OpRM(reg, mem, 0x0F, 0x5c);
1553 }
1554 
1555 /* and */
And(InsnSize insnSize,Reg srcReg,Reg destReg)1556 void ElfAssembler::And(InsnSize insnSize, Reg srcReg, Reg destReg)
1557 {
1558     OpRR(srcReg, destReg, 0x20);
1559 }
1560 
And(InsnSize insnSize,const Mem & mem,Reg reg)1561 void ElfAssembler::And(InsnSize insnSize, const Mem &mem, Reg reg)
1562 {
1563     OpRM(reg, mem, 0x21);
1564 }
1565 
And(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1566 void ElfAssembler::And(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1567 {
1568     OpImmAndReg(immOpnd, reg, 0x20, kAndModReg);
1569 }
1570 
And(InsnSize insnSize,Reg reg,const Mem & mem)1571 void ElfAssembler::And(InsnSize insnSize, Reg reg, const Mem &mem)
1572 {
1573     OpRM(reg, mem, 0x20);
1574 }
1575 
And(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1576 void ElfAssembler::And(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1577 {
1578     OpImmAndMem(immOpnd, mem, kAndModReg);
1579 }
1580 
1581 /* or */
Or(InsnSize insnSize,Reg srcReg,Reg destReg)1582 void ElfAssembler::Or(InsnSize insnSize, Reg srcReg, Reg destReg)
1583 {
1584     OpRR(srcReg, destReg, 0x08);
1585 }
1586 
Or(InsnSize insnSize,const Mem & mem,Reg reg)1587 void ElfAssembler::Or(InsnSize insnSize, const Mem &mem, Reg reg)
1588 {
1589     OpRM(reg, mem, 0x0A);
1590 }
1591 
Or(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1592 void ElfAssembler::Or(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1593 {
1594     OpImmAndReg(immOpnd, reg, 0x08, kOrModReg);
1595 }
1596 
Or(InsnSize insnSize,Reg reg,const Mem & mem)1597 void ElfAssembler::Or(InsnSize insnSize, Reg reg, const Mem &mem)
1598 {
1599     OpRM(reg, mem, 0x08);
1600 }
1601 
Or(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1602 void ElfAssembler::Or(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1603 {
1604     OpImmAndMem(immOpnd, mem, kOrModReg);
1605 }
1606 
1607 /* xor */
Xor(InsnSize insnSize,Reg srcReg,Reg destReg)1608 void ElfAssembler::Xor(InsnSize insnSize, Reg srcReg, Reg destReg)
1609 {
1610     OpRR(srcReg, destReg, 0x30);
1611 }
1612 
Xor(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1613 void ElfAssembler::Xor(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1614 {
1615     OpImmAndReg(immOpnd, reg, 0x30, kXorModReg);
1616 }
1617 
Xor(InsnSize insnSize,const Mem & mem,Reg reg)1618 void ElfAssembler::Xor(InsnSize insnSize, const Mem &mem, Reg reg)
1619 {
1620     OpRM(reg, mem, 0x32);
1621 }
1622 
Xor(InsnSize insnSize,Reg reg,const Mem & mem)1623 void ElfAssembler::Xor(InsnSize insnSize, Reg reg, const Mem &mem)
1624 {
1625     OpRM(reg, mem, 0x30);
1626 }
1627 
Xor(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1628 void ElfAssembler::Xor(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1629 {
1630     OpImmAndMem(immOpnd, mem, kXorModReg);
1631 }
1632 
1633 /* not */
Not(InsnSize insnSize,Reg reg)1634 void ElfAssembler::Not(InsnSize insnSize, Reg reg)
1635 {
1636     OpReg(reg, 0xF6, 0, kNotModReg);
1637 }
1638 
Not(InsnSize insnSize,const Mem & mem)1639 void ElfAssembler::Not(InsnSize insnSize, const Mem &mem)
1640 {
1641     OpMem(mem, 0xF6, 0, kNotModReg);
1642 }
1643 
1644 /* neg */
Neg(InsnSize insnSize,Reg reg)1645 void ElfAssembler::Neg(InsnSize insnSize, Reg reg)
1646 {
1647     OpReg(reg, 0xF6, 0, kNegModReg);
1648 }
1649 
Neg(InsnSize insnSize,const Mem & mem)1650 void ElfAssembler::Neg(InsnSize insnSize, const Mem &mem)
1651 {
1652     OpMem(mem, 0xF6, 0, kNegModReg);
1653 }
1654 
1655 /* div & cwd, cdq, cqo */
Idiv(InsnSize insnSize,Reg reg)1656 void ElfAssembler::Idiv(InsnSize insnSize, Reg reg)
1657 {
1658     OpReg(reg, 0xF6, 0, kIdivModReg);
1659 }
1660 
Idiv(InsnSize insnSize,const Mem & mem)1661 void ElfAssembler::Idiv(InsnSize insnSize, const Mem &mem)
1662 {
1663     OpMem(mem, 0xF6, 0, kIdivModReg);
1664 }
1665 
Div(InsnSize insnSize,Reg reg)1666 void ElfAssembler::Div(InsnSize insnSize, Reg reg)
1667 {
1668     OpReg(reg, 0xF6, 0, kDivModReg);
1669 }
1670 
Div(InsnSize insnSize,const Mem & mem)1671 void ElfAssembler::Div(InsnSize insnSize, const Mem &mem)
1672 {
1673     OpMem(mem, 0xF6, 0, kDivModReg);
1674 }
1675 
Cwd()1676 void ElfAssembler::Cwd()
1677 {
1678     Encodeb(0x66);
1679     Encodeb(0x99);
1680 }
1681 
Cdq()1682 void ElfAssembler::Cdq()
1683 {
1684     Encodeb(0x99);
1685 }
1686 
Cqo()1687 void ElfAssembler::Cqo()
1688 {
1689     Encodeb(0x48);
1690     Encodeb(0x99);
1691 }
1692 
1693 /* shl */
Shl(InsnSize insnSize,Reg srcReg,Reg destReg)1694 void ElfAssembler::Shl(InsnSize insnSize, Reg srcReg, Reg destReg)
1695 {
1696     OpReg(destReg, 0xD2, 0, kShlModReg);
1697 }
1698 
Shl(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1699 void ElfAssembler::Shl(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1700 {
1701     OpReg(reg, 0xC0, 0, kShlModReg);
1702     Encodeb(static_cast<uint64>(immOpnd.first));
1703 }
1704 
Shl(InsnSize insnSize,Reg reg,const Mem & mem)1705 void ElfAssembler::Shl(InsnSize insnSize, Reg reg, const Mem &mem)
1706 {
1707     OpMem(mem, 0xD2, 0, kShlModReg);
1708 }
1709 
Shl(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1710 void ElfAssembler::Shl(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1711 {
1712     OpMem(mem, 0xC0, 0, kShlModReg);
1713     Encodeb(static_cast<uint64>(immOpnd.first));
1714 }
1715 
1716 /* sar */
Sar(InsnSize insnSize,Reg srcReg,Reg destReg)1717 void ElfAssembler::Sar(InsnSize insnSize, Reg srcReg, Reg destReg)
1718 {
1719     OpReg(destReg, 0xD2, 0, kSarModReg);
1720 }
1721 
Sar(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1722 void ElfAssembler::Sar(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1723 {
1724     OpReg(reg, 0xC0, 0, kSarModReg);
1725     Encodeb(static_cast<uint64>(immOpnd.first));
1726 }
1727 
Sar(InsnSize insnSize,Reg reg,const Mem & mem)1728 void ElfAssembler::Sar(InsnSize insnSize, Reg reg, const Mem &mem)
1729 {
1730     OpMem(mem, 0xD2, 0, kSarModReg);
1731 }
1732 
Sar(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1733 void ElfAssembler::Sar(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1734 {
1735     OpMem(mem, 0xC0, 0, kSarModReg);
1736     Encodeb(static_cast<uint64>(immOpnd.first));
1737 }
1738 
1739 /* shr */
Shr(InsnSize insnSize,Reg srcReg,Reg destReg)1740 void ElfAssembler::Shr(InsnSize insnSize, Reg srcReg, Reg destReg)
1741 {
1742     OpReg(destReg, 0xD2, 0, kShrModReg);
1743 }
1744 
Shr(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1745 void ElfAssembler::Shr(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1746 {
1747     OpReg(reg, 0xC0, 0, kShrModReg);
1748     Encodeb(static_cast<uint64>(immOpnd.first));
1749 }
1750 
Shr(InsnSize insnSize,Reg reg,const Mem & mem)1751 void ElfAssembler::Shr(InsnSize insnSize, Reg reg, const Mem &mem)
1752 {
1753     OpMem(mem, 0xD2, 0, kShrModReg);
1754 }
1755 
Shr(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1756 void ElfAssembler::Shr(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1757 {
1758     OpMem(mem, 0xC0, 0, kShrModReg);
1759     Encodeb(static_cast<uint64>(immOpnd.first));
1760 }
1761 
1762 /* jmp */
Jmp(Reg reg)1763 void ElfAssembler::Jmp(Reg reg)
1764 {
1765     OpReg(reg, 0xFF, 0, kJmpModReg);
1766 }
1767 
Jmp(const Mem & mem)1768 void ElfAssembler::Jmp(const Mem &mem)
1769 {
1770     OpMem(mem, 0xFF, 0, kJmpModReg);
1771 }
1772 
Jmp(int64 symIdx)1773 void ElfAssembler::Jmp(int64 symIdx)
1774 {
1775     JmpToLabel(symIdx, 0xE9);
1776 }
1777 
1778 /* jump condition */
Je(int64 symIdx)1779 void ElfAssembler::Je(int64 symIdx)
1780 {
1781     JmpToLabel(symIdx, 0x0F, 0x84);
1782 }
1783 
Ja(int64 symIdx)1784 void ElfAssembler::Ja(int64 symIdx)
1785 {
1786     JmpToLabel(symIdx, 0x0F, 0x87);
1787 }
1788 
Jae(int64 symIdx)1789 void ElfAssembler::Jae(int64 symIdx)
1790 {
1791     JmpToLabel(symIdx, 0x0F, 0x83);
1792 }
1793 
Jne(int64 symIdx)1794 void ElfAssembler::Jne(int64 symIdx)
1795 {
1796     JmpToLabel(symIdx, 0x0F, 0x85);
1797 }
1798 
Jb(int64 symIdx)1799 void ElfAssembler::Jb(int64 symIdx)
1800 {
1801     JmpToLabel(symIdx, 0x0F, 0x82);
1802 }
1803 
Jbe(int64 symIdx)1804 void ElfAssembler::Jbe(int64 symIdx)
1805 {
1806     JmpToLabel(symIdx, 0x0F, 0x86);
1807 }
1808 
Jg(int64 symIdx)1809 void ElfAssembler::Jg(int64 symIdx)
1810 {
1811     JmpToLabel(symIdx, 0x0F, 0x8F);
1812 }
1813 
Jge(int64 symIdx)1814 void ElfAssembler::Jge(int64 symIdx)
1815 {
1816     JmpToLabel(symIdx, 0x0F, 0x8D);
1817 }
1818 
Jl(int64 symIdx)1819 void ElfAssembler::Jl(int64 symIdx)
1820 {
1821     JmpToLabel(symIdx, 0x0F, 0x8C);
1822 }
1823 
Jle(int64 symIdx)1824 void ElfAssembler::Jle(int64 symIdx)
1825 {
1826     JmpToLabel(symIdx, 0x0F, 0x8E);
1827 }
1828 
1829 /* cmp */
Cmp(InsnSize insnSize,Reg srcReg,Reg destReg)1830 void ElfAssembler::Cmp(InsnSize insnSize, Reg srcReg, Reg destReg)
1831 {
1832     OpRR(srcReg, destReg, 0x38);
1833 }
1834 
Cmp(InsnSize insnSize,const Mem & mem,Reg reg)1835 void ElfAssembler::Cmp(InsnSize insnSize, const Mem &mem, Reg reg)
1836 {
1837     OpRM(reg, mem, 0x3A);
1838 }
1839 
Cmp(InsnSize insnSize,Reg reg,const Mem & mem)1840 void ElfAssembler::Cmp(InsnSize insnSize, Reg reg, const Mem &mem)
1841 {
1842     OpRM(reg, mem, 0x38);
1843 }
1844 
Cmp(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1845 void ElfAssembler::Cmp(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1846 {
1847     OpImmAndReg(immOpnd, reg, 0x38, kCmpModReg);
1848 }
1849 
Cmp(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1850 void ElfAssembler::Cmp(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1851 {
1852     OpImmAndMem(immOpnd, mem, kCmpModReg);
1853 }
1854 
1855 /* test */
Test(InsnSize insnSize,Reg srcReg,Reg destReg)1856 void ElfAssembler::Test(InsnSize insnSize, Reg srcReg, Reg destReg)
1857 {
1858     OpRR(srcReg, destReg, 0x84);
1859 }
1860 
1861 /* setcc */
Setbe(Reg reg)1862 void ElfAssembler::Setbe(Reg reg)
1863 {
1864     OpReg(reg, 0x0F, 0x96, 0);
1865 }
1866 
Setbe(const Mem & mem)1867 void ElfAssembler::Setbe(const Mem &mem)
1868 {
1869     OpMem(mem, 0x0F, 0x96, 0);
1870 }
1871 
Setle(Reg reg)1872 void ElfAssembler::Setle(Reg reg)
1873 {
1874     OpReg(reg, 0x0F, 0x9E, 0);
1875 }
1876 
Setle(const Mem & mem)1877 void ElfAssembler::Setle(const Mem &mem)
1878 {
1879     OpMem(mem, 0x0F, 0x9E, 0);
1880 }
1881 
Setae(Reg reg)1882 void ElfAssembler::Setae(Reg reg)
1883 {
1884     OpReg(reg, 0x0F, 0x93, 0);
1885 }
1886 
Setae(const Mem & mem)1887 void ElfAssembler::Setae(const Mem &mem)
1888 {
1889     OpMem(mem, 0x0F, 0x93, 0);
1890 }
1891 
Setge(Reg reg)1892 void ElfAssembler::Setge(Reg reg)
1893 {
1894     OpReg(reg, 0x0F, 0x9D, 0);
1895 }
Setge(const Mem & mem)1896 void ElfAssembler::Setge(const Mem &mem)
1897 {
1898     OpMem(mem, 0x0F, 0x9D, 0);
1899 }
1900 
Setne(Reg reg)1901 void ElfAssembler::Setne(Reg reg)
1902 {
1903     OpReg(reg, 0x0F, 0x95, 0);
1904 }
1905 
Setne(const Mem & mem)1906 void ElfAssembler::Setne(const Mem &mem)
1907 {
1908     OpMem(mem, 0x0F, 0x95, 0);
1909 }
1910 
Setb(Reg reg)1911 void ElfAssembler::Setb(Reg reg)
1912 {
1913     OpReg(reg, 0x0F, 0x92, 0);
1914 }
1915 
Setb(const Mem & mem)1916 void ElfAssembler::Setb(const Mem &mem)
1917 {
1918     OpMem(mem, 0x0F, 0x92, 0);
1919 }
1920 
Setl(Reg reg)1921 void ElfAssembler::Setl(Reg reg)
1922 {
1923     OpReg(reg, 0x0F, 0x9C, 0);
1924 }
1925 
Setl(const Mem & mem)1926 void ElfAssembler::Setl(const Mem &mem)
1927 {
1928     OpMem(mem, 0x0F, 0x9C, 0);
1929 }
1930 
Seta(Reg reg)1931 void ElfAssembler::Seta(Reg reg)
1932 {
1933     OpReg(reg, 0x0F, 0x97, 0);
1934 }
1935 
Seta(const Mem & mem)1936 void ElfAssembler::Seta(const Mem &mem)
1937 {
1938     OpMem(mem, 0x0F, 0x97, 0);
1939 }
1940 
Setg(Reg reg)1941 void ElfAssembler::Setg(Reg reg)
1942 {
1943     OpReg(reg, 0x0F, 0x9F, 0);
1944 }
1945 
Setg(const Mem & mem)1946 void ElfAssembler::Setg(const Mem &mem)
1947 {
1948     OpMem(mem, 0x0F, 0x9F, 0);
1949 }
1950 
Sete(Reg reg)1951 void ElfAssembler::Sete(Reg reg)
1952 {
1953     OpReg(reg, 0x0F, 0x94, 0);
1954 }
1955 
Sete(const Mem & mem)1956 void ElfAssembler::Sete(const Mem &mem)
1957 {
1958     OpMem(mem, 0x0F, 0x94, 0);
1959 }
1960 
Seto(Reg reg)1961 void ElfAssembler::Seto(Reg reg)
1962 {
1963     OpReg(reg, 0x0F, 0x90, 0);
1964 }
1965 
Seto(const Mem & mem)1966 void ElfAssembler::Seto(const Mem &mem)
1967 {
1968     OpMem(mem, 0x0F, 0x90, 0);
1969 }
1970 
1971 /* cmov */
Cmova(InsnSize insnSize,Reg srcReg,Reg destReg)1972 void ElfAssembler::Cmova(InsnSize insnSize, Reg srcReg, Reg destReg)
1973 {
1974     OpCmovcc(srcReg, destReg, 0x0F, 0x47);
1975 }
1976 
Cmova(InsnSize insnSize,const Mem & mem,Reg reg)1977 void ElfAssembler::Cmova(InsnSize insnSize, const Mem &mem, Reg reg)
1978 {
1979     OpRM(reg, mem, 0x0E, 0x47);
1980 }
Cmovae(InsnSize insnSize,Reg srcReg,Reg destReg)1981 void ElfAssembler::Cmovae(InsnSize insnSize, Reg srcReg, Reg destReg)
1982 {
1983     OpCmovcc(srcReg, destReg, 0x0F, 0x43);
1984 }
1985 
Cmovae(InsnSize insnSize,const Mem & mem,Reg reg)1986 void ElfAssembler::Cmovae(InsnSize insnSize, const Mem &mem, Reg reg)
1987 {
1988     OpRM(reg, mem, 0x0E, 0x43);
1989 }
1990 
Cmovb(InsnSize insnSize,Reg srcReg,Reg destReg)1991 void ElfAssembler::Cmovb(InsnSize insnSize, Reg srcReg, Reg destReg)
1992 {
1993     OpCmovcc(srcReg, destReg, 0x0F, 0x42);
1994 }
1995 
Cmovb(InsnSize insnSize,const Mem & mem,Reg reg)1996 void ElfAssembler::Cmovb(InsnSize insnSize, const Mem &mem, Reg reg)
1997 {
1998     OpRM(reg, mem, 0x0E, 0x42);
1999 }
2000 
Cmovbe(InsnSize insnSize,Reg srcReg,Reg destReg)2001 void ElfAssembler::Cmovbe(InsnSize insnSize, Reg srcReg, Reg destReg)
2002 {
2003     OpCmovcc(srcReg, destReg, 0x0F, 0x46);
2004 }
2005 
Cmovbe(InsnSize insnSize,const Mem & mem,Reg reg)2006 void ElfAssembler::Cmovbe(InsnSize insnSize, const Mem &mem, Reg reg)
2007 {
2008     OpRM(reg, mem, 0x0E, 0x46);
2009 }
2010 
Cmove(InsnSize insnSize,Reg srcReg,Reg destReg)2011 void ElfAssembler::Cmove(InsnSize insnSize, Reg srcReg, Reg destReg)
2012 {
2013     OpCmovcc(srcReg, destReg, 0x0F, 0x44);
2014 }
2015 
Cmove(InsnSize insnSize,const Mem & mem,Reg reg)2016 void ElfAssembler::Cmove(InsnSize insnSize, const Mem &mem, Reg reg)
2017 {
2018     OpRM(reg, mem, 0x0E, 0x44);
2019 }
2020 
Cmovg(InsnSize insnSize,Reg srcReg,Reg destReg)2021 void ElfAssembler::Cmovg(InsnSize insnSize, Reg srcReg, Reg destReg)
2022 {
2023     OpCmovcc(srcReg, destReg, 0x0F, 0x4F);
2024 }
2025 
Cmovg(InsnSize insnSize,const Mem & mem,Reg reg)2026 void ElfAssembler::Cmovg(InsnSize insnSize, const Mem &mem, Reg reg)
2027 {
2028     OpRM(reg, mem, 0x0E, 0x4F);
2029 }
2030 
Cmovge(InsnSize insnSize,Reg srcReg,Reg destReg)2031 void ElfAssembler::Cmovge(InsnSize insnSize, Reg srcReg, Reg destReg)
2032 {
2033     OpCmovcc(srcReg, destReg, 0x0F, 0x4D);
2034 }
2035 
Cmovge(InsnSize insnSize,const Mem & mem,Reg reg)2036 void ElfAssembler::Cmovge(InsnSize insnSize, const Mem &mem, Reg reg)
2037 {
2038     OpRM(reg, mem, 0x0E, 0x4D);
2039 }
2040 
Cmovl(InsnSize insnSize,Reg srcReg,Reg destReg)2041 void ElfAssembler::Cmovl(InsnSize insnSize, Reg srcReg, Reg destReg)
2042 {
2043     OpCmovcc(srcReg, destReg, 0x0F, 0x4C);
2044 }
2045 
Cmovl(InsnSize insnSize,const Mem & mem,Reg reg)2046 void ElfAssembler::Cmovl(InsnSize insnSize, const Mem &mem, Reg reg)
2047 {
2048     OpRM(reg, mem, 0x0E, 0x4C);
2049 }
2050 
Cmovle(InsnSize insnSize,Reg srcReg,Reg destReg)2051 void ElfAssembler::Cmovle(InsnSize insnSize, Reg srcReg, Reg destReg)
2052 {
2053     OpCmovcc(srcReg, destReg, 0x0F, 0x4E);
2054 }
2055 
Cmovle(InsnSize insnSize,const Mem & mem,Reg reg)2056 void ElfAssembler::Cmovle(InsnSize insnSize, const Mem &mem, Reg reg)
2057 {
2058     OpRM(reg, mem, 0x0E, 0x4E);
2059 }
2060 
Cmovo(InsnSize insnSize,Reg srcReg,Reg destReg)2061 void ElfAssembler::Cmovo(InsnSize insnSize, Reg srcReg, Reg destReg)
2062 {
2063     OpCmovcc(srcReg, destReg, 0x0F, 0x40);
2064 }
2065 
Cmovne(InsnSize insnSize,Reg srcReg,Reg destReg)2066 void ElfAssembler::Cmovne(InsnSize insnSize, Reg srcReg, Reg destReg)
2067 {
2068     OpCmovcc(srcReg, destReg, 0x0F, 0x45);
2069 }
2070 
Cmovne(InsnSize insnSize,const Mem & mem,Reg reg)2071 void ElfAssembler::Cmovne(InsnSize insnSize, const Mem &mem, Reg reg)
2072 {
2073     OpRM(reg, mem, 0x0E, 0x45);
2074 }
2075 
2076 /* call */
Call(InsnSize insnSize,Reg reg)2077 void ElfAssembler::Call(InsnSize insnSize, Reg reg)
2078 {
2079     // Save to disignate memory
2080     OpReg(reg, 0xFF, 0, kCallModReg);
2081 }
2082 
Call(InsnSize insnSize,const Mem & mem)2083 void ElfAssembler::Call(InsnSize insnSize, const Mem &mem)
2084 {
2085     OpMem(mem, 0xFF, 0, kCallModReg);
2086 }
2087 
Call(InsnSize insnSize,int64 symIdx)2088 void ElfAssembler::Call(InsnSize insnSize, int64 symIdx)
2089 {
2090     Encodeb(0xE8);
2091     if (!CanEncodeLabel(symIdx)) {
2092         size_t offsetSize = 4;
2093         UpdateLabel(symIdx, LabelType::kFunc);
2094         AppendFixup(symIdx, kPLT, {static_cast<uint32>(codeBuff.size()), offsetSize}, fixups);
2095         uint8 imm = 0;
2096         Encodeb(imm, offsetSize);
2097     }
2098 }
2099 
2100 /* ret */
Ret()2101 void ElfAssembler::Ret()
2102 {
2103     Encodeb(0xC3);
2104 }
2105 
2106 /* leave */
Leave()2107 void ElfAssembler::Leave()
2108 {
2109     Encodeb(0xC9);
2110 }
2111 
2112 /* imul */
Imul(InsnSize insnSize,Reg srcReg,Reg destReg)2113 void ElfAssembler::Imul(InsnSize insnSize, Reg srcReg, Reg destReg)
2114 {
2115     OpRR(destReg, srcReg, 0x0F, 0xAF);
2116 }
2117 
2118 /* mul float */
Mul(Reg srcReg,Reg destReg,bool isSingle)2119 void ElfAssembler::Mul(Reg srcReg, Reg destReg, bool isSingle)
2120 {
2121     if (isSingle) {
2122         Encodeb(0xF3);
2123     } else {
2124         Encodeb(0xF2);
2125     }
2126     OpRR(destReg, srcReg, 0x0F, 0x59);
2127 }
2128 
Mul(const Mem & mem,Reg reg,bool isSingle)2129 void ElfAssembler::Mul(const Mem &mem, Reg reg, bool isSingle)
2130 {
2131     if (isSingle) {
2132         Encodeb(0xF3);
2133     } else {
2134         Encodeb(0xF2);
2135     }
2136     OpRM(reg, mem, 0x0F, 0x59);
2137 }
2138 
2139 /* nop */
Nop(InsnSize insnSize,const Mem & mem)2140 void ElfAssembler::Nop(InsnSize insnSize, const Mem &mem)
2141 {
2142     OpMem(mem, 0x0E, 0x1F, 0);
2143 }
2144 
Nop()2145 void ElfAssembler::Nop()
2146 {
2147     Encodeb(0x90);
2148 }
2149 
2150 /* byte swap */
Bswap(InsnSize insnSize,Reg reg)2151 void ElfAssembler::Bswap(InsnSize insnSize, Reg reg)
2152 {
2153     uint8 rex = GetRex(reg);
2154     if (rex != 0) {
2155         Encodeb(rex);
2156     }
2157     Encodeb(0x0F);
2158     Encodeb(0xC8 | GetRegCodeId(reg));
2159 }
2160 
Xchg(InsnSize insnSize,Reg srcReg,Reg destReg)2161 void ElfAssembler::Xchg(InsnSize insnSize, Reg srcReg, Reg destReg)
2162 {
2163     /* if the reg is ax, eax or rax */
2164     if ((GetRegId(srcReg) == 0 || GetRegId(destReg) == 0) && GetRegSize(srcReg) != k8Bits) {
2165         uint8 rex = GetRex(srcReg, destReg);
2166         if (rex != 0) {
2167             Encodeb(rex);
2168         } else if (GetRegSize(srcReg) == k16Bits) {
2169             Encodeb(0x66);
2170         }
2171         uint8 regCodeId = GetRegId(srcReg) == 0 ? GetRegCodeId(destReg) : GetRegCodeId(srcReg);
2172         Encodeb(0x90 | regCodeId);
2173     } else {
2174         OpRR(srcReg, destReg, 0x86);
2175     }
2176 }
2177 
2178 /* floating point */
MovF(Reg srcReg,Reg destReg,bool isSingle)2179 void ElfAssembler::MovF(Reg srcReg, Reg destReg, bool isSingle)
2180 {
2181     bool isXMM = GetRegSize(srcReg) == k128Bits || GetRegSize(destReg) == k128Bits;
2182     if (isSingle) {
2183         if (isXMM) {
2184             Encodeb(0xF3);
2185         }
2186         OpRR(destReg, srcReg, 0x0F, 0x10);
2187     } else {
2188         if (isXMM) {
2189             Encodeb(0xF2);
2190         }
2191         OpRR(destReg, srcReg, 0x0F, 0x10);
2192     }
2193 }
2194 
2195 /* floating point and */
And(Reg srcReg,Reg destReg,bool isSingle)2196 void ElfAssembler::And(Reg srcReg, Reg destReg, bool isSingle)
2197 {
2198     if (isSingle) {
2199         Encodeb(0x100);
2200     } else {
2201         Encodeb(0x66);
2202     }
2203     OpRR(destReg, srcReg, 0x0F, 0x54);
2204 }
2205 
And(const Mem & mem,Reg reg,bool isSingle)2206 void ElfAssembler::And(const Mem &mem, Reg reg, bool isSingle)
2207 {
2208     if (isSingle) {
2209         Encodeb(0x100);
2210     } else {
2211         Encodeb(0x66);
2212     }
2213     OpRM(reg, mem, 0x0F, 0x54);
2214 }
2215 
2216 /* floating div */
Divsd(Reg srcReg,Reg destReg)2217 void ElfAssembler::Divsd(Reg srcReg, Reg destReg)
2218 {
2219     Encodeb(0xF2);
2220     OpRR(destReg, srcReg, 0x0F, 0x5E);
2221 }
2222 
Divsd(const Mem & mem,Reg reg)2223 void ElfAssembler::Divsd(const Mem &mem, Reg reg)
2224 {
2225     Encodeb(0xF2);
2226     OpRM(reg, mem, 0x0F, 0x5E);
2227 }
2228 
2229 /* convert int2float */
Cvtsi2ss(InsnSize insnSize,Reg srcReg,Reg destReg)2230 void ElfAssembler::Cvtsi2ss(InsnSize insnSize, Reg srcReg, Reg destReg)
2231 {
2232     Encodeb(0xF3);
2233     OpRR(destReg, srcReg, 0x0F, 0x2A);
2234 }
2235 
Cvtsi2sd(InsnSize insnSize,Reg srcReg,Reg destReg)2236 void ElfAssembler::Cvtsi2sd(InsnSize insnSize, Reg srcReg, Reg destReg)
2237 {
2238     Encodeb(0xF2);
2239     OpRR(destReg, srcReg, 0x0F, 0x2A);
2240 }
2241 
2242 /*convert float2int */
Cvttsd2si(InsnSize insnSize,Reg srcReg,Reg destReg)2243 void ElfAssembler::Cvttsd2si(InsnSize insnSize, Reg srcReg, Reg destReg)
2244 {
2245     Encodeb(0xF2);
2246     OpRR(destReg, srcReg, 0x0F, 0x2C);
2247 }
2248 
Cvttss2si(InsnSize insnSize,Reg srcReg,Reg destReg)2249 void ElfAssembler::Cvttss2si(InsnSize insnSize, Reg srcReg, Reg destReg)
2250 {
2251     Encodeb(0xF3);
2252     OpRR(destReg, srcReg, 0x0F, 0x2C);
2253 }
2254 
2255 /* convert float2float */
Cvtss2sd(Reg srcReg,Reg destReg)2256 void ElfAssembler::Cvtss2sd(Reg srcReg, Reg destReg)
2257 {
2258     Encodeb(0xF3);
2259     OpRR(destReg, srcReg, 0x0F, 0x5A);
2260 }
2261 
Cvtsd2ss(Reg srcReg,Reg destReg)2262 void ElfAssembler::Cvtsd2ss(Reg srcReg, Reg destReg)
2263 {
2264     Encodeb(0xF2);
2265     OpRR(destReg, srcReg, 0x0F, 0x5A);
2266 }
2267 
2268 /* unordered compare */
Ucomisd(Reg srcReg,Reg destReg)2269 void ElfAssembler::Ucomisd(Reg srcReg, Reg destReg)
2270 {
2271     Encodeb(0x66);
2272     OpRR(destReg, srcReg, 0x0F, 0x2E);
2273 }
2274 
Ucomiss(Reg srcReg,Reg destReg)2275 void ElfAssembler::Ucomiss(Reg srcReg, Reg destReg)
2276 {
2277     Encodeb(0x100);
2278     OpRR(destReg, srcReg, 0x0F, 0x2E);
2279 }
2280 
Cmpsd(Reg srcReg,Reg destReg,uint8 imm)2281 void ElfAssembler::Cmpsd(Reg srcReg, Reg destReg, uint8 imm)
2282 {
2283     Encodeb(0xF2);
2284     OpRR(destReg, srcReg, 0x0F, 0xC2);
2285     Encodeb(imm);
2286 }
2287 
Cmpeqsd(Reg srcReg,Reg destReg)2288 void ElfAssembler::Cmpeqsd(Reg srcReg, Reg destReg)
2289 {
2290     Cmpsd(srcReg, destReg, 0);
2291 }
2292 
2293 /* float sqrt*/
Sqrtss_r(Reg srcReg,Reg destReg)2294 void ElfAssembler::Sqrtss_r(Reg srcReg, Reg destReg)
2295 {
2296     Encodeb(0xF3);
2297     OpRR(destReg, srcReg, 0x0F, 0x51);
2298 }
2299 
Sqrtsd_r(Reg srcReg,Reg destReg)2300 void ElfAssembler::Sqrtsd_r(Reg srcReg, Reg destReg)
2301 {
2302     Encodeb(0xF2);
2303     OpRR(destReg, srcReg, 0x0F, 0x51);
2304 }
2305 /* end of X64 instructions */
2306 
2307 /* process stackmap */
RecordStackmap(const std::vector<uint64> & referenceMap,const std::vector<uint64> & deoptVreg2LocationInfo)2308 void ElfAssembler::RecordStackmap(const std::vector<uint64> &referenceMap,
2309                                   const std::vector<uint64> &deoptVreg2LocationInfo)
2310 {
2311     const auto &emitMemoryManager = maplebe::CGOptions::GetInstance().GetEmitMemoryManager();
2312     if (emitMemoryManager.codeSpace == nullptr) {
2313         return;
2314     }
2315     emitMemoryManager.pc2CallSiteInfoSaver(emitMemoryManager.codeSpace, lastModulePC + codeBuff.size(), referenceMap);
2316     emitMemoryManager.pc2DeoptInfoSaver(emitMemoryManager.codeSpace, lastModulePC + codeBuff.size(),
2317                                         deoptVreg2LocationInfo);
2318 }
2319 
GetCurModulePC()2320 uint32 ElfAssembler::GetCurModulePC()
2321 {
2322     return static_cast<uint32>(lastModulePC + codeBuff.size());
2323 }
2324 
SetLastModulePC(uint32 pc)2325 void ElfAssembler::SetLastModulePC(uint32 pc)
2326 {
2327     lastModulePC = pc;
2328 }
2329 } /* namespace assembler */