1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2024-11-10 19:20:13 +00:00

Add support for 'after' and 'number' in mkldscript and use 'after' to properly shift the code segment (#194)

* Add support for 'after' and 'number' in mkldscript

* Use 'after' in spec to ensure code ends up after dmadata in RAM
This commit is contained in:
Roman971 2020-06-07 16:31:11 +02:00 committed by GitHub
parent c10bcdc3c4
commit e413325637
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 24 deletions

2
spec
View file

@ -268,7 +268,7 @@ endseg
beginseg beginseg
name "code" name "code"
address 0x8001CE60 after "dmadata"
include "build/src/code/z_en_a_keep.o" include "build/src/code/z_en_a_keep.o"
include "build/src/code/z_en_item00.o" include "build/src/code/z_en_item00.o"
include "build/data/z_en_item00.data.o" include "build/data/z_en_item00.data.o"

View file

@ -6,7 +6,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
//#include "opts.h"
#include "util.h" #include "util.h"
#define ARRAY_COUNT(arr) (sizeof(arr) / sizeof(arr[0])) #define ARRAY_COUNT(arr) (sizeof(arr) / sizeof(arr[0]))
@ -16,6 +15,7 @@ static FILE *fout;
enum enum
{ {
STMT_address, STMT_address,
STMT_after,
STMT_align, STMT_align,
STMT_beginseg, STMT_beginseg,
STMT_endseg, STMT_endseg,
@ -23,6 +23,7 @@ enum
STMT_flags, STMT_flags,
STMT_include, STMT_include,
STMT_name, STMT_name,
STMT_number,
STMT_romalign, STMT_romalign,
STMT_stack, STMT_stack,
STMT_increment, STMT_increment,
@ -39,6 +40,7 @@ struct Segment
{ {
uint32_t fields; uint32_t fields;
char *name; char *name;
char *after;
uint32_t flags; uint32_t flags;
uint32_t address; uint32_t address;
uint32_t stack; uint32_t stack;
@ -46,6 +48,7 @@ struct Segment
uint32_t romalign; uint32_t romalign;
uint32_t increment; uint32_t increment;
uint32_t entry; uint32_t entry;
uint32_t number;
char **includes; char **includes;
int includesCount; int includesCount;
}; };
@ -165,17 +168,19 @@ static bool is_pow_of_2(unsigned int n)
static const char *const stmtNames[] = static const char *const stmtNames[] =
{ {
[STMT_address] = "address", [STMT_address] = "address",
[STMT_align] = "align", [STMT_after] = "after",
[STMT_beginseg] = "beginseg", [STMT_align] = "align",
[STMT_endseg] = "endseg", [STMT_beginseg] = "beginseg",
[STMT_entry] = "entry", [STMT_endseg] = "endseg",
[STMT_flags] = "flags", [STMT_entry] = "entry",
[STMT_include] = "include", [STMT_flags] = "flags",
[STMT_name] = "name", [STMT_include] = "include",
[STMT_romalign] = "romalign", [STMT_name] = "name",
[STMT_stack] = "stack", [STMT_number] = "number",
[STMT_increment] = "increment", [STMT_romalign] = "romalign",
[STMT_stack] = "stack",
[STMT_increment] = "increment",
}; };
static void parse_rom_spec(char *spec) static void parse_rom_spec(char *spec)
@ -228,10 +233,18 @@ static void parse_rom_spec(char *spec)
if (!parse_quoted_string(args, &currSeg->name)) if (!parse_quoted_string(args, &currSeg->name))
util_fatal_error("line %i: invalid name", lineNum); util_fatal_error("line %i: invalid name", lineNum);
break; break;
case STMT_after:
if (!parse_quoted_string(args, &currSeg->after))
util_fatal_error("line %i: invalid name for 'after'", lineNum);
break;
case STMT_address: case STMT_address:
if (!parse_number(args, &currSeg->address)) if (!parse_number(args, &currSeg->address))
util_fatal_error("line %i: expected number after 'address'", lineNum); util_fatal_error("line %i: expected number after 'address'", lineNum);
break; break;
case STMT_number:
if (!parse_number(args, &currSeg->number))
util_fatal_error("line %i: expected number after 'number'", lineNum);
break;
case STMT_flags: case STMT_flags:
if (!parse_flags(args, &currSeg->flags)) if (!parse_flags(args, &currSeg->flags))
util_fatal_error("line %i: invalid flags", lineNum); util_fatal_error("line %i: invalid flags", lineNum);
@ -242,23 +255,21 @@ static void parse_rom_spec(char *spec)
if (!is_pow_of_2(currSeg->align)) if (!is_pow_of_2(currSeg->align))
util_fatal_error("line %i: alignment is not a power of two", lineNum); util_fatal_error("line %i: alignment is not a power of two", lineNum);
break; break;
case STMT_include:
currSeg->includesCount++;
currSeg->includes = realloc(currSeg->includes, currSeg->includesCount * sizeof(*currSeg->includes));
if (!parse_quoted_string(args, &currSeg->includes[currSeg->includesCount - 1]))
util_fatal_error("line %i: invalid filename", lineNum);
break;
case STMT_romalign: case STMT_romalign:
if (!parse_number(args, &currSeg->romalign)) if (!parse_number(args, &currSeg->romalign))
util_fatal_error("line %i: expected number after 'romalign'", lineNum); util_fatal_error("line %i: expected number after 'romalign'", lineNum);
if (!is_pow_of_2(currSeg->romalign)) if (!is_pow_of_2(currSeg->romalign))
util_fatal_error("line %i: alignment is not a power of two", lineNum); util_fatal_error("line %i: alignment is not a power of two", lineNum);
break; break;
case STMT_include:
currSeg->includesCount++;
currSeg->includes = realloc(currSeg->includes, currSeg->includesCount * sizeof(*currSeg->includes));
if (!parse_quoted_string(args, &currSeg->includes[currSeg->includesCount - 1]))
util_fatal_error("line %i: invalid filename", lineNum);
break;
case STMT_increment: case STMT_increment:
if (!parse_number(args, &currSeg->increment)) if (!parse_number(args, &currSeg->increment))
util_fatal_error("line %i: expected number after 'increment'", lineNum); util_fatal_error("line %i: expected number after 'increment'", lineNum);
//if (!is_pow_of_2(currSeg->romalign))
//util_fatal_error("line %i: alignment is not a power of two", lineNum);
break; break;
default: default:
fprintf(stderr, "warning: '%s' is not implemented\n", stmtName); fprintf(stderr, "warning: '%s' is not implemented\n", stmtName);
@ -314,10 +325,14 @@ static void write_ld_script(void)
fprintf(fout, " _%sSegmentRomStart = _RomSize;\n" fprintf(fout, " _%sSegmentRomStart = _RomSize;\n"
" ..%s ", seg->name, seg->name); " ..%s ", seg->name, seg->name);
if (seg->address != 0)
{ if (seg->fields & (1 << STMT_after))
fprintf(fout, "_%sSegmentEnd ", seg->after);
else if (seg->fields & (1 << STMT_number))
fprintf(fout, "0x%02X000000 ", seg->number);
else if (seg->fields & (1 << STMT_address))
fprintf(fout, "0x%08X ", seg->address); fprintf(fout, "0x%08X ", seg->address);
}
// (AT(_RomSize) isn't necessary, but adds useful "load address" lines to the map file) // (AT(_RomSize) isn't necessary, but adds useful "load address" lines to the map file)
fprintf(fout, ": AT(_RomSize)\n {\n" fprintf(fout, ": AT(_RomSize)\n {\n"
" _%sSegmentStart = .;\n" " _%sSegmentStart = .;\n"