#include #include #include #include #include #include "parse.h" #define SECTBL_INIT_LEN 8 static const char inital_section[MAX_LEX_LENGTH] = "data"; int sectbl_init(struct section_table *sec_tbl) { sec_tbl->len = SECTBL_INIT_LEN; sec_tbl->count = 0; sec_tbl->sections = malloc(sizeof(struct section) * SECTBL_INIT_LEN); if (sec_tbl->sections == NULL) { ERROR("cannot alloc"); return M_ERROR; } if (sectbl_alloc(sec_tbl, &sec_tbl->current, inital_section)) return M_ERROR; return M_SUCCESS; } void sectbl_free(struct section_table *sec_tbl) { for (uint32_t i = 0; i < sec_tbl->count; i++) { free(sec_tbl->sections[i].entries); } free(sec_tbl->sections); } struct section_settings { const char *name; bool read; bool write; bool execute; uint32_t align; }; static struct section_settings default_section_settings[] = { {"data", true, true, false, 1}, {"bss", true, true, false, 1}, {"rodata", true, false, false, 1}, {"text", true, false, true, 4}, }; int sectbl_alloc(struct section_table *sec_tbl, struct section **sec, const char name[MAX_LEX_LENGTH]) { if (sec_tbl->count >= sec_tbl->len) { sec_tbl->len *= 2; sec_tbl->sections = realloc(sec_tbl->sections, sizeof(struct section) * sec_tbl->len); if (sec_tbl->sections == NULL) { ERROR("cannot realloc"); return M_ERROR; } } struct section *temp; temp = &sec_tbl->sections[sec_tbl->count]; strcpy(temp->name,name); temp->count = 0; temp->len = SECTBL_INIT_LEN; temp->alignment = 1; temp->read = true; temp->write = true; temp->execute = false; temp->index = sec_tbl->count; temp->entries = malloc(sizeof(struct section_entry) * SECTBL_INIT_LEN); for (int i = 0; i < 4; i++) { struct section_settings *set = &default_section_settings[i]; if (strcmp(set->name, name) == 0) { temp->read = set->read; temp->write = set->write; temp->execute = set->execute; temp->alignment = set->align; break; } } if (temp->entries == NULL) { ERROR("cannot alloc"); return M_ERROR; } sec_tbl->count++; *sec = temp; return M_SUCCESS; } int sectbl_get(struct section_table *sec_tbl, struct section **sec, const char name[MAX_LEX_LENGTH]) { for (uint32_t i = 0; i < sec_tbl->count; i++) { struct section *temp = &sec_tbl->sections[i]; if (strcmp(name, temp->name) == 0) { if (sec != NULL) *sec = temp; return M_SUCCESS; } } return M_ERROR; } int sec_push(struct section *section, struct section_entry entry) { if (section->count >= section->len) { section->len *= 2; void *new = realloc(section->entries, sizeof(struct section_entry) * section->len); if (new == NULL) { ERROR("cannot realloc"); return M_ERROR; } section->entries = new; } section->entries[section->count++] = entry; return M_SUCCESS; } size_t sec_size(struct section *sec) { size_t n = 0; for (uint32_t i = 0; i < sec->count; i++) { size_t t = sec->entries[i].size; size_t m = t % sec->alignment; if (m) t += sec->alignment - m; n += t; } return n; } size_t sec_index(struct section *sec, uint32_t idx) { size_t n = 0; for (uint32_t i = 0; i < idx; i++) { size_t t = sec->entries[i].size; size_t m = t % sec->alignment; if (m) t += sec->alignment - m; n += t; } return n; }