-
Notifications
You must be signed in to change notification settings - Fork 0
/
assemble.cpp
82 lines (67 loc) · 2.3 KB
/
assemble.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <stdio.h>
#include <stdlib.h>
#include "assemble.h"
using std::string;
using std::vector;
const static char AArch64LLVMMC[] = "llvm-mc -filetype=obj -triple=aarch64 -mattr=+sve %s -o %s";
const static char X86LLVMMC[] = "llvm-mc -filetype=obj -triple=x86_64 -x86-asm-syntax=intel %s -o %s";
#ifndef NDEBUG
const static char AArch64LLVMMC_DISPLAY[] =
"llvm-mc -filetype=asm -show-encoding -triple=aarch64 -mattr=+sve %s";
const static char X86_64LLVMMC_DISPLAY[] = "llvm-mc -filetype=asm -show-encoding -x86-asm-syntax=intel -triple=x86_64 %s";
#endif
const static unsigned MaxInstNum = 0x100000;
bool assemble(ArchType arch, const string &asmcode, InstBytes &bincode) {
char asmfilename[260];
char objfilename[260];
tmpnam(asmfilename);
tmpnam(objfilename);
FILE *asmfile = fopen(asmfilename, "w");
if (asmfile == nullptr)
return false;
fputs(asmcode.c_str(), asmfile);
fclose(asmfile);
char cmd[256];
sprintf(cmd, (arch == ArchType::X86_64) ? X86LLVMMC : AArch64LLVMMC, asmfilename, objfilename);
system(cmd);
#ifndef NDEBUG
sprintf(cmd, (arch == ArchType::X86_64) ? X86_64LLVMMC_DISPLAY : AArch64LLVMMC_DISPLAY,
asmfilename);
system(cmd);
#endif
remove(asmfilename);
FILE *objfile = fopen(objfilename, "rb");
if (objfile == nullptr)
return false;
const unsigned elf_header_szie = 64;
char elf_header[elf_header_szie];
size_t readsize;
readsize = fread(elf_header, 1, elf_header_szie, objfile);
if (readsize != elf_header_szie) {
fclose(objfile);
remove(objfilename);
return false;
}
unsigned buffersize = *(unsigned *)(elf_header + 40) - 0x40 + 0xa0;
void *instbuff = malloc(buffersize);
readsize = fread(instbuff, 1, buffersize, objfile);
if (readsize != buffersize || buffersize >= MaxInstNum) {
fclose(objfile);
remove(objfilename);
return false;
}
unsigned instsize = 0;
readsize = fread(&instsize, 1, 4, objfile);
if (readsize != 4 || instsize >= MaxInstNum) {
free(instbuff);
fclose(objfile);
remove(objfilename);
return false;
}
bincode.resize(instsize);
memcpy(&bincode[0], instbuff, instsize);
free(instbuff);
fclose(objfile);
remove(objfilename);
return true;
}