asm: assembler: implement label creation and resolution
This commit is contained in:
@@ -63,6 +63,7 @@ enum ivy_status ivy_assembler_create(FILE *fp, struct ivy_assembler **as)
|
||||
|
||||
static void pad(struct ivy_assembler *as, unsigned int boundary)
|
||||
{
|
||||
fseek(as->as_data, as->as_data_offset, SEEK_SET);
|
||||
while ((as->as_data_offset % boundary) != 0) {
|
||||
fputc(0, as->as_data);
|
||||
as->as_data_offset++;
|
||||
@@ -75,6 +76,7 @@ enum ivy_status ivy_assembler_finish(struct ivy_assembler *as)
|
||||
size_t xdat_len = as->as_next_xdata_key;
|
||||
|
||||
fseek(as->as_xdat, 0, SEEK_SET);
|
||||
fseek(as->as_data, as->as_data_offset, SEEK_SET);
|
||||
unsigned char *buf = malloc(buf_len);
|
||||
|
||||
if (!buf) {
|
||||
@@ -143,16 +145,40 @@ enum ivy_status ivy_assembler_finish(struct ivy_assembler *as)
|
||||
return IVY_OK;
|
||||
}
|
||||
|
||||
size_t ivy_assembler_get_ptr(const struct ivy_assembler *as)
|
||||
{
|
||||
return as->as_data_offset;
|
||||
}
|
||||
|
||||
size_t assembler_write_data(struct ivy_assembler *as, const void *p, size_t len)
|
||||
{
|
||||
size_t offset = as->as_data_offset;
|
||||
|
||||
fwrite(p, 1, len, as->as_data);
|
||||
fseek(as->as_data, offset, SEEK_SET);
|
||||
size_t w = fwrite(p, 1, len, as->as_data);
|
||||
|
||||
as->as_data_offset += len;
|
||||
return offset;
|
||||
}
|
||||
|
||||
enum ivy_status assembler_read_data_at(
|
||||
struct ivy_assembler *as, void *p, size_t offset, size_t len, size_t *nr_read)
|
||||
{
|
||||
fseek(as->as_data, offset, SEEK_SET);
|
||||
*nr_read = fread(p, 1, len, as->as_data);
|
||||
|
||||
return ferror(as->as_data) ? IVY_ERR_IO_FAILURE : IVY_OK;
|
||||
}
|
||||
|
||||
size_t assembler_write_data_at(
|
||||
struct ivy_assembler *as, const void *p, size_t offset, size_t len)
|
||||
{
|
||||
fseek(as->as_data, offset, SEEK_SET);
|
||||
fwrite(p, 1, len, as->as_data);
|
||||
|
||||
return ferror(as->as_data) ? IVY_ERR_IO_FAILURE : IVY_OK;
|
||||
}
|
||||
|
||||
ivy_extended_data_key assembler_write_extended_data(
|
||||
struct ivy_assembler *as, const void *p, size_t len)
|
||||
{
|
||||
@@ -193,10 +219,7 @@ enum ivy_status ivy_assembler_begin_scope(
|
||||
|
||||
memset(scope, 0x0, type_info->s_scope_size);
|
||||
|
||||
while ((as->as_data_offset % 16) != 0) {
|
||||
fputc(0, as->as_data);
|
||||
as->as_data_offset++;
|
||||
}
|
||||
pad(as, 16);
|
||||
|
||||
scope->s_ops = type_info;
|
||||
scope->s_type = type;
|
||||
@@ -314,3 +337,39 @@ enum ivy_status ivy_assembler_put_instr(
|
||||
|
||||
return type_info->s_put_instr(as, scope, i);
|
||||
}
|
||||
|
||||
enum ivy_status ivy_assembler_put_label(
|
||||
struct ivy_assembler *as, const struct ivy_asm_token *label_name,
|
||||
size_t label_offset)
|
||||
{
|
||||
struct assembler_scope *scope = as->as_scope;
|
||||
|
||||
if (!scope) {
|
||||
return IVY_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
const struct assembler_scope_type *type_info = scope->s_ops;
|
||||
if (!type_info || !type_info->s_put_label) {
|
||||
return IVY_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return type_info->s_put_label(as, scope, label_name, label_offset);
|
||||
}
|
||||
|
||||
enum ivy_status ivy_assembler_put_label_ref(
|
||||
struct ivy_assembler *as, const struct ivy_asm_token *label_name,
|
||||
size_t ref_offset)
|
||||
{
|
||||
struct assembler_scope *scope = as->as_scope;
|
||||
|
||||
if (!scope) {
|
||||
return IVY_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
const struct assembler_scope_type *type_info = scope->s_ops;
|
||||
if (!type_info || !type_info->s_put_label_ref) {
|
||||
return IVY_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return type_info->s_put_label_ref(as, scope, label_name, ref_offset);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user