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