• 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     AppendGlobalSymsToSymTabSec();
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     DEBUG_ASSERT(sections.size() > 0, "must not be zero");
662     section.SetIndex(static_cast<SectionIndex>(sections.size() - 1));
663 }
664 
LayoutSections()665 void ElfAssembler::LayoutSections()
666 {
667     globalOffset = sizeof(FileHeader);
668     globalOffset = Alignment::Align<Offset>(globalOffset, k8Bits);
669 
670     for (auto *section : sections) {
671         section->SetSectionHeaderNameIndex(static_cast<Word>(strTabSection->AddString(section->GetName())));
672     }
673 
674     for (auto *section : sections) {
675         globalOffset = Alignment::Align<Offset>(globalOffset, section->GetAlign());
676         /* lay out section */
677         UpdateSectionOffset(*section);
678         if (section->GetType() != SHT_NOBITS) {
679             section->GenerateData();
680         }
681         UpdateGlobalOffset(*section);
682     }
683 
684     globalOffset = Alignment::Align<Offset>(globalOffset, 16U);
685     header.e_shoff = globalOffset;
686     header.e_shnum = static_cast<uint16>(sections.size());
687 }
688 
UpdateSectionOffset(Section & section)689 void ElfAssembler::UpdateSectionOffset(Section &section)
690 {
691     if (section.GetType() != SHT_NOBITS) {
692         section.SetOffset(globalOffset);
693     } else {
694         section.SetOffset(0);
695     }
696 }
697 
UpdateGlobalOffset(Section & section)698 void ElfAssembler::UpdateGlobalOffset(Section &section)
699 {
700     if (section.GetType() != SHT_NOBITS) {
701         globalOffset += section.GetSectionSize();
702     }
703 }
704 
SetFileOffset(uint64 offset)705 void ElfAssembler::SetFileOffset(uint64 offset)
706 {
707     (void)outStream.seekp(offset);
708 }
709 
710 /* symIdx is the key used to get symbol's index in .symtab */
AddSymToSymTab(const Symbol & symbol,int64 symIdx)711 void ElfAssembler::AddSymToSymTab(const Symbol &symbol, int64 symIdx)
712 {
713     const int kGetHigh4Bits = 4;
714     if ((symbol.st_info >> kGetHigh4Bits) == STB_LOCAL) {
715         localSymTab.push_back(std::make_pair(symbol, symIdx));
716     } else {
717         symTab.push_back(std::make_pair(symbol, symIdx));
718     }
719 }
720 
AppendRela(const Label & label,const std::pair<uint32,size_t> & offsetPair,uint64 type,Sxword addend)721 void ElfAssembler::AppendRela(const Label &label, const std::pair<uint32, size_t> &offsetPair, uint64 type,
722                               Sxword addend)
723 {
724     LabelType labelType = label.GetLabelType();
725     int64 relOffset = static_cast<int64>(label.GetRelOffset());
726     uint64 offset = static_cast<uint64>(offsetPair.first);
727     int64 offsetSize = static_cast<int64>(offsetPair.second);
728     if (labelType == LabelType::kConst) {
729         int64 rodataSecSymIdx = ~rodataSection->GetIndex() + 1;
730         relaSection->AppendRela(
731             {offset,
732              static_cast<Xword>((symbolTabSection->GetIdxInSymbols(rodataSecSymIdx) << kLeftShift32Bits) +
733                                 (type & 0xffffffff)),
734              relOffset});
735     } else if (labelType == LabelType::kGlobal) {
736         addend -= offsetSize;
737         relaSection->AppendRela(
738             {offset,
739              static_cast<Xword>((symbolTabSection->GetIdxInSymbols(label.GetlabelIdx()) << kLeftShift32Bits) +
740                                 (type & 0xffffffff)),
741              addend});
742     } else if (labelType == LabelType::kStatic) {
743         addend += relOffset - offsetSize;
744         int64 dataSecSymIdx = ~dataSection->GetIndex() + 1;
745         relaSection->AppendRela(
746             {offset,
747              static_cast<Xword>((symbolTabSection->GetIdxInSymbols(dataSecSymIdx) << kLeftShift32Bits) +
748                                 (type & 0xffffffff)),
749              addend});
750     } else if (labelType == LabelType::kLocalUninitialized) {
751         addend = addend + relOffset - offsetSize;
752         int64 bssSecSymIdx = ~bssSection->GetIndex() + 1;
753         relaSection->AppendRela(
754             {offset,
755              static_cast<Xword>((symbolTabSection->GetIdxInSymbols(bssSecSymIdx) << kLeftShift32Bits) +
756                                 (type & 0xffffffff)),
757              addend});
758     } else if (labelType == LabelType::kGlobalUninitialized) {
759         addend = addend - offsetSize;
760         relaSection->AppendRela(
761             {offset,
762              static_cast<Xword>((symbolTabSection->GetIdxInSymbols(label.GetlabelIdx()) << kLeftShift32Bits) +
763                                 (type & 0xffffffff)),
764              addend});
765     } else if (labelType == LabelType::kJmpLabel) {
766         type = R_X86_64_32;
767         addend = relOffset;
768         int64 textSecSymIdx = ~textSection->GetIndex() + 1;
769         relaSection->AppendRela(
770             {offset,
771              static_cast<Xword>((symbolTabSection->GetIdxInSymbols(textSecSymIdx) << kLeftShift32Bits) +
772                                 (type & 0xffffffff)),
773              addend});
774     } else if (labelType == LabelType::kBBLabel) {
775         addend = relOffset;
776         int64 textSecSymIdx = ~textSection->GetIndex() + 1;
777         relaSection->AppendRela(
778             {offset,
779              static_cast<Xword>((symbolTabSection->GetIdxInSymbols(textSecSymIdx) << kLeftShift32Bits) +
780                                 (type & 0xffffffff)),
781              addend});
782     } else if (labelType == LabelType::kFunc ||
783                (label.GetRelOffset() == 0xFFFFFFFFU && labelType == LabelType::kLNone)) {
784         int64 labelIdx = label.GetlabelIdx();
785         if (!symbolTabSection->ExistSymInSymbols(labelIdx)) {
786             symbolTabSection->AppendIdxInSymbols(labelIdx);
787         }
788         relaSection->AppendRela({offsetPair.first,
789                                  static_cast<Xword>((symbolTabSection->GetIdxInSymbols(labelIdx) << kLeftShift32Bits) +
790                                                     (type & 0xffffffff)),
791                                  addend});
792     } else {
793         assert(false && "unsupported label type in func AddRela");
794     }
795 }
796 
GetRelaType(FixupKind kind) const797 uint64 ElfAssembler::GetRelaType(FixupKind kind) const
798 {
799     switch (kind) {
800         case kRelative:
801             return R_X86_64_PC32;
802         case kRelative64:
803             return R_X86_64_PC64;
804         case kAbsolute:
805             return R_X86_64_32;
806         case kAbsolute64:
807             return R_X86_64_64;
808         case kPLT:
809             return R_X86_64_PLT32;
810         case kFNone:
811             return R_X86_64_NONE;
812     }
813 }
814 
HandleTextSectionFixup()815 void ElfAssembler::HandleTextSectionFixup()
816 {
817     if (!fixups.empty()) {
818         relaSection =
819             new RelaSection(".rela.text", SHT_RELA, SHF_INFO_LINK, textSection->GetIndex(), k8Bits, *symbolTabSection);
820         RegisterSection(*relaSection);
821     }
822 
823     for (auto fixup : fixups) {
824         int64 labelIdx = fixup->GetlabelIdx();
825         if (labelManager.count(labelIdx) == 0) {
826             continue;
827         }
828 
829         const std::pair<uint32, size_t> &offsetPair = fixup->GetOffset();
830         Label *label = labelManager.at(labelIdx);
831         uint32 relOffset = label->GetRelOffset();
832         LabelType labelType = label->GetLabelType();
833 
834         FixupKind fixupKind = fixup->GetFixupKind();
835         if ((fixupKind == kRelative || fixupKind == kRelative64) &&
836             (labelType == LabelType::kBBLabel || labelType == LabelType::kFunc)) {
837             FixupEncode(offsetPair.first, relOffset, offsetPair.second);
838             fixup->SetFixupKind(kFNone);
839         }
840 
841         if (relOffset != 0xFFFFFFFFU && fixupKind == kPLT) {
842             FixupEncode(offsetPair.first, relOffset, offsetPair.second);
843             fixup->SetFixupKind(kFNone);
844         }
845 
846         fixupKind = fixup->GetFixupKind();
847         uint64 type = GetRelaType(fixupKind);
848         int64 addend = (fixupKind == kAbsolute || fixupKind == kAbsolute64) ? 0 : -0x4;
849         if (fixupKind != kFNone) {
850             addend = labelType == LabelType::kGlobalUninitialized || labelType == LabelType::kLocalUninitialized ||
851                              labelType == LabelType::kGlobal || labelType == LabelType::kStatic
852                          ? fixup->GetDisp()
853                          : addend;
854             AppendRela(*label, offsetPair, type, addend);
855         }
856     }
857     textSection->AppendData(codeBuff.data(), codeBuff.size());
858 }
859 
HandleDataSectionFixup()860 void ElfAssembler::HandleDataSectionFixup()
861 {
862     if (!dataFixups.empty()) {
863         relaDataSection =
864             new RelaSection(".rela.data", SHT_RELA, SHF_INFO_LINK, dataSection->GetIndex(), k8Bits, *symbolTabSection);
865         RegisterSection(*relaDataSection);
866     }
867     for (auto fixup : dataFixups) {
868         int64 labelIdx = fixup->GetlabelIdx();
869         std::pair<uint32, size_t> offset = fixup->GetOffset();
870         const uint32 relocType = R_X86_64_64;
871         if (labelManager.count(labelIdx) == 0) {
872             continue;
873         }
874         Label *label = labelManager.at(labelIdx);
875         LabelType labelType = label->GetLabelType();
876         int64 addend = 0;
877         int64 relOffset = static_cast<int64>(label->GetRelOffset());
878         if (labelType == LabelType::kGlobalUninitialized) {
879             addend = fixup->GetDisp();
880             uint64 pos = symbolTabSection->GetIdxInSymbols(labelIdx);
881             relaDataSection->AppendRela(
882                 {offset.first, static_cast<Xword>((pos << kLeftShift32Bits) + (relocType & 0xffffffff)), addend});
883         } else if (labelType == LabelType::kLocalUninitialized) {
884             addend = fixup->GetDisp();
885             int64 bssSecSymIdx = ~bssSection->GetIndex() + 1;
886             relaDataSection->AppendRela(
887                 {offset.first,
888                  static_cast<Xword>((symbolTabSection->GetIdxInSymbols(bssSecSymIdx) << kLeftShift32Bits) +
889                                     (relocType & 0xffffffff)),
890                  addend});
891         } else if (labelType == LabelType::kFunc) {
892             uint64 pos = symbolTabSection->GetIdxInSymbols(labelIdx);
893             relaDataSection->AppendRela(
894                 {offset.first, static_cast<Xword>((pos << kLeftShift32Bits) + (relocType & 0xffffffff)), addend});
895         } else if (labelType == LabelType::kStrLabel || labelType == LabelType::kGlobal ||
896                    labelType == LabelType::kStatic) {
897             uint64 pos = symbolTabSection->GetIdxInSymbols(~dataSection->GetIndex() + 1);
898             addend = (labelType == LabelType::kGlobal || labelType == LabelType::kStatic) ? fixup->GetDisp() + relOffset
899                                                                                           : relOffset;
900             relaDataSection->AppendRela(
901                 {offset.first, static_cast<Xword>((pos << kLeftShift32Bits) + (relocType & 0xffffffff)), addend});
902         } else {
903             addend = relOffset;
904             int64 textSecSymIdx = ~textSection->GetIndex() + 1;
905             relaDataSection->AppendRela(
906                 {offset.first,
907                  static_cast<Xword>((symbolTabSection->GetIdxInSymbols(textSecSymIdx) << kLeftShift32Bits) +
908                                     (relocType & 0xffffffff)),
909                  addend});
910         }
911     }
912 }
913 
HandleRodataSectionFixup()914 void ElfAssembler::HandleRodataSectionFixup()
915 {
916     if (!rodataFixups.empty()) {
917         relaRodataSection = new RelaSection(".rela.rodata", SHT_RELA, SHF_INFO_LINK, rodataSection->GetIndex(), k8Bits,
918                                             *symbolTabSection);
919         RegisterSection(*relaRodataSection);
920     }
921     for (auto fixup : rodataFixups) {
922         int64 labelIdx = fixup->GetlabelIdx();
923         std::pair<uint32, size_t> offset = fixup->GetOffset();
924         const uint32 relocType = R_X86_64_64;
925         if (labelManager.count(labelIdx) == 0) {
926             continue;
927         }
928         Label *label = labelManager.at(labelIdx);
929         LabelType labelType = label->GetLabelType();
930         int64 addend = 0;
931         int64 relOffset = static_cast<int64>(label->GetRelOffset());
932         if (labelType == LabelType::kGlobalUninitialized || labelType == LabelType::kLocalUninitialized) {
933             addend = relOffset;
934             uint64 pos = symbolTabSection->GetIdxInSymbols(~textSection->GetIndex() + 1);
935             relaRodataSection->AppendRela(
936                 {offset.first, static_cast<Xword>((pos << kLeftShift32Bits) + (relocType & 0xffffffff)), addend});
937         }
938     }
939 }
940 
WriteElfFile()941 void ElfAssembler::WriteElfFile()
942 {
943     /* Init elf file header */
944     InitElfHeader();
945 
946     LayoutSections();
947 
948     const auto &emitMemoryManager = maplebe::CGOptions::GetInstance().GetEmitMemoryManager();
949     if (emitMemoryManager.codeSpace != nullptr) {
950         DEBUG_ASSERT(textSection != nullptr, "textSection has not been initialized");
951         uint8 *codeSpace = emitMemoryManager.allocateDataSection(emitMemoryManager.codeSpace,
952             textSection->GetSectionSize(), textSection->GetAlign(), textSection->GetName());
953         auto ret = memcpy_s(
954             codeSpace, textSection->GetSectionSize(), textSection->GetData().data(), textSection->GetDataSize());
955         CHECK_FATAL(ret == EOK, "memcpy failed");
956         if (CGOptions::addFuncSymbol()) {
957             uint8 *symtabSpace = emitMemoryManager.allocateDataSection(emitMemoryManager.codeSpace,
958                 symbolTabSection->GetDataSize(), symbolTabSection->GetAlign(), symbolTabSection->GetName().c_str());
959             ret = memcpy_s(symtabSpace,
960                 symbolTabSection->GetDataSize(),
961                 symbolTabSection->GetAddr(),
962                 symbolTabSection->GetDataSize());
963             CHECK_FATAL(ret == EOK, "memcpy failed");
964             uint8 *stringTabSpace = emitMemoryManager.allocateDataSection(emitMemoryManager.codeSpace,
965                 strTabSection->GetDataSize(),
966                 strTabSection->GetAlign(),
967                 strTabSection->GetName().c_str());
968             ret = memcpy_s(stringTabSpace,
969                 strTabSection->GetDataSize(),
970                 strTabSection->GetData().data(),
971                 strTabSection->GetDataSize());
972             CHECK_FATAL(ret == EOK, "memcpy failed");
973         }
974         return;
975     }
976 
977     /* write header */
978     Emit(&header, sizeof(header));
979 
980     /* write sections */
981     for (auto *section : sections) {
982         if (section->GetType() == SHT_NOBITS) {
983             continue;
984         }
985         SetFileOffset(section->GetOffset());
986         section->WriteSection(outFStream);
987     }
988 
989     /* write section table */
990     SetFileOffset(header.e_shoff);
991     for (auto *section : sections) {
992         Emit(&section->GetSectionHeader(), sizeof(section->GetSectionHeader()));
993     }
994 }
995 
996 /* Append the symbol of non-empty and necessary section to symbol table section. */
AppendSecSymsToSymTabSec()997 void ElfAssembler::AppendSecSymsToSymTabSec()
998 {
999     for (Section *section : sections) {
1000         if (section->GetType() != SHT_PROGBITS && section->GetType() != SHT_NOBITS) {
1001             continue;
1002         }
1003         DataSection *dataSec = static_cast<DataSection *>(section);
1004         if (section->GetFlags() == (SHF_ALLOC | SHF_EXECINSTR) || section->GetSectionSize() != 0 ||
1005             (dataSec != nullptr && dataSec->GetDataSize() != 0)) {
1006             auto nameIndex = strTabSection->AddString(section->GetName());
1007             symbolTabSection->AppendSymbol({static_cast<Word>(nameIndex),
1008                                             static_cast<uint8>((STB_LOCAL << kLeftShift4Bits) + (STT_SECTION & 0xf)), 0,
1009                                             section->GetIndex(), 0, 0});
1010             /* Indexed by the inverse of the section index. */
1011             int64 secSymIdx = ~section->GetIndex() + 1;
1012             symbolTabSection->AppendIdxInSymbols(secSymIdx);
1013         }
1014     }
1015 }
1016 
AppendGlobalSymsToSymTabSec()1017 void ElfAssembler::AppendGlobalSymsToSymTabSec()
1018 {
1019     for (auto elem : symTab) {
1020         const Symbol &symbol = elem.first;
1021         int64 symIdx = elem.second;
1022         symbolTabSection->AppendSymbol(symbol);
1023         symbolTabSection->AppendIdxInSymbols(symIdx);
1024     }
1025 }
1026 
AppendSymsToSymTabSec()1027 void ElfAssembler::AppendSymsToSymTabSec()
1028 {
1029     /* emit local symbol */
1030     for (auto elem : localSymTab) {
1031         Symbol symbol = elem.first;
1032         int64 symIdx = elem.second;
1033         symbolTabSection->AppendSymbol(symbol);
1034         symbolTabSection->AppendIdxInSymbols(symIdx);
1035     }
1036 
1037     /* Append section symbol that may be used in relocation item, section is local. */
1038     AppendSecSymsToSymTabSec();
1039 
1040     /* set .symtab's info : index of the first non-local symbol */
1041     symbolTabSection->SetInfo(symbolTabSection->GetSymbolsSize());
1042 
1043     /* emit global and other symbol */
1044     for (auto elem : symTab) {
1045         const Symbol &symbol = elem.first;
1046         int64 symIdx = elem.second;
1047         symbolTabSection->AppendSymbol(symbol);
1048         symbolTabSection->AppendIdxInSymbols(symIdx);
1049     }
1050 }
1051 
1052 /* emit debug info */
EmitDIDebugInfoSectionHeader(uint64 debugInfoLength)1053 void ElfAssembler::EmitDIDebugInfoSectionHeader(uint64 debugInfoLength)
1054 {
1055     debugInfoSection = new DataSection(".debug_info", SHT_PROGBITS, 0, 1);
1056     RegisterSection(*debugInfoSection);
1057     /* length of .debug_info section, 4 bytes */
1058     size_t debugInfoLenSize = 4;
1059     debugInfoSection->AppendData(static_cast<int64>(debugInfoLength), debugInfoLenSize);
1060     size_t dwarfVersionSize = 2;
1061     /* DWARF version, 2 bytes */
1062     debugInfoSection->AppendData(static_cast<int64>(kDwarfVersion), dwarfVersionSize);
1063     /* debug_abbrev_offset. 4 bytes for dwarf32, 8 bytes for dwarf64 */
1064     int64 debugAbbrevOffset = 0;
1065     size_t debugAbbrevOffsetSize = 4;
1066     /* If labelSymIdx equals LLONG_MAX, there is not a real label bound to the fixup. */
1067     AppendFixup(LLONG_MAX, kAbsolute, {debugInfoSection->GetDataSize(), debugAbbrevOffsetSize}, debugInfoFixups);
1068     debugInfoSection->AppendData(debugAbbrevOffset, debugAbbrevOffsetSize);
1069     /* address size. 1 byte */
1070     size_t byteOfkSizeOfPTR = 1;
1071     debugInfoSection->AppendData(kSizeOfPTR, byteOfkSizeOfPTR);
1072 }
1073 
EmitDIDebugInfoSectionAbbrevId(bool verbose,uint32 abbrevId,const std::string & dieTagName,uint32 offset,uint32 size)1074 void ElfAssembler::EmitDIDebugInfoSectionAbbrevId(bool verbose, uint32 abbrevId, const std::string &dieTagName,
1075                                                   uint32 offset, uint32 size)
1076 {
1077     auto abbrevIdUleb128 = EncodeULEB128(abbrevId);
1078     debugInfoSection->AppendData(&abbrevIdUleb128, abbrevIdUleb128.size());
1079 }
1080 
1081 /* EmitDIAttrValue */
EmitDwFormString(const std::string & name)1082 void ElfAssembler::EmitDwFormString(const std::string &name)
1083 {
1084     debugInfoSection->AppendData(&name, name.size());
1085 }
1086 
EmitDwFormStrp(uint32 strLabelId,size_t strTableSize)1087 void ElfAssembler::EmitDwFormStrp(uint32 strLabelId, size_t strTableSize)
1088 {
1089     int64 labelSymIdx = CalculateStrLabelSymIdx(static_cast<int64>(strLabelId), static_cast<int64>(strTableSize));
1090     UpdateLabel(labelSymIdx, LabelType::kDebugStrLabel);
1091     int64 strLabelOffset = 0;
1092     size_t strLabelOffsetSize = 4;
1093     AppendFixup(labelSymIdx, kAbsolute, {debugInfoSection->GetDataSize(), strLabelOffsetSize}, debugInfoFixups);
1094     debugInfoSection->AppendData(strLabelOffset, strLabelOffsetSize);
1095 }
1096 
EmitDwFormData(int32 attrValue,uint8 sizeInByte)1097 void ElfAssembler::EmitDwFormData(int32 attrValue, uint8 sizeInByte)
1098 {
1099     debugInfoSection->AppendData(attrValue, sizeInByte);
1100 }
1101 
EmitDwFormData8()1102 void ElfAssembler::EmitDwFormData8()
1103 {
1104     int64 addr = 0;
1105     size_t addrSizeInByte = 8;
1106     debugInfoSection->AppendData(addr, addrSizeInByte);
1107 }
1108 
EmitDwFormData8(uint32 endLabelFuncPuIdx,uint32 startLabelFuncPuIdx,uint32 endLabelIdx,uint32 startLabelIdx)1109 void ElfAssembler::EmitDwFormData8(uint32 endLabelFuncPuIdx, uint32 startLabelFuncPuIdx, uint32 endLabelIdx,
1110                                    uint32 startLabelIdx)
1111 {
1112     int64 addr = 0;
1113     size_t addrSizeInByte = 8;
1114     debugInfoSection->AppendData(addr, addrSizeInByte);
1115 }
1116 
EmitLabel(uint32 funcPuIdx,uint32 labIdx)1117 void ElfAssembler::EmitLabel(uint32 funcPuIdx, uint32 labIdx)
1118 {
1119     int64 labSymIdx = CalculateLabelSymIdx(funcPuIdx, labIdx);
1120     UpdateLabel(labIdx);
1121     int64 addr = 0;
1122     size_t addrSizeInByte = 8;
1123     AppendFixup(labSymIdx, kAbsolute64, {debugInfoSection->GetDataSize(), addrSizeInByte}, debugInfoFixups);
1124     debugInfoSection->AppendData(addr, addrSizeInByte);
1125 }
1126 
EmitDwFormSecOffset()1127 void ElfAssembler::EmitDwFormSecOffset()
1128 {
1129     int64 lineLabelOffset = 0;
1130     size_t lineLabelOffsetSize = 4;
1131     /* If labelSymIdx equals  - 2, there is not a real label bound to the fixup. */
1132     AppendFixup(LLONG_MAX - 2, kAbsolute, {debugInfoSection->GetDataSize(), lineLabelOffsetSize}, debugInfoFixups);
1133     debugInfoSection->AppendData(lineLabelOffset, lineLabelOffsetSize);
1134 }
1135 
EmitDwFormAddr(bool emitTextBegin)1136 void ElfAssembler::EmitDwFormAddr(bool emitTextBegin)
1137 {
1138     if (emitTextBegin) {
1139         int64 addr = 0;
1140         size_t addrSizeInByte = 8;
1141         /* If labelSymIdx equals LLONG_MAX - 1, there is not a real label bound to the fixup. */
1142         AppendFixup(LLONG_MAX - 1, kAbsolute64, {debugInfoSection->GetDataSize(), addrSizeInByte}, debugInfoFixups);
1143         debugInfoSection->AppendData(addr, addrSizeInByte);
1144     }
1145 }
1146 
EmitDwFormRef4(uint64 offsetOrValue,bool unknownType,bool emitOffset)1147 void ElfAssembler::EmitDwFormRef4(uint64 offsetOrValue, bool unknownType, bool emitOffset)
1148 {
1149     size_t offsetOrValueSize = 4;
1150     debugInfoSection->AppendData(static_cast<int64>(offsetOrValue), offsetOrValueSize);
1151 }
1152 
EmitDwFormExprlocCfa(uint32 dwOp)1153 void ElfAssembler::EmitDwFormExprlocCfa(uint32 dwOp)
1154 {
1155     debugInfoSection->AppendData(1, 1);
1156     debugInfoSection->AppendData(static_cast<int64>(dwOp), 1);
1157 }
1158 
EmitDwFormExprlocAddr(uint32 dwOp,const std::string & addrStr)1159 void ElfAssembler::EmitDwFormExprlocAddr(uint32 dwOp, const std::string &addrStr)
1160 {
1161     debugInfoSection->AppendData(static_cast<int64>(k9ByteSize), 1);
1162     debugInfoSection->AppendData(static_cast<int64>(dwOp), 1);
1163     size_t addStrSize = 8;
1164     debugInfoSection->AppendData(&addrStr, addStrSize);
1165 }
1166 
EmitDwFormExprlocFbreg(uint32 dwOp,int fboffset,size_t sleb128Size)1167 void ElfAssembler::EmitDwFormExprlocFbreg(uint32 dwOp, int fboffset, size_t sleb128Size)
1168 {
1169     auto sleb128SizeEncode = EncodeSLEB128(1 + static_cast<int64>(sleb128Size));
1170     debugInfoSection->AppendData(&sleb128SizeEncode, sleb128SizeEncode.size());
1171     debugInfoSection->AppendData(static_cast<int64>(dwOp), 1);
1172     auto fboffsetSleb128 = EncodeSLEB128(fboffset);
1173     debugInfoSection->AppendData(&fboffsetSleb128, fboffsetSleb128.size());
1174 }
1175 
EmitDwFormExprlocBregn(uint32 dwOp,const std::string & dwOpName)1176 void ElfAssembler::EmitDwFormExprlocBregn(uint32 dwOp, const std::string &dwOpName)
1177 {
1178     debugInfoSection->AppendData(static_cast<int64>(k2Bytes), 1);
1179     debugInfoSection->AppendData(static_cast<int64>(dwOp), 1);
1180     debugInfoSection->AppendData(&dwOpName, dwOpName.size());
1181     int64 offset = 0;
1182     debugInfoSection->AppendData(offset, 1);
1183 }
1184 
EmitDwFormExprloc(uintptr elp)1185 void ElfAssembler::EmitDwFormExprloc(uintptr elp)
1186 {
1187     auto elpUleb128 = EncodeULEB128(elp);
1188     debugInfoSection->AppendData(&elpUleb128, elpUleb128.size());
1189 }
1190 
EmitDIDebugAbbrevDiae(bool verbose,uint32 abbrevId,uint32 tag,const std::string & dwTagName,bool withChildren)1191 void ElfAssembler::EmitDIDebugAbbrevDiae(bool verbose, uint32 abbrevId, uint32 tag, const std::string &dwTagName,
1192                                          bool withChildren)
1193 {
1194     debugAbbrevSection = new DataSection(".debug_abbrev", SHT_PROGBITS, 0, 1);
1195     RegisterSection(*debugAbbrevSection);
1196     /* Abbrev Entry ID */
1197     auto abbrevIdUleb128 = EncodeULEB128(abbrevId);
1198     debugAbbrevSection->AppendData(&abbrevIdUleb128, abbrevIdUleb128.size());
1199     /* TAG */
1200     auto tagUleb128 = EncodeULEB128(tag);
1201     debugAbbrevSection->AppendData(&tagUleb128, tagUleb128.size());
1202     /* children */
1203     auto childrenValue = withChildren ? 1 : 0;
1204     debugAbbrevSection->AppendData(childrenValue, 1);
1205 }
1206 
EmitDIDebugAbbrevDiaePairItem(bool verbose,uint32 aplAt,uint32 aplFrom,const std::string & dwAtName,const std::string & dwFromName)1207 void ElfAssembler::EmitDIDebugAbbrevDiaePairItem(bool verbose, uint32 aplAt, uint32 aplFrom,
1208                                                  const std::string &dwAtName, const std::string &dwFromName)
1209 {
1210     /* odd entry -- DW_AT_*, even entry -- DW_FORM_* */
1211     auto aplAtUleb128 = EncodeULEB128(aplAt);
1212     debugAbbrevSection->AppendData(&aplAtUleb128, aplAtUleb128.size());
1213     auto aplFromUleb128 = EncodeULEB128(aplFrom);
1214     debugAbbrevSection->AppendData(&aplFromUleb128, aplFromUleb128.size());
1215 }
1216 
EmitDIDebugSectionEnd(SectionKind secKind)1217 void ElfAssembler::EmitDIDebugSectionEnd(SectionKind secKind)
1218 {
1219     int64 value = 0;
1220     size_t valueSizeInByte = 1;
1221     switch (secKind) {
1222         case kSDebugInfo:
1223             debugInfoSection->AppendData(value, valueSizeInByte);
1224             break;
1225         case kSDebugAbbrev:
1226             debugAbbrevSection->AppendData(value, valueSizeInByte);
1227             break;
1228         case kSBss:
1229         case kSComm:
1230         case kSData:
1231         case kSRodata:
1232         case kSTbss:
1233         case kSTdata:
1234         case kSText:
1235         case kSDebugStr:
1236         default:
1237             assert(false && "unsupport SectionKind in EmitDIDebugSectionEnd");
1238             break;
1239     }
1240 }
1241 
EmitDIDebugStrSection(const std::vector<uint32> & strps,const std::vector<std::string> & debugStrs,uint64 size,size_t strTableSize)1242 void ElfAssembler::EmitDIDebugStrSection(const std::vector<uint32> &strps, const std::vector<std::string> &debugStrs,
1243                                          uint64 size, size_t strTableSize)
1244 {
1245     debugStrSection = new DataSection(".debug_str", SHT_PROGBITS, SHF_MASKPROC, 1);
1246     RegisterSection(*debugStrSection);
1247     for (int i = 0; i < static_cast<int>(debugStrs.size()); i++) {
1248         int64 strLabSymIdx = CalculateStrLabelSymIdx(size, strps[i], strTableSize);
1249         UpdateLabel(strLabSymIdx, LabelType::kDebugStrLabel, debugStrSection->GetDataSize());
1250         debugStrSection->AppendData(&debugStrs[i], debugStrs[i].size());
1251         EmitDIDebugSectionEnd(kSDebugStr);
1252     }
1253 }
1254 
HandleDebugInfoSectionFixup()1255 void ElfAssembler::HandleDebugInfoSectionFixup()
1256 {
1257     if (!debugInfoFixups.empty()) {
1258         relaDebugInfoSection = new RelaSection(".rela.debug_info", SHT_RELA, SHF_INFO_LINK,
1259                                                debugInfoSection->GetIndex(), k8Bits, *symbolTabSection);
1260         RegisterSection(*relaDebugInfoSection);
1261     }
1262     for (auto fixup : debugInfoFixups) {
1263         int64 labelIdx = fixup->GetlabelIdx();
1264         const std::pair<uint32, size_t> &offsetPair = fixup->GetOffset();
1265         FixupKind fixupKind = fixup->GetFixupKind();
1266         uint64 relocType = GetRelaType(fixupKind);
1267         int64 addend = fixup->GetDisp();
1268         int64 textSecSymIdx = ~textSection->GetIndex() + 1;
1269         int64 debugLineSecSymIdx = ~debugLineSection->GetIndex() + 1;
1270         int64 abbrevSecSymIdx = ~debugAbbrevSection->GetIndex() + 1;
1271         uint64 pos = labelIdx == LLONG_MAX
1272                          ? symbolTabSection->GetIdxInSymbols(debugLineSecSymIdx)
1273                          : (labelIdx == LLONG_MAX - 1 ? symbolTabSection->GetIdxInSymbols(textSecSymIdx)
1274                                                       : symbolTabSection->GetIdxInSymbols(abbrevSecSymIdx));
1275         if (!labelManager.count(labelIdx)) {
1276             relaDebugInfoSection->AppendRela(
1277                 {offsetPair.first, static_cast<Xword>((pos << kLeftShift32Bits) + (relocType & 0xffffffff)), addend});
1278             continue;
1279         }
1280         Label *label = labelManager.at(labelIdx);
1281         LabelType labelType = label->GetLabelType();
1282         addend = label->GetRelOffset();
1283         if (labelType == LabelType::kBBLabel) {
1284             pos = symbolTabSection->GetIdxInSymbols(textSecSymIdx);
1285         } else if (labelType == LabelType::kDebugStrLabel) {
1286             pos = symbolTabSection->GetIdxInSymbols(~debugStrSection->GetIndex() + 1);
1287         } else {
1288             assert(false && "unsupport label type in HandleDebugInfoSectionFixup!");
1289         }
1290         relaDebugInfoSection->AppendRela(
1291             {offsetPair.first, static_cast<Xword>((pos << kLeftShift32Bits) + (relocType & 0xffffffff)), addend});
1292     }
1293 }
1294 
1295 /* start of X64 instructions */
1296 /* mov */
Mov(InsnSize insnSize,Reg srcReg,Reg destReg)1297 void ElfAssembler::Mov(InsnSize insnSize, Reg srcReg, Reg destReg)
1298 {
1299     OpRR(srcReg, destReg, 0x88, 0);
1300 }
1301 
Mov(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1302 void ElfAssembler::Mov(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1303 {
1304     bool isSymbol = immOpnd.second;
1305     uint64 imm = static_cast<uint64>(immOpnd.first); /* When isSymbol is true, this is index. */
1306     uint8 regSize = GetRegSize(reg);
1307     uint8 regId = GetRegCodeId(reg);
1308     uint8 code = 0xB0 | ((regSize == k8Bits ? 0 : 1) << kLeftShift3Bits);
1309     if (HasOpndSizePrefix(reg)) {
1310         Encodeb(0x66);
1311     }
1312     if (GetRex(reg) != 0) {
1313         Encodeb(GetRex(reg));
1314     }
1315     if (regSize == k64Bits && (isSymbol || Is32Bits(imm))) {
1316         Encodeb(0xC7);
1317         code = 0xC0;
1318         regSize = k32Bits;
1319     }
1320     size_t offsetSize = isSymbol ? k64Bits : regSize / k8Bits;
1321     Encodeb(code | regId);
1322     if (isSymbol) {
1323         UpdateLabel(immOpnd.first);
1324         AppendFixup(immOpnd.first, kAbsolute64, {static_cast<uint32>(codeBuff.size()), offsetSize}, fixups);
1325         imm = 0;
1326     }
1327     Encodeb(imm, offsetSize);
1328 }
1329 
Mov(InsnSize insnSize,const Mem & mem,Reg reg)1330 void ElfAssembler::Mov(InsnSize insnSize, const Mem &mem, Reg reg)
1331 {
1332     if (GetRegId(reg) == 0 && mem.memType == kOnlyDisp) {
1333         MovRegAndDisp(reg, mem, 0xA0);
1334     } else {
1335         OpRM(reg, mem, 0x8A, 0);
1336     }
1337 }
1338 
Mov(InsnSize insnSize,Reg reg,const Mem & mem)1339 void ElfAssembler::Mov(InsnSize insnSize, Reg reg, const Mem &mem)
1340 {
1341     if (GetRegId(reg) == 0 && mem.memType == kOnlyDisp) {
1342         MovRegAndDisp(reg, mem, 0xA2);
1343     } else {
1344         OpRM(reg, mem, 0x88, 0);
1345     }
1346 }
1347 
Mov(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1348 void ElfAssembler::Mov(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1349 {
1350     bool isSymbol = immOpnd.second;
1351     uint32 imm = static_cast<uint32>(immOpnd.first); /* When isSymbol is true, this is index. */
1352     uint8 immBit = Is8Bits(imm) ? k8Bits : (Is16Bits(imm) ? k16Bits : k32Bits);
1353     if (mem.size == k8Bits) {
1354         immBit = k8Bits;
1355     }
1356     if (immBit == k16Bits && (mem.size == k64Bits || mem.size == k32Bits)) {
1357         immBit = k32Bits; /* if 32/64bit mode, imm val can not use 16-bit. */
1358     }
1359     immBit = isSymbol ? k64Bits : immBit;
1360     size_t immSize = immBit / k8Bits;
1361     OpMem(mem, 0xC6, 0, 0);
1362     if (isSymbol) {
1363         UpdateLabel(immOpnd.first);
1364         AppendFixup(immOpnd.first, kAbsolute64, {static_cast<uint32>(codeBuff.size()), immSize}, fixups);
1365         imm = 0;
1366     }
1367     Encodeb(imm, immSize);
1368 }
1369 
1370 /* floating point mov */
Mov(Reg srcReg,Reg destReg,bool isMovD)1371 void ElfAssembler::Mov(Reg srcReg, Reg destReg, bool isMovD)
1372 {
1373     uint8 srcRegSize = GetRegSize(srcReg);
1374     uint8 destRegSize = GetRegSize(destReg);
1375     if (srcRegSize == k128Bits || destRegSize == k128Bits) {
1376         Encodeb(0x66);
1377     }
1378     if (srcRegSize == k128Bits) {
1379         OpRR(srcReg, destReg, 0x0F, 0x7E);
1380     } else if (destRegSize == k128Bits) {
1381         OpRR(destReg, srcReg, 0x0F, 0x6E);
1382     }
1383 }
1384 
MovF(const Mem & mem,Reg reg,bool isSingle)1385 void ElfAssembler::MovF(const Mem &mem, Reg reg, bool isSingle)
1386 {
1387     if (isSingle) {
1388         Encodeb(0xF3);
1389     } else {
1390         Encodeb(0xF2);
1391     }
1392     OpRM(reg, mem, 0x0F, 0x10);
1393 }
1394 
MovF(Reg reg,const Mem & mem,bool isSingle)1395 void ElfAssembler::MovF(Reg reg, const Mem &mem, bool isSingle)
1396 {
1397     if (isSingle) {
1398         Encodeb(0xF3);
1399     } else {
1400         Encodeb(0xF2);
1401     }
1402     OpRM(reg, mem, 0x0F, 0x11);
1403 }
1404 
1405 /* movabs */
Movabs(const ImmOpnd & immOpnd,Reg reg)1406 void ElfAssembler::Movabs(const ImmOpnd &immOpnd, Reg reg)
1407 {
1408     bool isSymbol = immOpnd.second;
1409     uint64 imm = static_cast<uint64>(immOpnd.first); /* When isSymbol is true, this is index. */
1410     if (GetRex(reg) != 0) {
1411         Encodeb(GetRex(reg));
1412     }
1413     Encodeb(0xB8 | GetRegCodeId(reg));
1414     size_t offsetSize = 8;
1415     if (isSymbol) {
1416         UpdateLabel(immOpnd.first);
1417         AppendFixup(immOpnd.first, kAbsolute64, {static_cast<uint32>(codeBuff.size()), offsetSize}, fixups);
1418         imm = 0;
1419     }
1420     Encodeb(imm, offsetSize);
1421 }
1422 
Movabs(int64 symIdx,Reg reg)1423 void ElfAssembler::Movabs(int64 symIdx, Reg reg)
1424 {
1425     if (GetRex(reg) != 0) {
1426         Encodeb(GetRex(reg));
1427     }
1428     Encodeb(0xB8 | GetRegCodeId(reg));
1429     size_t offsetSize = 8;
1430     size_t offset = codeBuff.size() - offsetSize;
1431     UpdateLabel(symIdx);
1432     AppendFixup(symIdx, kAbsolute64, {offset, offsetSize}, fixups);
1433     uint8 imm = 0;
1434     Encodeb(imm, offsetSize);
1435 }
1436 
1437 /* push */
Push(InsnSize insnSize,Reg reg)1438 void ElfAssembler::Push(InsnSize insnSize, Reg reg)
1439 {
1440     OpPushPop(reg, 0x50);
1441 }
1442 
1443 /* pop */
Pop(InsnSize insnSize,Reg reg)1444 void ElfAssembler::Pop(InsnSize insnSize, Reg reg)
1445 {
1446     OpPushPop(reg, 0x58);
1447 }
1448 
1449 /* lea */
Lea(InsnSize insnSize,const Mem & mem,Reg reg)1450 void ElfAssembler::Lea(InsnSize insnSize, const Mem &mem, Reg reg)
1451 {
1452     OpRM(reg, mem, 0x8C);
1453 }
1454 
1455 /* movzx */
MovZx(InsnSize sSize,InsnSize dSize,Reg srcReg,Reg destReg)1456 void ElfAssembler::MovZx(InsnSize sSize, InsnSize dSize, Reg srcReg, Reg destReg)
1457 {
1458     OpRR(srcReg, destReg, 0x0F, 0xB6 | (GetRegSize(srcReg) == k8Bits ? 0 : 1), true);
1459 }
1460 
MovZx(InsnSize sSize,InsnSize dSize,const Mem & mem,Reg reg)1461 void ElfAssembler::MovZx(InsnSize sSize, InsnSize dSize, const Mem &mem, Reg reg)
1462 {
1463     OpRM(reg, mem, 0x0F, 0xB6 | (mem.size == k8Bits ? 0 : 1), true);
1464 }
1465 
1466 /* movsx */
MovSx(InsnSize sSize,InsnSize dSize,Reg srcReg,Reg destReg)1467 void ElfAssembler::MovSx(InsnSize sSize, InsnSize dSize, Reg srcReg, Reg destReg)
1468 {
1469     uint8 code1 = 0x0F;
1470     uint8 code2 = 0xBE | (GetRegSize(srcReg) == k8Bits ? 0 : 1);
1471     if (GetRegSize(srcReg) == k32Bits && GetRegSize(destReg) == k64Bits) {
1472         code1 = 0x63;
1473         code2 = 0;
1474     }
1475     OpRR(srcReg, destReg, code1, code2, true);
1476 }
1477 
MovSx(InsnSize sSize,InsnSize dSize,const Mem & mem,Reg reg)1478 void ElfAssembler::MovSx(InsnSize sSize, InsnSize dSize, const Mem &mem, Reg reg)
1479 {
1480     uint8 code1 = 0x0F;
1481     uint8 code2 = 0xBE | (mem.size == k8Bits ? 0 : 1);
1482     if (mem.size == k32Bits && GetRegSize(reg) == k64Bits) {
1483         code1 = 0x63;
1484         code2 = 0;
1485     }
1486     OpRM(reg, mem, code1, code2, true);
1487 }
1488 
1489 /* add */
Add(InsnSize insnSize,Reg srcReg,Reg destReg)1490 void ElfAssembler::Add(InsnSize insnSize, Reg srcReg, Reg destReg)
1491 {
1492     OpRR(srcReg, destReg, 0x00);
1493 }
1494 
Add(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1495 void ElfAssembler::Add(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1496 {
1497     OpImmAndReg(immOpnd, reg, 0x00, 0);
1498 }
1499 
Add(InsnSize insnSize,const Mem & mem,Reg reg)1500 void ElfAssembler::Add(InsnSize insnSize, const Mem &mem, Reg reg)
1501 {
1502     OpRM(reg, mem, 0x02);
1503 }
1504 
Add(InsnSize insnSize,Reg reg,const Mem & mem)1505 void ElfAssembler::Add(InsnSize insnSize, Reg reg, const Mem &mem)
1506 {
1507     OpRM(reg, mem, 0x00);
1508 }
1509 
Add(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1510 void ElfAssembler::Add(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1511 {
1512     OpImmAndMem(immOpnd, mem, 0);
1513 }
1514 
1515 /* add floating point */
Add(Reg srcReg,Reg destReg,bool isSingle)1516 void ElfAssembler::Add(Reg srcReg, Reg destReg, bool isSingle)
1517 {
1518     if (isSingle) {
1519         Encodeb(0xF3);
1520     } else {
1521         Encodeb(0xF2);
1522     }
1523     OpRR(destReg, srcReg, 0x0F, 0x58);
1524 }
1525 
Add(const Mem & mem,Reg reg,bool isSingle)1526 void ElfAssembler::Add(const Mem &mem, Reg reg, bool isSingle)
1527 {
1528     if (isSingle) {
1529         Encodeb(0xF3);
1530     } else {
1531         Encodeb(0xF2);
1532     }
1533     OpRM(reg, mem, 0x0F, 0x58);
1534 }
1535 
1536 /* sub */
Sub(InsnSize insnSize,Reg srcReg,Reg destReg)1537 void ElfAssembler::Sub(InsnSize insnSize, Reg srcReg, Reg destReg)
1538 {
1539     OpRR(srcReg, destReg, 0x28);
1540 }
1541 
Sub(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1542 void ElfAssembler::Sub(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1543 {
1544     OpImmAndReg(immOpnd, reg, 0x28, kSubModReg);
1545 }
1546 
Sub(InsnSize insnSize,const Mem & mem,Reg reg)1547 void ElfAssembler::Sub(InsnSize insnSize, const Mem &mem, Reg reg)
1548 {
1549     OpRM(reg, mem, 0x2A);
1550 }
1551 
Sub(InsnSize insnSize,Reg reg,const Mem & mem)1552 void ElfAssembler::Sub(InsnSize insnSize, Reg reg, const Mem &mem)
1553 {
1554     OpRM(reg, mem, 0x28);
1555 }
1556 
Sub(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1557 void ElfAssembler::Sub(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1558 {
1559     OpImmAndMem(immOpnd, mem, kSubModReg);
1560 }
1561 
1562 /* sub floating point */
Sub(Reg srcReg,Reg destReg,bool isSingle)1563 void ElfAssembler::Sub(Reg srcReg, Reg destReg, bool isSingle)
1564 {
1565     if (isSingle) {
1566         Encodeb(0xF3);
1567     } else {
1568         Encodeb(0xF2);
1569     }
1570     OpRR(destReg, srcReg, 0x0F, 0x5c);
1571 }
1572 
Sub(const Mem & mem,Reg reg,bool isSingle)1573 void ElfAssembler::Sub(const Mem &mem, Reg reg, bool isSingle)
1574 {
1575     if (isSingle) {
1576         Encodeb(0xF3);
1577     } else {
1578         Encodeb(0xF2);
1579     }
1580     OpRM(reg, mem, 0x0F, 0x5c);
1581 }
1582 
1583 /* and */
And(InsnSize insnSize,Reg srcReg,Reg destReg)1584 void ElfAssembler::And(InsnSize insnSize, Reg srcReg, Reg destReg)
1585 {
1586     OpRR(srcReg, destReg, 0x20);
1587 }
1588 
And(InsnSize insnSize,const Mem & mem,Reg reg)1589 void ElfAssembler::And(InsnSize insnSize, const Mem &mem, Reg reg)
1590 {
1591     OpRM(reg, mem, 0x21);
1592 }
1593 
And(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1594 void ElfAssembler::And(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1595 {
1596     OpImmAndReg(immOpnd, reg, 0x20, kAndModReg);
1597 }
1598 
And(InsnSize insnSize,Reg reg,const Mem & mem)1599 void ElfAssembler::And(InsnSize insnSize, Reg reg, const Mem &mem)
1600 {
1601     OpRM(reg, mem, 0x20);
1602 }
1603 
And(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1604 void ElfAssembler::And(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1605 {
1606     OpImmAndMem(immOpnd, mem, kAndModReg);
1607 }
1608 
1609 /* or */
Or(InsnSize insnSize,Reg srcReg,Reg destReg)1610 void ElfAssembler::Or(InsnSize insnSize, Reg srcReg, Reg destReg)
1611 {
1612     OpRR(srcReg, destReg, 0x08);
1613 }
1614 
Or(InsnSize insnSize,const Mem & mem,Reg reg)1615 void ElfAssembler::Or(InsnSize insnSize, const Mem &mem, Reg reg)
1616 {
1617     OpRM(reg, mem, 0x0A);
1618 }
1619 
Or(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1620 void ElfAssembler::Or(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1621 {
1622     OpImmAndReg(immOpnd, reg, 0x08, kOrModReg);
1623 }
1624 
Or(InsnSize insnSize,Reg reg,const Mem & mem)1625 void ElfAssembler::Or(InsnSize insnSize, Reg reg, const Mem &mem)
1626 {
1627     OpRM(reg, mem, 0x08);
1628 }
1629 
Or(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1630 void ElfAssembler::Or(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1631 {
1632     OpImmAndMem(immOpnd, mem, kOrModReg);
1633 }
1634 
1635 /* xor */
Xor(InsnSize insnSize,Reg srcReg,Reg destReg)1636 void ElfAssembler::Xor(InsnSize insnSize, Reg srcReg, Reg destReg)
1637 {
1638     OpRR(srcReg, destReg, 0x30);
1639 }
1640 
Xor(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1641 void ElfAssembler::Xor(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1642 {
1643     OpImmAndReg(immOpnd, reg, 0x30, kXorModReg);
1644 }
1645 
Xor(InsnSize insnSize,const Mem & mem,Reg reg)1646 void ElfAssembler::Xor(InsnSize insnSize, const Mem &mem, Reg reg)
1647 {
1648     OpRM(reg, mem, 0x32);
1649 }
1650 
Xor(InsnSize insnSize,Reg reg,const Mem & mem)1651 void ElfAssembler::Xor(InsnSize insnSize, Reg reg, const Mem &mem)
1652 {
1653     OpRM(reg, mem, 0x30);
1654 }
1655 
Xor(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1656 void ElfAssembler::Xor(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1657 {
1658     OpImmAndMem(immOpnd, mem, kXorModReg);
1659 }
1660 
1661 /* bsr */
Bsr(InsnSize insnSize,Reg srcReg,Reg destReg)1662 void ElfAssembler::Bsr(InsnSize insnSize, Reg srcReg, Reg destReg)
1663 {
1664     OpRR(srcReg, destReg, 0x0f, 0xbd);
1665 }
1666 
1667 /* not */
Not(InsnSize insnSize,Reg reg)1668 void ElfAssembler::Not(InsnSize insnSize, Reg reg)
1669 {
1670     OpReg(reg, 0xF6, 0, kNotModReg);
1671 }
1672 
Not(InsnSize insnSize,const Mem & mem)1673 void ElfAssembler::Not(InsnSize insnSize, const Mem &mem)
1674 {
1675     OpMem(mem, 0xF6, 0, kNotModReg);
1676 }
1677 
1678 /* neg */
Neg(InsnSize insnSize,Reg reg)1679 void ElfAssembler::Neg(InsnSize insnSize, Reg reg)
1680 {
1681     OpReg(reg, 0xF6, 0, kNegModReg);
1682 }
1683 
Neg(InsnSize insnSize,const Mem & mem)1684 void ElfAssembler::Neg(InsnSize insnSize, const Mem &mem)
1685 {
1686     OpMem(mem, 0xF6, 0, kNegModReg);
1687 }
1688 
1689 /* div & cwd, cdq, cqo */
Idiv(InsnSize insnSize,Reg reg)1690 void ElfAssembler::Idiv(InsnSize insnSize, Reg reg)
1691 {
1692     OpReg(reg, 0xF6, 0, kIdivModReg);
1693 }
1694 
Idiv(InsnSize insnSize,const Mem & mem)1695 void ElfAssembler::Idiv(InsnSize insnSize, const Mem &mem)
1696 {
1697     OpMem(mem, 0xF6, 0, kIdivModReg);
1698 }
1699 
Div(InsnSize insnSize,Reg reg)1700 void ElfAssembler::Div(InsnSize insnSize, Reg reg)
1701 {
1702     OpReg(reg, 0xF6, 0, kDivModReg);
1703 }
1704 
Div(InsnSize insnSize,const Mem & mem)1705 void ElfAssembler::Div(InsnSize insnSize, const Mem &mem)
1706 {
1707     OpMem(mem, 0xF6, 0, kDivModReg);
1708 }
1709 
Cwd()1710 void ElfAssembler::Cwd()
1711 {
1712     Encodeb(0x66);
1713     Encodeb(0x99);
1714 }
1715 
Cdq()1716 void ElfAssembler::Cdq()
1717 {
1718     Encodeb(0x99);
1719 }
1720 
Cqo()1721 void ElfAssembler::Cqo()
1722 {
1723     Encodeb(0x48);
1724     Encodeb(0x99);
1725 }
1726 
1727 /* shl */
Shl(InsnSize insnSize,Reg srcReg,Reg destReg)1728 void ElfAssembler::Shl(InsnSize insnSize, Reg srcReg, Reg destReg)
1729 {
1730     OpReg(destReg, 0xD2, 0, kShlModReg);
1731 }
1732 
Shl(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1733 void ElfAssembler::Shl(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1734 {
1735     OpReg(reg, 0xC0, 0, kShlModReg);
1736     Encodeb(static_cast<uint64>(immOpnd.first));
1737 }
1738 
Shl(InsnSize insnSize,Reg reg,const Mem & mem)1739 void ElfAssembler::Shl(InsnSize insnSize, Reg reg, const Mem &mem)
1740 {
1741     OpMem(mem, 0xD2, 0, kShlModReg);
1742 }
1743 
Shl(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1744 void ElfAssembler::Shl(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1745 {
1746     OpMem(mem, 0xC0, 0, kShlModReg);
1747     Encodeb(static_cast<uint64>(immOpnd.first));
1748 }
1749 
1750 /* sar */
Sar(InsnSize insnSize,Reg srcReg,Reg destReg)1751 void ElfAssembler::Sar(InsnSize insnSize, Reg srcReg, Reg destReg)
1752 {
1753     OpReg(destReg, 0xD2, 0, kSarModReg);
1754 }
1755 
Sar(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1756 void ElfAssembler::Sar(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1757 {
1758     OpReg(reg, 0xC0, 0, kSarModReg);
1759     Encodeb(static_cast<uint64>(immOpnd.first));
1760 }
1761 
Sar(InsnSize insnSize,Reg reg,const Mem & mem)1762 void ElfAssembler::Sar(InsnSize insnSize, Reg reg, const Mem &mem)
1763 {
1764     OpMem(mem, 0xD2, 0, kSarModReg);
1765 }
1766 
Sar(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1767 void ElfAssembler::Sar(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1768 {
1769     OpMem(mem, 0xC0, 0, kSarModReg);
1770     Encodeb(static_cast<uint64>(immOpnd.first));
1771 }
1772 
1773 /* shr */
Shr(InsnSize insnSize,Reg srcReg,Reg destReg)1774 void ElfAssembler::Shr(InsnSize insnSize, Reg srcReg, Reg destReg)
1775 {
1776     OpReg(destReg, 0xD2, 0, kShrModReg);
1777 }
1778 
Shr(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1779 void ElfAssembler::Shr(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1780 {
1781     OpReg(reg, 0xC0, 0, kShrModReg);
1782     Encodeb(static_cast<uint64>(immOpnd.first));
1783 }
1784 
Shr(InsnSize insnSize,Reg reg,const Mem & mem)1785 void ElfAssembler::Shr(InsnSize insnSize, Reg reg, const Mem &mem)
1786 {
1787     OpMem(mem, 0xD2, 0, kShrModReg);
1788 }
1789 
Shr(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1790 void ElfAssembler::Shr(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1791 {
1792     OpMem(mem, 0xC0, 0, kShrModReg);
1793     Encodeb(static_cast<uint64>(immOpnd.first));
1794 }
1795 
1796 /* jmp */
Jmp(Reg reg)1797 void ElfAssembler::Jmp(Reg reg)
1798 {
1799     OpReg(reg, 0xFF, 0, kJmpModReg);
1800 }
1801 
Jmp(const Mem & mem)1802 void ElfAssembler::Jmp(const Mem &mem)
1803 {
1804     OpMem(mem, 0xFF, 0, kJmpModReg);
1805 }
1806 
Jmp(int64 symIdx)1807 void ElfAssembler::Jmp(int64 symIdx)
1808 {
1809     JmpToLabel(symIdx, 0xE9);
1810 }
1811 
1812 /* jump condition */
Je(int64 symIdx)1813 void ElfAssembler::Je(int64 symIdx)
1814 {
1815     JmpToLabel(symIdx, 0x0F, 0x84);
1816 }
1817 
Ja(int64 symIdx)1818 void ElfAssembler::Ja(int64 symIdx)
1819 {
1820     JmpToLabel(symIdx, 0x0F, 0x87);
1821 }
1822 
Jae(int64 symIdx)1823 void ElfAssembler::Jae(int64 symIdx)
1824 {
1825     JmpToLabel(symIdx, 0x0F, 0x83);
1826 }
1827 
Jne(int64 symIdx)1828 void ElfAssembler::Jne(int64 symIdx)
1829 {
1830     JmpToLabel(symIdx, 0x0F, 0x85);
1831 }
1832 
Jb(int64 symIdx)1833 void ElfAssembler::Jb(int64 symIdx)
1834 {
1835     JmpToLabel(symIdx, 0x0F, 0x82);
1836 }
1837 
Jbe(int64 symIdx)1838 void ElfAssembler::Jbe(int64 symIdx)
1839 {
1840     JmpToLabel(symIdx, 0x0F, 0x86);
1841 }
1842 
Jg(int64 symIdx)1843 void ElfAssembler::Jg(int64 symIdx)
1844 {
1845     JmpToLabel(symIdx, 0x0F, 0x8F);
1846 }
1847 
Jge(int64 symIdx)1848 void ElfAssembler::Jge(int64 symIdx)
1849 {
1850     JmpToLabel(symIdx, 0x0F, 0x8D);
1851 }
1852 
Jl(int64 symIdx)1853 void ElfAssembler::Jl(int64 symIdx)
1854 {
1855     JmpToLabel(symIdx, 0x0F, 0x8C);
1856 }
1857 
Jle(int64 symIdx)1858 void ElfAssembler::Jle(int64 symIdx)
1859 {
1860     JmpToLabel(symIdx, 0x0F, 0x8E);
1861 }
1862 
1863 /* cmp */
Cmp(InsnSize insnSize,Reg srcReg,Reg destReg)1864 void ElfAssembler::Cmp(InsnSize insnSize, Reg srcReg, Reg destReg)
1865 {
1866     OpRR(srcReg, destReg, 0x38);
1867 }
1868 
Cmp(InsnSize insnSize,const Mem & mem,Reg reg)1869 void ElfAssembler::Cmp(InsnSize insnSize, const Mem &mem, Reg reg)
1870 {
1871     OpRM(reg, mem, 0x3A);
1872 }
1873 
Cmp(InsnSize insnSize,Reg reg,const Mem & mem)1874 void ElfAssembler::Cmp(InsnSize insnSize, Reg reg, const Mem &mem)
1875 {
1876     OpRM(reg, mem, 0x38);
1877 }
1878 
Cmp(InsnSize insnSize,const ImmOpnd & immOpnd,Reg reg)1879 void ElfAssembler::Cmp(InsnSize insnSize, const ImmOpnd &immOpnd, Reg reg)
1880 {
1881     OpImmAndReg(immOpnd, reg, 0x38, kCmpModReg);
1882 }
1883 
Cmp(InsnSize insnSize,const ImmOpnd & immOpnd,const Mem & mem)1884 void ElfAssembler::Cmp(InsnSize insnSize, const ImmOpnd &immOpnd, const Mem &mem)
1885 {
1886     OpImmAndMem(immOpnd, mem, kCmpModReg);
1887 }
1888 
1889 /* test */
Test(InsnSize insnSize,Reg srcReg,Reg destReg)1890 void ElfAssembler::Test(InsnSize insnSize, Reg srcReg, Reg destReg)
1891 {
1892     OpRR(srcReg, destReg, 0x84);
1893 }
1894 
1895 /* setcc */
Setbe(Reg reg)1896 void ElfAssembler::Setbe(Reg reg)
1897 {
1898     OpReg(reg, 0x0F, 0x96, 0);
1899 }
1900 
Setbe(const Mem & mem)1901 void ElfAssembler::Setbe(const Mem &mem)
1902 {
1903     OpMem(mem, 0x0F, 0x96, 0);
1904 }
1905 
Setle(Reg reg)1906 void ElfAssembler::Setle(Reg reg)
1907 {
1908     OpReg(reg, 0x0F, 0x9E, 0);
1909 }
1910 
Setle(const Mem & mem)1911 void ElfAssembler::Setle(const Mem &mem)
1912 {
1913     OpMem(mem, 0x0F, 0x9E, 0);
1914 }
1915 
Setae(Reg reg)1916 void ElfAssembler::Setae(Reg reg)
1917 {
1918     OpReg(reg, 0x0F, 0x93, 0);
1919 }
1920 
Setae(const Mem & mem)1921 void ElfAssembler::Setae(const Mem &mem)
1922 {
1923     OpMem(mem, 0x0F, 0x93, 0);
1924 }
1925 
Setge(Reg reg)1926 void ElfAssembler::Setge(Reg reg)
1927 {
1928     OpReg(reg, 0x0F, 0x9D, 0);
1929 }
Setge(const Mem & mem)1930 void ElfAssembler::Setge(const Mem &mem)
1931 {
1932     OpMem(mem, 0x0F, 0x9D, 0);
1933 }
1934 
Setne(Reg reg)1935 void ElfAssembler::Setne(Reg reg)
1936 {
1937     OpReg(reg, 0x0F, 0x95, 0);
1938 }
1939 
Setne(const Mem & mem)1940 void ElfAssembler::Setne(const Mem &mem)
1941 {
1942     OpMem(mem, 0x0F, 0x95, 0);
1943 }
1944 
Setb(Reg reg)1945 void ElfAssembler::Setb(Reg reg)
1946 {
1947     OpReg(reg, 0x0F, 0x92, 0);
1948 }
1949 
Setb(const Mem & mem)1950 void ElfAssembler::Setb(const Mem &mem)
1951 {
1952     OpMem(mem, 0x0F, 0x92, 0);
1953 }
1954 
Setl(Reg reg)1955 void ElfAssembler::Setl(Reg reg)
1956 {
1957     OpReg(reg, 0x0F, 0x9C, 0);
1958 }
1959 
Setl(const Mem & mem)1960 void ElfAssembler::Setl(const Mem &mem)
1961 {
1962     OpMem(mem, 0x0F, 0x9C, 0);
1963 }
1964 
Seta(Reg reg)1965 void ElfAssembler::Seta(Reg reg)
1966 {
1967     OpReg(reg, 0x0F, 0x97, 0);
1968 }
1969 
Seta(const Mem & mem)1970 void ElfAssembler::Seta(const Mem &mem)
1971 {
1972     OpMem(mem, 0x0F, 0x97, 0);
1973 }
1974 
Setg(Reg reg)1975 void ElfAssembler::Setg(Reg reg)
1976 {
1977     OpReg(reg, 0x0F, 0x9F, 0);
1978 }
1979 
Setg(const Mem & mem)1980 void ElfAssembler::Setg(const Mem &mem)
1981 {
1982     OpMem(mem, 0x0F, 0x9F, 0);
1983 }
1984 
Sete(Reg reg)1985 void ElfAssembler::Sete(Reg reg)
1986 {
1987     OpReg(reg, 0x0F, 0x94, 0);
1988 }
1989 
Sete(const Mem & mem)1990 void ElfAssembler::Sete(const Mem &mem)
1991 {
1992     OpMem(mem, 0x0F, 0x94, 0);
1993 }
1994 
Seto(Reg reg)1995 void ElfAssembler::Seto(Reg reg)
1996 {
1997     OpReg(reg, 0x0F, 0x90, 0);
1998 }
1999 
Seto(const Mem & mem)2000 void ElfAssembler::Seto(const Mem &mem)
2001 {
2002     OpMem(mem, 0x0F, 0x90, 0);
2003 }
2004 
2005 /* cmov */
Cmova(InsnSize insnSize,Reg srcReg,Reg destReg)2006 void ElfAssembler::Cmova(InsnSize insnSize, Reg srcReg, Reg destReg)
2007 {
2008     OpCmovcc(srcReg, destReg, 0x0F, 0x47);
2009 }
2010 
Cmova(InsnSize insnSize,const Mem & mem,Reg reg)2011 void ElfAssembler::Cmova(InsnSize insnSize, const Mem &mem, Reg reg)
2012 {
2013     OpRM(reg, mem, 0x0E, 0x47);
2014 }
Cmovae(InsnSize insnSize,Reg srcReg,Reg destReg)2015 void ElfAssembler::Cmovae(InsnSize insnSize, Reg srcReg, Reg destReg)
2016 {
2017     OpCmovcc(srcReg, destReg, 0x0F, 0x43);
2018 }
2019 
Cmovae(InsnSize insnSize,const Mem & mem,Reg reg)2020 void ElfAssembler::Cmovae(InsnSize insnSize, const Mem &mem, Reg reg)
2021 {
2022     OpRM(reg, mem, 0x0E, 0x43);
2023 }
2024 
Cmovb(InsnSize insnSize,Reg srcReg,Reg destReg)2025 void ElfAssembler::Cmovb(InsnSize insnSize, Reg srcReg, Reg destReg)
2026 {
2027     OpCmovcc(srcReg, destReg, 0x0F, 0x42);
2028 }
2029 
Cmovb(InsnSize insnSize,const Mem & mem,Reg reg)2030 void ElfAssembler::Cmovb(InsnSize insnSize, const Mem &mem, Reg reg)
2031 {
2032     OpRM(reg, mem, 0x0E, 0x42);
2033 }
2034 
Cmovbe(InsnSize insnSize,Reg srcReg,Reg destReg)2035 void ElfAssembler::Cmovbe(InsnSize insnSize, Reg srcReg, Reg destReg)
2036 {
2037     OpCmovcc(srcReg, destReg, 0x0F, 0x46);
2038 }
2039 
Cmovbe(InsnSize insnSize,const Mem & mem,Reg reg)2040 void ElfAssembler::Cmovbe(InsnSize insnSize, const Mem &mem, Reg reg)
2041 {
2042     OpRM(reg, mem, 0x0E, 0x46);
2043 }
2044 
Cmove(InsnSize insnSize,Reg srcReg,Reg destReg)2045 void ElfAssembler::Cmove(InsnSize insnSize, Reg srcReg, Reg destReg)
2046 {
2047     OpCmovcc(srcReg, destReg, 0x0F, 0x44);
2048 }
2049 
Cmove(InsnSize insnSize,const Mem & mem,Reg reg)2050 void ElfAssembler::Cmove(InsnSize insnSize, const Mem &mem, Reg reg)
2051 {
2052     OpRM(reg, mem, 0x0E, 0x44);
2053 }
2054 
Cmovg(InsnSize insnSize,Reg srcReg,Reg destReg)2055 void ElfAssembler::Cmovg(InsnSize insnSize, Reg srcReg, Reg destReg)
2056 {
2057     OpCmovcc(srcReg, destReg, 0x0F, 0x4F);
2058 }
2059 
Cmovg(InsnSize insnSize,const Mem & mem,Reg reg)2060 void ElfAssembler::Cmovg(InsnSize insnSize, const Mem &mem, Reg reg)
2061 {
2062     OpRM(reg, mem, 0x0E, 0x4F);
2063 }
2064 
Cmovge(InsnSize insnSize,Reg srcReg,Reg destReg)2065 void ElfAssembler::Cmovge(InsnSize insnSize, Reg srcReg, Reg destReg)
2066 {
2067     OpCmovcc(srcReg, destReg, 0x0F, 0x4D);
2068 }
2069 
Cmovge(InsnSize insnSize,const Mem & mem,Reg reg)2070 void ElfAssembler::Cmovge(InsnSize insnSize, const Mem &mem, Reg reg)
2071 {
2072     OpRM(reg, mem, 0x0E, 0x4D);
2073 }
2074 
Cmovl(InsnSize insnSize,Reg srcReg,Reg destReg)2075 void ElfAssembler::Cmovl(InsnSize insnSize, Reg srcReg, Reg destReg)
2076 {
2077     OpCmovcc(srcReg, destReg, 0x0F, 0x4C);
2078 }
2079 
Cmovl(InsnSize insnSize,const Mem & mem,Reg reg)2080 void ElfAssembler::Cmovl(InsnSize insnSize, const Mem &mem, Reg reg)
2081 {
2082     OpRM(reg, mem, 0x0E, 0x4C);
2083 }
2084 
Cmovle(InsnSize insnSize,Reg srcReg,Reg destReg)2085 void ElfAssembler::Cmovle(InsnSize insnSize, Reg srcReg, Reg destReg)
2086 {
2087     OpCmovcc(srcReg, destReg, 0x0F, 0x4E);
2088 }
2089 
Cmovle(InsnSize insnSize,const Mem & mem,Reg reg)2090 void ElfAssembler::Cmovle(InsnSize insnSize, const Mem &mem, Reg reg)
2091 {
2092     OpRM(reg, mem, 0x0E, 0x4E);
2093 }
2094 
Cmovo(InsnSize insnSize,Reg srcReg,Reg destReg)2095 void ElfAssembler::Cmovo(InsnSize insnSize, Reg srcReg, Reg destReg)
2096 {
2097     OpCmovcc(srcReg, destReg, 0x0F, 0x40);
2098 }
2099 
Cmovne(InsnSize insnSize,Reg srcReg,Reg destReg)2100 void ElfAssembler::Cmovne(InsnSize insnSize, Reg srcReg, Reg destReg)
2101 {
2102     OpCmovcc(srcReg, destReg, 0x0F, 0x45);
2103 }
2104 
Cmovne(InsnSize insnSize,const Mem & mem,Reg reg)2105 void ElfAssembler::Cmovne(InsnSize insnSize, const Mem &mem, Reg reg)
2106 {
2107     OpRM(reg, mem, 0x0E, 0x45);
2108 }
2109 
2110 /* call */
Call(InsnSize insnSize,Reg reg)2111 void ElfAssembler::Call(InsnSize insnSize, Reg reg)
2112 {
2113     // Save to disignate memory
2114     OpReg(reg, 0xFF, 0, kCallModReg);
2115 }
2116 
Call(InsnSize insnSize,const Mem & mem)2117 void ElfAssembler::Call(InsnSize insnSize, const Mem &mem)
2118 {
2119     OpMem(mem, 0xFF, 0, kCallModReg);
2120 }
2121 
Call(InsnSize insnSize,int64 symIdx)2122 void ElfAssembler::Call(InsnSize insnSize, int64 symIdx)
2123 {
2124     Encodeb(0xE8);
2125     if (!CanEncodeLabel(symIdx)) {
2126         size_t offsetSize = 4;
2127         UpdateLabel(symIdx, LabelType::kFunc);
2128         AppendFixup(symIdx, kPLT, {static_cast<uint32>(codeBuff.size()), offsetSize}, fixups);
2129         uint8 imm = 0;
2130         Encodeb(imm, offsetSize);
2131     }
2132 }
2133 
2134 /* ret */
Ret()2135 void ElfAssembler::Ret()
2136 {
2137     Encodeb(0xC3);
2138 }
2139 
2140 /* leave */
Leave()2141 void ElfAssembler::Leave()
2142 {
2143     Encodeb(0xC9);
2144 }
2145 
2146 /* imul */
Imul(InsnSize insnSize,Reg srcReg,Reg destReg)2147 void ElfAssembler::Imul(InsnSize insnSize, Reg srcReg, Reg destReg)
2148 {
2149     OpRR(destReg, srcReg, 0x0F, 0xAF);
2150 }
2151 
2152 /* mul float */
Mul(Reg srcReg,Reg destReg,bool isSingle)2153 void ElfAssembler::Mul(Reg srcReg, Reg destReg, bool isSingle)
2154 {
2155     if (isSingle) {
2156         Encodeb(0xF3);
2157     } else {
2158         Encodeb(0xF2);
2159     }
2160     OpRR(destReg, srcReg, 0x0F, 0x59);
2161 }
2162 
Mul(const Mem & mem,Reg reg,bool isSingle)2163 void ElfAssembler::Mul(const Mem &mem, Reg reg, bool isSingle)
2164 {
2165     if (isSingle) {
2166         Encodeb(0xF3);
2167     } else {
2168         Encodeb(0xF2);
2169     }
2170     OpRM(reg, mem, 0x0F, 0x59);
2171 }
2172 
2173 /* nop */
Nop(InsnSize insnSize,const Mem & mem)2174 void ElfAssembler::Nop(InsnSize insnSize, const Mem &mem)
2175 {
2176     OpMem(mem, 0x0E, 0x1F, 0);
2177 }
2178 
Nop()2179 void ElfAssembler::Nop()
2180 {
2181     Encodeb(0x90);
2182 }
2183 
2184 /* byte swap */
Bswap(InsnSize insnSize,Reg reg)2185 void ElfAssembler::Bswap(InsnSize insnSize, Reg reg)
2186 {
2187     uint8 rex = GetRex(reg);
2188     if (rex != 0) {
2189         Encodeb(rex);
2190     }
2191     Encodeb(0x0F);
2192     Encodeb(0xC8 | GetRegCodeId(reg));
2193 }
2194 
Xchg(InsnSize insnSize,Reg srcReg,Reg destReg)2195 void ElfAssembler::Xchg(InsnSize insnSize, Reg srcReg, Reg destReg)
2196 {
2197     /* if the reg is ax, eax or rax */
2198     if ((GetRegId(srcReg) == 0 || GetRegId(destReg) == 0) && GetRegSize(srcReg) != k8Bits) {
2199         uint8 rex = GetRex(srcReg, destReg);
2200         if (rex != 0) {
2201             Encodeb(rex);
2202         } else if (GetRegSize(srcReg) == k16Bits) {
2203             Encodeb(0x66);
2204         }
2205         uint8 regCodeId = GetRegId(srcReg) == 0 ? GetRegCodeId(destReg) : GetRegCodeId(srcReg);
2206         Encodeb(0x90 | regCodeId);
2207     } else {
2208         OpRR(srcReg, destReg, 0x86);
2209     }
2210 }
2211 
2212 /* floating point */
MovF(Reg srcReg,Reg destReg,bool isSingle)2213 void ElfAssembler::MovF(Reg srcReg, Reg destReg, bool isSingle)
2214 {
2215     bool isXMM = GetRegSize(srcReg) == k128Bits || GetRegSize(destReg) == k128Bits;
2216     if (isSingle) {
2217         if (isXMM) {
2218             Encodeb(0xF3);
2219         }
2220         OpRR(destReg, srcReg, 0x0F, 0x10);
2221     } else {
2222         if (isXMM) {
2223             Encodeb(0xF2);
2224         }
2225         OpRR(destReg, srcReg, 0x0F, 0x10);
2226     }
2227 }
2228 
2229 /* floating point and */
And(Reg srcReg,Reg destReg,bool isSingle)2230 void ElfAssembler::And(Reg srcReg, Reg destReg, bool isSingle)
2231 {
2232     if (isSingle) {
2233         Encodeb(0x100);
2234     } else {
2235         Encodeb(0x66);
2236     }
2237     OpRR(destReg, srcReg, 0x0F, 0x54);
2238 }
2239 
And(const Mem & mem,Reg reg,bool isSingle)2240 void ElfAssembler::And(const Mem &mem, Reg reg, bool isSingle)
2241 {
2242     if (isSingle) {
2243         Encodeb(0x100);
2244     } else {
2245         Encodeb(0x66);
2246     }
2247     OpRM(reg, mem, 0x0F, 0x54);
2248 }
2249 
2250 /* floating div */
Divsd(Reg srcReg,Reg destReg)2251 void ElfAssembler::Divsd(Reg srcReg, Reg destReg)
2252 {
2253     Encodeb(0xF2);
2254     OpRR(destReg, srcReg, 0x0F, 0x5E);
2255 }
2256 
Divsd(const Mem & mem,Reg reg)2257 void ElfAssembler::Divsd(const Mem &mem, Reg reg)
2258 {
2259     Encodeb(0xF2);
2260     OpRM(reg, mem, 0x0F, 0x5E);
2261 }
2262 
2263 /* convert int2float */
Cvtsi2ss(InsnSize insnSize,Reg srcReg,Reg destReg)2264 void ElfAssembler::Cvtsi2ss(InsnSize insnSize, Reg srcReg, Reg destReg)
2265 {
2266     Encodeb(0xF3);
2267     OpRR(destReg, srcReg, 0x0F, 0x2A);
2268 }
2269 
Cvtsi2sd(InsnSize insnSize,Reg srcReg,Reg destReg)2270 void ElfAssembler::Cvtsi2sd(InsnSize insnSize, Reg srcReg, Reg destReg)
2271 {
2272     Encodeb(0xF2);
2273     OpRR(destReg, srcReg, 0x0F, 0x2A);
2274 }
2275 
2276 /*convert float2int */
Cvttsd2si(InsnSize insnSize,Reg srcReg,Reg destReg)2277 void ElfAssembler::Cvttsd2si(InsnSize insnSize, Reg srcReg, Reg destReg)
2278 {
2279     Encodeb(0xF2);
2280     OpRR(destReg, srcReg, 0x0F, 0x2C);
2281 }
2282 
Cvttss2si(InsnSize insnSize,Reg srcReg,Reg destReg)2283 void ElfAssembler::Cvttss2si(InsnSize insnSize, Reg srcReg, Reg destReg)
2284 {
2285     Encodeb(0xF3);
2286     OpRR(destReg, srcReg, 0x0F, 0x2C);
2287 }
2288 
2289 /* convert float2float */
Cvtss2sd(Reg srcReg,Reg destReg)2290 void ElfAssembler::Cvtss2sd(Reg srcReg, Reg destReg)
2291 {
2292     Encodeb(0xF3);
2293     OpRR(destReg, srcReg, 0x0F, 0x5A);
2294 }
2295 
Cvtsd2ss(Reg srcReg,Reg destReg)2296 void ElfAssembler::Cvtsd2ss(Reg srcReg, Reg destReg)
2297 {
2298     Encodeb(0xF2);
2299     OpRR(destReg, srcReg, 0x0F, 0x5A);
2300 }
2301 
2302 /* unordered compare */
Ucomisd(Reg srcReg,Reg destReg)2303 void ElfAssembler::Ucomisd(Reg srcReg, Reg destReg)
2304 {
2305     Encodeb(0x66);
2306     OpRR(destReg, srcReg, 0x0F, 0x2E);
2307 }
2308 
Ucomiss(Reg srcReg,Reg destReg)2309 void ElfAssembler::Ucomiss(Reg srcReg, Reg destReg)
2310 {
2311     Encodeb(0x100);
2312     OpRR(destReg, srcReg, 0x0F, 0x2E);
2313 }
2314 
Cmpsd(Reg srcReg,Reg destReg,uint8 imm)2315 void ElfAssembler::Cmpsd(Reg srcReg, Reg destReg, uint8 imm)
2316 {
2317     Encodeb(0xF2);
2318     OpRR(destReg, srcReg, 0x0F, 0xC2);
2319     Encodeb(imm);
2320 }
2321 
Cmpeqsd(Reg srcReg,Reg destReg)2322 void ElfAssembler::Cmpeqsd(Reg srcReg, Reg destReg)
2323 {
2324     Cmpsd(srcReg, destReg, 0);
2325 }
2326 
2327 /* float sqrt*/
Sqrtss_r(Reg srcReg,Reg destReg)2328 void ElfAssembler::Sqrtss_r(Reg srcReg, Reg destReg)
2329 {
2330     Encodeb(0xF3);
2331     OpRR(destReg, srcReg, 0x0F, 0x51);
2332 }
2333 
Sqrtsd_r(Reg srcReg,Reg destReg)2334 void ElfAssembler::Sqrtsd_r(Reg srcReg, Reg destReg)
2335 {
2336     Encodeb(0xF2);
2337     OpRR(destReg, srcReg, 0x0F, 0x51);
2338 }
2339 /* end of X64 instructions */
2340 
2341 /* process stackmap */
RecordStackmap(const std::vector<uint8> & referenceMap,const std::vector<uint8> & deoptVreg2LocationInfo)2342 void ElfAssembler::RecordStackmap(const std::vector<uint8> &referenceMap,
2343                                   const std::vector<uint8> &deoptVreg2LocationInfo)
2344 {
2345     const auto &emitMemoryManager = maplebe::CGOptions::GetInstance().GetEmitMemoryManager();
2346     if (emitMemoryManager.codeSpace == nullptr) {
2347         return;
2348     }
2349     emitMemoryManager.pc2CallSiteInfoSaver(emitMemoryManager.codeSpace, lastModulePC + codeBuff.size(), referenceMap);
2350     emitMemoryManager.pc2DeoptInfoSaver(emitMemoryManager.codeSpace, lastModulePC + codeBuff.size(),
2351                                         deoptVreg2LocationInfo);
2352 }
2353 
GetCurModulePC()2354 uint32 ElfAssembler::GetCurModulePC()
2355 {
2356     return static_cast<uint32>(lastModulePC + codeBuff.size());
2357 }
2358 
SetLastModulePC(uint32 pc)2359 void ElfAssembler::SetLastModulePC(uint32 pc)
2360 {
2361     lastModulePC = pc;
2362 }
2363 } /* namespace assembler */