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