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