update mld comments
This commit is contained in:
parent
47d226cf36
commit
64a7a67f00
6 changed files with 58 additions and 25 deletions
|
@ -12,12 +12,11 @@ PREFIX=/usr/local
|
||||||
|
|
||||||
# ======================== CONFIG OPTIONS ==
|
# ======================== CONFIG OPTIONS ==
|
||||||
#
|
#
|
||||||
# MAX LEX LENGTH
|
# MAX EXT LENGTH
|
||||||
# Specifies how long a ident, register,
|
# Specifies how long a stirng extension in a
|
||||||
# instruction name, or any type of variable
|
# shdr entry name can be.
|
||||||
# length text can be inside the lexer
|
|
||||||
#
|
#
|
||||||
# CFLAGS+= -DMAX_LEX_LENGTH=24
|
# CFLAGS+= -DMAX_EXT_LENGTH=48
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# MAX_ARG_LENGTH
|
# MAX_ARG_LENGTH
|
||||||
|
|
|
@ -32,7 +32,7 @@ static const Elf32_Ehdr MIPS_ELF_EHDR =
|
||||||
.e_machine = B16(EM_MIPS),
|
.e_machine = B16(EM_MIPS),
|
||||||
.e_version = B32(EV_CURRENT),
|
.e_version = B32(EV_CURRENT),
|
||||||
.e_entry = 0x00,
|
.e_entry = 0x00,
|
||||||
.e_flags = 0x00, // B32(EF_MIPS_ARCH_32R6),
|
.e_flags = B32(EF_MIPS_ARCH_32R6 | EF_MIPS_NAN2008 | EF_MIPS_ABI_O32),
|
||||||
.e_ehsize = B16(sizeof(Elf32_Ehdr)),
|
.e_ehsize = B16(sizeof(Elf32_Ehdr)),
|
||||||
.e_phentsize = B16(sizeof(Elf32_Phdr)),
|
.e_phentsize = B16(sizeof(Elf32_Phdr)),
|
||||||
.e_shentsize = B16(sizeof(Elf32_Shdr)),
|
.e_shentsize = B16(sizeof(Elf32_Shdr)),
|
||||||
|
|
|
@ -3,12 +3,11 @@
|
||||||
#ifndef __MLIMITS_H__
|
#ifndef __MLIMITS_H__
|
||||||
#define __MLIMITS_H__
|
#define __MLIMITS_H__
|
||||||
|
|
||||||
/* Specifies how long a ident, register,
|
/* Specifies how long a stirng extension in a
|
||||||
* instruction name, or any type of variable
|
* shdr entry name can be.
|
||||||
* length text can be inside the lexer.
|
|
||||||
*/
|
*/
|
||||||
#ifndef MAX_LEX_LENGTH
|
#ifndef MAX_EXT_LENGTH
|
||||||
#define MAX_LEX_LENGTH 24
|
#define MAX_EXT_LENGTH 48
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Specifices how many max arguments a
|
/* Specifices how many max arguments a
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
#include "asm.h"
|
#include "asm.h"
|
||||||
#include "gen.h"
|
#include "gen.h"
|
||||||
#include "mlimits.h"
|
|
||||||
#include "tab.h"
|
#include "tab.h"
|
||||||
|
|
||||||
extern char *current_file;
|
extern char *current_file;
|
||||||
|
@ -202,14 +201,14 @@ static int assemble_shdr(struct assembler *assembler, Elf32_Shdr **res,
|
||||||
for (uint32_t i = 0; i < assembler->section_len; i++) {
|
for (uint32_t i = 0; i < assembler->section_len; i++) {
|
||||||
struct elf_section *sec = &assembler->sections[i];
|
struct elf_section *sec = &assembler->sections[i];
|
||||||
const char *prefix = ".reltab";
|
const char *prefix = ".reltab";
|
||||||
char reltab_name[MAX_LEX_LENGTH + strlen(prefix)];
|
char reltab_name[MAX_EXT_LENGTH + strlen(prefix)];
|
||||||
|
|
||||||
if (sec->reltab_len == 0)
|
if (sec->reltab_len == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
strcpy(reltab_name, prefix);
|
strcpy(reltab_name, prefix);
|
||||||
strncat(reltab_name, sec->data->name.str,
|
strncat(reltab_name, sec->data->name.str,
|
||||||
MAX_LEX_LENGTH - strlen(prefix));
|
MAX_EXT_LENGTH - strlen(prefix));
|
||||||
|
|
||||||
if (strtab_write_str(&assembler->shstrtab,
|
if (strtab_write_str(&assembler->shstrtab,
|
||||||
reltab_name, &str_off)) {
|
reltab_name, &str_off)) {
|
||||||
|
|
29
mld/link.c
29
mld/link.c
|
@ -47,6 +47,7 @@ static int load_objects(struct linker *linker)
|
||||||
skip_obj:
|
skip_obj:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// load runtime object if not set to be freestanding
|
||||||
if (linker->args->freestanding == false) {
|
if (linker->args->freestanding == false) {
|
||||||
#define _STR(x) _STR2(x)
|
#define _STR(x) _STR2(x)
|
||||||
#define _STR2(x) #x
|
#define _STR2(x) #x
|
||||||
|
@ -69,6 +70,9 @@ skip_obj:
|
||||||
*/
|
*/
|
||||||
static int relocate_segment_name(struct linker *linker, const char *name)
|
static int relocate_segment_name(struct linker *linker, const char *name)
|
||||||
{
|
{
|
||||||
|
// find each segment with the provided segment name,
|
||||||
|
// and then relocate them
|
||||||
|
|
||||||
for (size_t i = 0; i < linker->obj_len; i++) {
|
for (size_t i = 0; i < linker->obj_len; i++) {
|
||||||
struct object *obj = &linker->objects[i];
|
struct object *obj = &linker->objects[i];
|
||||||
for (size_t j = 0; j < obj->segment_len; j++) {
|
for (size_t j = 0; j < obj->segment_len; j++) {
|
||||||
|
@ -122,6 +126,7 @@ static int relocate_segment_name(struct linker *linker, const char *name)
|
||||||
M_SUCCESS) {
|
M_SUCCESS) {
|
||||||
if (segtab_ent_push(ent, seg))
|
if (segtab_ent_push(ent, seg))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
|
// otherwise create a new segment table entry
|
||||||
} else {
|
} else {
|
||||||
// update vaddr to be page aligned
|
// update vaddr to be page aligned
|
||||||
uint32_t m = seg->new_vaddr % SEC_ALIGN;
|
uint32_t m = seg->new_vaddr % SEC_ALIGN;
|
||||||
|
@ -134,7 +139,7 @@ static int relocate_segment_name(struct linker *linker, const char *name)
|
||||||
linker->data_vaddr += add;
|
linker->data_vaddr += add;
|
||||||
}
|
}
|
||||||
|
|
||||||
// else create a new segment
|
// create a new segment
|
||||||
if (segtab_push(&linker->segments, NULL, seg))
|
if (segtab_push(&linker->segments, NULL, seg))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -146,6 +151,9 @@ static int relocate_segment_name(struct linker *linker, const char *name)
|
||||||
|
|
||||||
static int relocate_segments(struct linker *linker)
|
static int relocate_segments(struct linker *linker)
|
||||||
{
|
{
|
||||||
|
// for each object, find each different
|
||||||
|
// unique segment name
|
||||||
|
|
||||||
for (size_t i = 0; i < linker->obj_len; i++) {
|
for (size_t i = 0; i < linker->obj_len; i++) {
|
||||||
struct object *obj = &linker->objects[i];
|
struct object *obj = &linker->objects[i];
|
||||||
for (size_t j = 0; j < obj->segment_len; j++) {
|
for (size_t j = 0; j < obj->segment_len; j++) {
|
||||||
|
@ -154,6 +162,9 @@ static int relocate_segments(struct linker *linker)
|
||||||
// check if the segment has already been relocated
|
// check if the segment has already been relocated
|
||||||
if (seg->new_vaddr != 0)
|
if (seg->new_vaddr != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// relocate each segment with that segment
|
||||||
|
// name
|
||||||
if(relocate_segment_name(linker, seg->name))
|
if(relocate_segment_name(linker, seg->name))
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -165,6 +176,14 @@ static int relocate_segments(struct linker *linker)
|
||||||
static int relocate_symbol(struct linker *linker, struct object *obj,
|
static int relocate_symbol(struct linker *linker, struct object *obj,
|
||||||
struct symbol_table *symtab, const Elf32_Sym *sym)
|
struct symbol_table *symtab, const Elf32_Sym *sym)
|
||||||
{
|
{
|
||||||
|
// given the symbol and the object its in
|
||||||
|
// 1. make sure the symbol is valid
|
||||||
|
// 2. get the segment in the object that the symbol is in
|
||||||
|
// 3. get tthe segment table entry that the segment is also
|
||||||
|
// in. This allows us to get the offset into the segment_table
|
||||||
|
// 4. the new shndx is the offset + 1 (since segments start at
|
||||||
|
// shndx 1
|
||||||
|
|
||||||
size_t shndx = B16(sym->st_shndx);
|
size_t shndx = B16(sym->st_shndx);
|
||||||
if (shndx == 0 || shndx == SHN_ABS)
|
if (shndx == 0 || shndx == SHN_ABS)
|
||||||
return M_SUCCESS; // ignore this symbol
|
return M_SUCCESS; // ignore this symbol
|
||||||
|
@ -177,11 +196,15 @@ static int relocate_symbol(struct linker *linker, struct object *obj,
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make sure the symbol name is
|
||||||
|
// in bounds
|
||||||
if (B32(sym->st_name) >= symtab->strtab->len) {
|
if (B32(sym->st_name) >= symtab->strtab->len) {
|
||||||
ERROR("symbol name out of bounds");
|
ERROR("symbol name out of bounds");
|
||||||
return M_ERROR;
|
return M_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// find the segment that this symbol
|
||||||
|
// is contained in
|
||||||
struct segment *sec = NULL;
|
struct segment *sec = NULL;
|
||||||
for (size_t i = 0; i < obj->phdr_len; i++) {
|
for (size_t i = 0; i < obj->phdr_len; i++) {
|
||||||
if (obj->phdr_to_shdr_mapping[i] == shndx) {
|
if (obj->phdr_to_shdr_mapping[i] == shndx) {
|
||||||
|
@ -245,13 +268,17 @@ static int relocate_symbol(struct linker *linker, struct object *obj,
|
||||||
|
|
||||||
static int relocate_symbols(struct linker *linker)
|
static int relocate_symbols(struct linker *linker)
|
||||||
{
|
{
|
||||||
|
// relocate in each object
|
||||||
for (size_t i = 0; i < linker->obj_len; i++) {
|
for (size_t i = 0; i < linker->obj_len; i++) {
|
||||||
struct object *obj = &linker->objects[i];
|
struct object *obj = &linker->objects[i];
|
||||||
|
// look though each shdr entry and find
|
||||||
|
// any symbol tables
|
||||||
for (size_t j = 0; j < obj->shdr_len; j++) {
|
for (size_t j = 0; j < obj->shdr_len; j++) {
|
||||||
struct symbol_table *symtab = &obj->symtabs[j];
|
struct symbol_table *symtab = &obj->symtabs[j];
|
||||||
if (symtab->len < 1)
|
if (symtab->len < 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// for each symbol in the table, relocate it
|
||||||
for (size_t k = 0; k < symtab->len; k++) {
|
for (size_t k = 0; k < symtab->len; k++) {
|
||||||
const Elf32_Sym *sym = &symtab->syms[k];
|
const Elf32_Sym *sym = &symtab->syms[k];
|
||||||
if (relocate_symbol(linker, obj, symtab, sym))
|
if (relocate_symbol(linker, obj, symtab, sym))
|
||||||
|
|
29
mld/link.h
29
mld/link.h
|
@ -92,11 +92,6 @@ struct symbol_table {
|
||||||
struct symbol_table_mapping *map;
|
struct symbol_table_mapping *map;
|
||||||
};
|
};
|
||||||
|
|
||||||
///
|
|
||||||
/// symbol table map
|
|
||||||
/// (metadata for each symbol)
|
|
||||||
///
|
|
||||||
|
|
||||||
int symtab_init(struct symbol_table *symtab);
|
int symtab_init(struct symbol_table *symtab);
|
||||||
void symtab_free(struct symbol_table *symtab);
|
void symtab_free(struct symbol_table *symtab);
|
||||||
|
|
||||||
|
@ -104,6 +99,13 @@ int symtab_push(struct symbol_table *symtab, const Elf32_Sym *sym);
|
||||||
int symtab_get(struct symbol_table *symtab, Elf32_Sym **sym, const char *name,
|
int symtab_get(struct symbol_table *symtab, Elf32_Sym **sym, const char *name,
|
||||||
int32_t obj_idx);
|
int32_t obj_idx);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// symbol table map
|
||||||
|
/// (metadata for each symbol)
|
||||||
|
/// stores each object that a symbol
|
||||||
|
/// is in
|
||||||
|
///
|
||||||
|
|
||||||
struct symbol_table_mapping {
|
struct symbol_table_mapping {
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
|
@ -163,6 +165,9 @@ int segment_load(struct object *object, struct segment *segment, size_t index);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// segment table
|
/// segment table
|
||||||
|
/// holds each segment that
|
||||||
|
/// share the same name
|
||||||
|
/// (i.e. all .text segments)
|
||||||
///
|
///
|
||||||
|
|
||||||
struct segment_table_entry {
|
struct segment_table_entry {
|
||||||
|
@ -172,6 +177,7 @@ struct segment_table_entry {
|
||||||
uint32_t off;
|
uint32_t off;
|
||||||
uint32_t vaddr;
|
uint32_t vaddr;
|
||||||
// weak segment pointers. we do not own these!!!
|
// weak segment pointers. we do not own these!!!
|
||||||
|
// (but we own the array)
|
||||||
struct segment **parts;
|
struct segment **parts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -181,9 +187,10 @@ void segtab_ent_free(struct segment_table_entry *ent);
|
||||||
int segtab_ent_push(struct segment_table_entry *ent, struct segment *seg);
|
int segtab_ent_push(struct segment_table_entry *ent, struct segment *seg);
|
||||||
uint32_t segtab_ent_size(struct segment_table_entry *ent);
|
uint32_t segtab_ent_size(struct segment_table_entry *ent);
|
||||||
|
|
||||||
// holds each segment by name
|
///
|
||||||
// and all the segment parts from each of the
|
/// segment table
|
||||||
// object files
|
/// holds each segment table entry by name
|
||||||
|
///
|
||||||
struct segment_table {
|
struct segment_table {
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
|
@ -215,14 +222,16 @@ struct object {
|
||||||
Elf32_Ehdr *ehdr;
|
Elf32_Ehdr *ehdr;
|
||||||
|
|
||||||
// section header table
|
// section header table
|
||||||
Elf32_Shdr *shdr;
|
Elf32_Shdr *shdr; // weak
|
||||||
size_t shdr_len;
|
size_t shdr_len;
|
||||||
|
|
||||||
// program table
|
// program table
|
||||||
Elf32_Phdr *phdr;
|
Elf32_Phdr *phdr; // owned
|
||||||
size_t phdr_len;
|
size_t phdr_len;
|
||||||
|
|
||||||
// phdr <=> shdr mappings
|
// phdr <=> shdr mappings
|
||||||
|
// need a way to find any assoiciated
|
||||||
|
// phdr with a shdr, and also reverse
|
||||||
uint32_t *phdr_to_shdr_mapping;
|
uint32_t *phdr_to_shdr_mapping;
|
||||||
|
|
||||||
// object meta
|
// object meta
|
||||||
|
|
Loading…
Reference in a new issue