2024-09-09 16:41:49 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <mips.h>
|
|
|
|
#include <merror.h>
|
|
|
|
#include <mlimits.h>
|
|
|
|
|
|
|
|
#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;
|
2024-09-10 00:48:08 +00:00
|
|
|
sec_tbl->sections = malloc(sizeof(struct section) * SECTBL_INIT_LEN);
|
2024-09-09 16:41:49 +00:00
|
|
|
|
2024-09-10 00:48:08 +00:00
|
|
|
if (sec_tbl->sections == NULL) {
|
|
|
|
ERROR("cannot alloc");
|
|
|
|
return M_ERROR;
|
|
|
|
}
|
2024-09-09 16:41:49 +00:00
|
|
|
|
|
|
|
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++) {
|
2024-09-10 00:48:08 +00:00
|
|
|
free(sec_tbl->sections[i].entries);
|
2024-09-09 16:41:49 +00:00
|
|
|
}
|
|
|
|
free(sec_tbl->sections);
|
|
|
|
}
|
|
|
|
|
2024-09-10 00:48:08 +00:00
|
|
|
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},
|
|
|
|
};
|
|
|
|
|
2024-09-09 16:41:49 +00:00
|
|
|
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;
|
2024-09-10 00:48:08 +00:00
|
|
|
temp = &sec_tbl->sections[sec_tbl->count];
|
2024-09-09 16:41:49 +00:00
|
|
|
strcpy(temp->name,name);
|
|
|
|
temp->count = 0;
|
|
|
|
temp->len = SECTBL_INIT_LEN;
|
|
|
|
temp->alignment = 1;
|
2024-09-10 00:48:08 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2024-09-09 16:41:49 +00:00
|
|
|
|
2024-09-10 00:48:08 +00:00
|
|
|
if (temp->entries == NULL) {
|
2024-09-09 16:41:49 +00:00
|
|
|
ERROR("cannot alloc");
|
|
|
|
return M_ERROR;
|
|
|
|
}
|
|
|
|
|
2024-09-10 00:48:08 +00:00
|
|
|
sec_tbl->count++;
|
|
|
|
|
2024-09-09 16:41:49 +00:00
|
|
|
*sec = temp;
|
|
|
|
return M_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2024-09-10 00:48:08 +00:00
|
|
|
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)
|
2024-09-09 16:41:49 +00:00
|
|
|
{
|
|
|
|
if (section->count >= section->len) {
|
|
|
|
section->len *= 2;
|
2024-09-10 00:48:08 +00:00
|
|
|
void *new = realloc(section->entries,
|
|
|
|
sizeof(struct section_entry) * section->len);
|
2024-09-09 16:41:49 +00:00
|
|
|
|
2024-09-10 00:48:08 +00:00
|
|
|
if (new == NULL) {
|
2024-09-09 16:41:49 +00:00
|
|
|
ERROR("cannot realloc");
|
|
|
|
return M_ERROR;
|
|
|
|
}
|
2024-09-10 00:48:08 +00:00
|
|
|
|
|
|
|
section->entries = new;
|
2024-09-09 16:41:49 +00:00
|
|
|
}
|
|
|
|
|
2024-09-10 00:48:08 +00:00
|
|
|
section->entries[section->count++] = entry;
|
2024-09-09 16:41:49 +00:00
|
|
|
|
|
|
|
return M_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2024-09-10 00:48:08 +00:00
|
|
|
size_t sec_size(struct section *sec)
|
2024-09-09 16:41:49 +00:00
|
|
|
{
|
2024-09-10 00:48:08 +00:00
|
|
|
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;
|
2024-09-09 16:41:49 +00:00
|
|
|
}
|
2024-09-10 00:48:08 +00:00
|
|
|
return n;
|
|
|
|
}
|
2024-09-09 16:41:49 +00:00
|
|
|
|
2024-09-10 00:48:08 +00:00
|
|
|
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;
|
2024-09-09 16:41:49 +00:00
|
|
|
}
|