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