91 lines
2.1 KiB
C
91 lines
2.1 KiB
C
// SPDX-FileCopyrightText: 2009-2020 pancake <pancake@nopcode.org>
|
|
// SPDX-FileCopyrightText: 2009-2020 eagleoflqj <liumeo@pku.edu.cn>
|
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
|
|
#include "binutils_as.h"
|
|
|
|
int binutils_assemble(RzAsm *a, RzAsmOp *op, const char *buf, const char *as, const char *env, const char *header, const char *cmd_opt) {
|
|
char *user_as = rz_sys_getenv(env);
|
|
if (user_as) {
|
|
as = user_as;
|
|
}
|
|
if (RZ_STR_ISEMPTY(as)) {
|
|
RZ_LOG_ERROR("Please set '%s' env to define a '%s' assembler program\n", env, a->cur->arch);
|
|
free(user_as);
|
|
return 1;
|
|
}
|
|
|
|
char *ipath, *opath;
|
|
int ifd = rz_file_mkstemp("rz_as", &ipath);
|
|
if (ifd == -1) {
|
|
free(user_as);
|
|
return -1;
|
|
}
|
|
int ofd = rz_file_mkstemp("rz_as", &opath);
|
|
if (ofd == -1) {
|
|
free(user_as);
|
|
free(ipath);
|
|
close(ifd);
|
|
return -1;
|
|
}
|
|
|
|
int res = -1;
|
|
char *asm_buf = rz_str_newf("%s"
|
|
".ascii \" BEGINMARK\"\n" // 4 bit align
|
|
"%s\n"
|
|
".ascii \"ENDMARK\"\n",
|
|
header, buf);
|
|
if (!asm_buf) {
|
|
goto beach;
|
|
}
|
|
const size_t asm_buf_len = strlen(asm_buf);
|
|
const bool success = write(ifd, asm_buf, asm_buf_len) == asm_buf_len;
|
|
free(asm_buf);
|
|
if (!success) {
|
|
goto beach;
|
|
}
|
|
|
|
char cmd[4096];
|
|
snprintf(cmd, sizeof(cmd), "%s %s %s -o %s", as, cmd_opt, ipath, opath);
|
|
if (!rz_sys_system(cmd)) {
|
|
int len = 0;
|
|
const ut8 *begin, *end;
|
|
close(ofd);
|
|
ofd = rz_sys_open(opath, O_BINARY | O_RDONLY, 0644);
|
|
if (ofd < 0) {
|
|
goto skip_ofd;
|
|
}
|
|
ut8 obuf[4096];
|
|
len = read(ofd, obuf, sizeof(obuf));
|
|
begin = rz_mem_mem(obuf, len, (const ut8 *)"BEGINMARK", 9);
|
|
end = rz_mem_mem(obuf, len, (const ut8 *)"ENDMARK", 7);
|
|
if (!begin || !end) {
|
|
RZ_LOG_ERROR("Cannot find water marks BEGINMARK or/and ENDMARK\n");
|
|
len = 0;
|
|
} else {
|
|
len = (int)(size_t)(end - begin - 9);
|
|
if (len > 0) {
|
|
rz_strbuf_setbin(&op->buf, begin + 9, len);
|
|
} else {
|
|
len = 0;
|
|
}
|
|
}
|
|
res = op->size = len;
|
|
} else {
|
|
RZ_LOG_ERROR("Failed to run command: '%s'\n", cmd);
|
|
}
|
|
|
|
beach:
|
|
close(ofd);
|
|
skip_ofd:
|
|
close(ifd);
|
|
|
|
unlink(ipath);
|
|
unlink(opath);
|
|
|
|
free(ipath);
|
|
free(opath);
|
|
free(user_as);
|
|
|
|
return res;
|
|
}
|