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