#include #include #include #include #include #include "asm.h" #define SECTBL_INIT_LEN 8 static const char inital_section[MAX_LEX_LENGTH] = "data"; int sectab_init(struct section_table *sectab) { sectab->size = SECTBL_INIT_LEN; sectab->len = 0; sectab->sections = malloc(sizeof(struct section) * SECTBL_INIT_LEN); if (sectab->sections == NULL) { ERROR("cannot alloc"); return M_ERROR; } if (sectab_alloc(sectab, §ab->current, inital_section)) return M_ERROR; return M_SUCCESS; } void sectab_free(struct section_table *sectab) { for (size_t i = 0; i < sectab->len; i++) { reltab_free(§ab->sections[i].reltab); free(sectab->sections[i].entries); } free(sectab->sections); } struct section_settings { const char *name; bool read; bool write; bool execute; size_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 sectab_alloc(struct section_table *sectab, struct section **res, const char name[MAX_LEX_LENGTH]) { if (sectab->len >= sectab->size) { sectab->size *= 2; sectab->sections = realloc(sectab->sections, sizeof(struct section) * sectab->size); if (sectab->sections == NULL) { ERROR("cannot realloc"); return M_ERROR; } } /* set the sectio defaults */ struct section *sec; sec = §ab->sections[sectab->len]; strcpy(sec->name,name); sec->len = 0; sec->size = SECTBL_INIT_LEN; sec->alignment = 1; sec->read = true; sec->write = true; sec->execute = false; sec->index = sectab->len; sec->entries = malloc(sizeof(struct section_entry) * SECTBL_INIT_LEN); if (reltab_init(&sec->reltab)) return M_ERROR; /* overwrite the default if the given name has their own * defaults */ for (int i = 0; i < 4; i++) { struct section_settings *set = &default_section_settings[i]; if (strcmp(set->name, name) == 0) { sec->read = set->read; sec->write = set->write; sec->execute = set->execute; sec->alignment = set->align; break; } } if (sec->entries == NULL) { ERROR("cannot alloc"); return M_ERROR; } sectab->len++; *res = sec; return M_SUCCESS; } int sectab_get(struct section_table *sectab, struct section **sec, const char name[MAX_LEX_LENGTH]) { for (size_t i = 0; i < sectab->len; i++) { struct section *temp = §ab->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->len >= section->size) { section->size *= 2; void *new = realloc(section->entries, sizeof(struct section_entry) * section->size); if (new == NULL) { ERROR("cannot realloc"); return M_ERROR; } section->entries = new; } section->entries[section->len++] = entry; return M_SUCCESS; } size_t sec_size(struct section *sec) { size_t n = 0; for (size_t i = 0; i < sec->len; 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, size_t idx) { size_t n = 0; for (size_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; }