diff --git a/src/main/java/gamecubeloader/rel/RELHeader.java b/src/main/java/gamecubeloader/rel/RELHeader.java index 4b0ef01..e0f1dfd 100644 --- a/src/main/java/gamecubeloader/rel/RELHeader.java +++ b/src/main/java/gamecubeloader/rel/RELHeader.java @@ -148,7 +148,7 @@ public boolean IsValid(BinaryReader reader) { } public int Size() { - switch ((int) this.moduleId) { + switch ((int) this.moduleVersion) { case 0: case 1: return 0x40; @@ -161,4 +161,8 @@ public int Size() { return 0x4C; } } + + public int FullSize() { + return this.size() + (int) this.sectionCount * 8; + } } diff --git a/src/main/java/gamecubeloader/rel/RELProgramBuilder.java b/src/main/java/gamecubeloader/rel/RELProgramBuilder.java index f257553..d949d70 100644 --- a/src/main/java/gamecubeloader/rel/RELProgramBuilder.java +++ b/src/main/java/gamecubeloader/rel/RELProgramBuilder.java @@ -244,16 +244,17 @@ else if (fileName.endsWith(".rel") || fileName.endsWith(".szs") || fileName.ends var isText = (section.address & RELProgramBuilder.EXECUTABLE_SECTION) != 0; var blockName = String.format("%s_%s%d", relInfo.name, isText ? ".text" : ".data", isText ? textCount : dataCount); - MemoryBlockUtils.createInitializedBlock(this.program, false, blockName, this.addressSpace.getAddress(currentOutputAddress), - relInfo.reader.getByteProvider().getInputStream(section.address & ~1), section.size, "", null, true, true, isText, null, this.monitor); + // Update the address of the section with its virtual memory address. + var offs = section.address & ~1; + section.address = relBaseAddress + offs; + + MemoryBlockUtils.createInitializedBlock(this.program, false, blockName, this.addressSpace.getAddress(section.address), + relInfo.reader.getByteProvider().getInputStream(offs), section.size, "", null, true, true, isText, null, this.monitor); if (isText) textCount++; else dataCount++; - // Update the address of the section with it's virtual memory address. - section.address = currentOutputAddress; - - currentOutputAddress += section.size; + currentOutputAddress = section.address + section.size; // Ensure output address is aligned to 4 bytes if ((currentOutputAddress & 3) != 0) { @@ -268,7 +269,30 @@ else if (relInfo.header.bssSectionId == 0) { // Add bss section. if (relInfo.header.bssSize != 0 && relInfo.header.bssSectionId != 0) { - if (relInfo.header.moduleVersion < 2 || relInfo.header.bssSectionAlignment == 0) { + if (this.specifyModuleMemAddrs) { + // TODO: Check against addresses already containing memory sections. + var setValidAddress = false; + while (!setValidAddress) { + var selectedAddress = OptionDialog.showInputSingleLineDialog(null, "Specify BSS Address", "Specify the BSS memory address for Module " + + relInfo.name, Long.toHexString(currentOutputAddress)); + + if (selectedAddress == null) { + break; + } + + try { + var specifiedAddr = Long.parseUnsignedLong(selectedAddress, 16) & 0xFFFFFFFF; + if (specifiedAddr >= 0x80000000L && (specifiedAddr + relInfo.header.Size()) < 0x81800000L) { + currentOutputAddress = specifiedAddr; + setValidAddress = true; + } + } + catch (NumberFormatException e) { + continue; + } + } + } + else if (relInfo.header.moduleVersion < 2 || relInfo.header.bssSectionAlignment == 0) { currentOutputAddress = align(currentOutputAddress, 0x20); } else { @@ -311,7 +335,7 @@ else if (relInfo.header.bssSectionId == 0) { name = name.substring(0, name.lastIndexOf(".")); } - mapLoadedResult = SymbolLoader.TryLoadAssociatedMapFile(name, directory, this.program, this.monitor, relBaseAddress, (int)relInfo.header.sectionAlignment, + mapLoadedResult = SymbolLoader.TryLoadAssociatedMapFile(name, directory, this.program, this.monitor, relBaseAddress + relInfo.header.FullSize(), (int)relInfo.header.sectionAlignment, relInfo.header.bssSectionId != 0 ? relInfo.header.sections[relInfo.header.bssSectionId].address : 0); if (mapLoadedResult.loaded != false) { @@ -330,7 +354,7 @@ else if (relInfo.header.bssSectionId == 0) { if (selectedFile != null) { var reader = new FileReader(selectedFile); - var loader = new SymbolLoader(this.program, monitor, reader, relBaseAddress, 0, + var loader = new SymbolLoader(this.program, monitor, reader, relBaseAddress + relInfo.header.FullSize(), 0, relInfo.header.bssSectionId != 0 ? relInfo.header.sections[relInfo.header.bssSectionId].address : 0, this.binaryName, true); this.symbolInfoList.add(loader.ApplySymbols());