REVISION := r$(shell git rev-list --count HEAD):$(shell git rev-parse HEAD | head -c8)
ASFLAGS := -mlittle-endian -mcpu=arm946e-s -march=armv5te
-CFLAGS := -MMD -MP -Wall -Wextra -Werror -fno-omit-frame-pointer -Os $(ASFLAGS) -fno-builtin -std=c11 -DVERSION=\"$(REVISION)\"
+CFLAGS := -MMD -MP -Wall -Wextra -Werror -fomit-frame-pointer -Os $(ASFLAGS) -fshort-wchar -fno-builtin -std=c11 -DVERSION=\"$(REVISION)\"
FLAGS := dir_out=$(abspath $(dir_out)) --no-print-directory
LDFLAGS := -nostdlib -Wl,-z,defs -lgcc -Wl,-Map,$(dir_build)/link.map
return bytearray()
-
if token_list[0] == "nop": # Nop. Expects 0 args.
return bytearray.fromhex("00")
elif token_list[0] == "rel": # Rel. Expects one argument. Possibly requires mapping.
return bytearray.fromhex("0D") + bytearray.fromhex(token_list[1])
elif token_list[0] == "clf":
return bytearray.fromhex("0E")
+ elif token_list[0] == "seek":
+ if s != 2:
+ syn_err("invalid number of arguments")
+
+ v = bytearray.fromhex(token_list[1])
+ v.reverse()
+ return bytearray.fromhex("0F") + v
elif token_list[0] == "jmpeq":
if s != 2:
syn_err("invalid number of arguments")
exit(1)
size = 0
-
offsets = []
+labels = []
with open(in_file, "r") as ins:
with open(out_file, "wb") as writ:
# One to figure out the opcode offsets, one
# to actually parse everything.
+ # FIXME - We need label support ASAP. The AGB and TWL patches I wrote make my head hurt.
+
for line in ins:
lines += 1
tokens = re.split("\s+", line.strip("\n")) # Split by whitespace.
- bytes = parse_op(tokens, None) # Parse.
+ try:
+ bytes = parse_op(tokens, None) # Parse.
+ except:
+ print("Error on line " + str(lines))
+ exit(1)
if bytes:
offsets += [size]
size += len(bytes)
offsets += [size+1] # So we can jump past the last instruction for 'exit' type behavior
+ lines = 0
ins.seek(0)
for line in ins:
lines += 1
tokens = re.split("\s+", line.strip("\n")) # Split by whitespace.
- bytes = parse_op(tokens, offsets) # Parse.
+ try:
+ bytes = parse_op(tokens, offsets) # Parse.
+ except:
+ print("Error on line " + str(lines))
+ exit(1)
if bytes:
bytecode += bytes
if (config.options[OPTION_RECONFIGURED]) {
fprintf(stderr, "Generating patch cache...\n");
generate_patch_cache();
- config.options[OPTION_RECONFIGURED] = 0;
- save_config();
}
fprintf(BOTTOM_SCREEN, "Patching firmware...\n");
return;
if (config.options[OPTION_REBOOT] && config.options[OPTION_RECONFIGURED]) {
- fprintf(stderr, "Saving FIRMs for reboot...");
+ fprintf(stderr, "Saving FIRM for reboot...\n");
if (!write_file(firm_loc, PATH_NATIVE_P, firm_size))
abort("Failed to save prepatched native\n");
abort("Failed to save prepatched agb\n");
}
+ if (config.options[OPTION_RECONFIGURED]) {
+ config.options[OPTION_RECONFIGURED] = 0;
+ save_config();
+ }
+
boot_firm();
}
#define OP_NOT 0x0C
#define OP_VER 0x0D
#define OP_CLF 0x0E
+#define OP_SEEK 0x0F
#define OP_JMPEQ 0x17
#define OP_JMPNE 0x27
eq = !eq;
code += 2;
break;
+ case OP_SEEK: // Jump to offset if greater than or equal
+ if (debug)
+ log("seek\n");
+ code++;
+ offset = code[3] + (code[2] * 0x100) + (code[1] * 0x10000) + (code[0] * 0x1000000);
+ if (offset > current_mode->size) {
+ // Went out of bounds. Error.
+ abort("seeked out of bounds\n");
+ }
+ else
+ code += 4;
+ break;
case OP_NEXT:
if (debug)
log("next\n");
{ OPTION_SVCS, "SVC Replacement", "Replaces ARM11 svc calls, including svcBackdoor. With 11.0 NATIVE_FIRM, you probably want this.", boolean_val, 0, 0 },
- { OPTION_REBOOT, "Reboot Hook", "Hooks firmlaunch to keep the CFW resident on o3DS and allow patching TWL/AGB firms as well.", boolean_val, 0, 0 },
+ { OPTION_REBOOT, "Reboot Hook", "Hooks firmlaunch to allow largemem games on o3DS (and allow patching TWL/AGB on all consoles)", boolean_val, 0, 0 },
{ OPTION_EMUNAND, "Use EmuNAND", "Redirects NAND write/read to the SD.", boolean_val, 0, 0 },
{ OPTION_EMUNAND_INDEX, " Index", "Which EmuNAND to use. Currently, 10 maximum (but this is arbitrary)", ranged_val, 0, 0x9 },
*pos_native = (uint32_t)mem;
memcpy(mem, L"sdmc:", 10);
mem += 10;
- for(size_t i=0; i < sizeof(PATH_NATIVE_P); i++, mem += 2)
+ for(size_t i=0; i < sizeof(PATH_NATIVE_P); i++, mem += 2) {
*mem = PATH_NATIVE_P[i];
+ *(mem + 1) = 0;
+ }
*pos_twl = (uint32_t)mem;
memcpy(mem, L"sdmc:", 10);
mem += 10;
- for(size_t i=0; i < sizeof(PATH_TWL_P); i++, mem += 2)
+ for(size_t i=0; i < sizeof(PATH_TWL_P); i++, mem += 2) {
*mem = PATH_TWL_P[i];
+ *(mem + 1) = 0;
+ }
*pos_agb = (uint32_t)mem;
memcpy(mem, L"sdmc:", 10);
mem += 10;
- for(size_t i=0; i < sizeof(PATH_AGB_P); i++, mem += 2)
+ for(size_t i=0; i < sizeof(PATH_AGB_P); i++, mem += 2) {
*mem = PATH_AGB_P[i];
+ *(mem + 1) = 0;
+ }
uint32_t *pos_rebc = (uint32_t*)memfind(off, size, "rebc", 4);
*pos_rebc = (uint32_t)mem;
fread(mem, 1, fsize(f), f);
fclose(f);
+
+ write_file((void*)0x1FF8000, "/test", 0x8000);
}
at[0] = ("0123456789abcdef")[i];
for (uint32_t j = 0; j < 0xf; j++) {
+ uint32_t svc = (i << 4) & j; // Actual svc index.
+
+ // Refuse to replace non-NULL services unless the user has it enabled.
+ // Also don't bother checking for non-null svc files (it's slow.)
+ if (svcTable[svc] && !config.options[OPTION_REPLACE_ALLOCATED_SVC])
+ continue;
+
// This is just hexdump. Nothing complicated.
at[1] = ("0123456789abcdef")[j];
if (!data)
continue; // No file for svc. Move on.
- uint32_t svc = (i << 4) & j;
-
- // Refuse to replace non-NULL services unless the user says to.
- if (svcTable[svc] && !config.options[OPTION_REPLACE_ALLOCATED_SVC]) {
- fclose(data);
- fprintf(stderr, "Svc: %x non-null, moving on\n", i);
- continue;
- }
-
// TODO - We can just fread directly to freeSpace with a little reordering.
uint32_t size = fsize(data);
fprintf(stderr, "Svc: %s, %d bytes\n", at, size);
- if (!freeSpace) {
- for (freeSpace = exceptionsPage; *freeSpace != 0xFFFFFFFF; freeSpace++)
- ;
- }
+ if (!freeSpace)
+ for (freeSpace = exceptionsPage; *freeSpace != 0xFFFFFFFF; freeSpace++);
fprintf(stderr, "Svc: Copy code to %x\n", (uint32_t)freeSpace);
fread(freeSpace, 1, size, data);
+
fclose(data);
svcTable[svc] = 0xFFFF0000 + ((uint8_t *)freeSpace - (uint8_t *)exceptionsPage);
- freeSpace += size; // We keep track of this because there's more than 7B free.
+ freeSpace += size;
fprintf(stderr, "Svc: entry set as %x\n", svcTable[svc]);
}