public void MakeFreeAreaList(byte[] data, uint RebuildAddress, Dictionary <uint, uint> useMap) { List <Address> knownList = U.MakeAllStructPointersList(false); List <DisassemblerTrumb.LDRPointer> ldrmap = DisassemblerTrumb.MakeLDRMap(Program.ROM.Data, 0x100); U.AppendAllASMStructPointersList(knownList , ldrmap , isPatchInstallOnly: true , isPatchPointerOnly: false , isPatchStructOnly: false , isUseOtherGraphics: true , isUseOAMSP: true ); MoveToFreeSapceForm.AppendSkillSystemsSanctuary(knownList); Dictionary <uint, bool> knownDic = MakeKnownListToDic(knownList); MakeFreeDataList(RecycleFreeAreaList, knownDic, FREEAREA_BLOCK_SIZE + 16 + 16, data, RebuildAddress, useMap); for (int i = 0; i < this.RecycleFreeAreaList.Count;) { Address p = this.RecycleFreeAreaList[i]; //頭としっぽはくれてやれ if (p.Length < 64) { this.RecycleFreeAreaList.RemoveAt(i); continue; } p.ResizeAddress(p.Addr + 16, p.Length - 16 - 16); i++; } }
static void RegistSymbolByNoDoll(List <Address> list, string basefilename, string symbol, uint baseaddr) { string basename = "@" + Path.GetFileName(basefilename); string[] lines = symbol.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); foreach (string line in lines) { //no$gba形式 //100109C MMBDrawInventoryObjs string[] sp = line.Split(' '); if (sp.Length != 2) { continue; } string name = sp[1]; uint addr = U.atoh(sp[0]); addr += baseaddr; if (name.Length <= 0 || addr <= 0x100) { continue; } addr = DisassemblerTrumb.ProgramAddrToPlain(addr); Address.AddCommentData(list, addr, name + basename); } }
static void ProcessSymbolElf(List <Address> list, string elffilename, uint baseaddr) { Elf elf = new Elf(elffilename, useHookMode: false); if (elf.ProgramBIN.Length < 0) { return; } string basename = "@" + Path.GetFileName(elffilename); foreach (Elf.Sym line in elf.SymList) { string name = line.name; uint addr = line.addr; addr += baseaddr; if (name.Length <= 0 || addr <= 0x100) { continue; } addr = DisassemblerTrumb.ProgramAddrToPlain(addr); Address.AddCommentData(list, addr, name + basename); } }
static void ProcessSymbolSymTxt(List <Address> list, string symtxt, uint baseaddr, string binfilename) { string basename = "@" + Path.GetFileName(binfilename); string[] lines = File.ReadAllLines(symtxt); foreach (string line in lines) { //EA形式 //MMBDrawInventoryObjs=$100109D string[] sp = line.Split('='); if (sp.Length < 2) { continue; } string name = sp[0]; uint addr = U.atoi0x(sp[1]); addr += baseaddr; if (name.Length <= 0 || addr <= 0x100) { continue; } addr = DisassemblerTrumb.ProgramAddrToPlain(addr); Address.AddCommentData(list, addr, name + basename); } }
//MAPファイルに定義されている定番のASMルーチン public bool IsFixedASM(uint num) { if (num <= 0) { return(false); } num = U.toOffset(num); uint plainAddr = DisassemblerTrumb.ProgramAddrToPlain(num); AsmMapFile map = GetAsmMapFile(); AsmMapFile.AsmMapSt a; if (!map.TryGetValue(U.toPointer(plainAddr), out a)) { return(false); } if (a.Length > 0) {//長さが判明しているということはおそらくASM関数ではない. return(false); } if (plainAddr >= Program.ROM.RomInfo.compress_image_borderline_address()) {//画像ボーダーよりも向こう側 return(false); } //おそらくASM関数だと思われる return(true); }
bool ParseLynSecondArgs(string a) { //次の引数へ a = U.skip(a, "\""); a = U.skip(a, "\""); string filename = U.cut(a, "\"", "\""); string fullbinname = Path.Combine(this.Dir, filename); if (!File.Exists(fullbinname)) { return(false); } Elf elf = new Elf(fullbinname, useHookMode: true); foreach (Elf.Sym sym in elf.SymList) { if (!U.isPointer(sym.addr)) { continue; } uint addr = U.toOffset(sym.addr); addr = DisassemblerTrumb.ProgramAddrToPlain(addr); Data data = new Data(addr, DataEnum.LYNHOOK); this.DataList.Add(data); } return(true); }
public List <DisassemblerTrumb.LDRPointer> GetLDRMapCache() { if (this.LDRMapCache.Count <= 0) {//まだデータがないらしいので仕方ない更新する. List <DisassemblerTrumb.LDRPointer> ldrmap; ldrmap = DisassemblerTrumb.MakeLDRMap(Program.ROM.Data, 0x100); this.LDRMapCache = ldrmap; return(ldrmap); } return(this.LDRMapCache); }
public string GetName(uint num) { num = DisassemblerTrumb.ProgramAddrToPlain(num); string errorMessage; string name = GetASMName(num, true, out errorMessage); if (errorMessage == "") { return name; } return ""; }
public string GetASMName(uint num, ASMTYPE asmtype, out string errorMessage) { if (num <= 0) { errorMessage = ""; return(""); //NULL } uint plainAddr = DisassemblerTrumb.ProgramAddrToPlain(num); if (asmtype == ASMTYPE.SWITCH) { if (plainAddr != num) {//逆に危険 +1してはいけない errorMessage = R._("危険なポインタです。\r\nここはswitch文のため、+1してはいけません。"); return(R._("危険なポインタ")); } } else if (asmtype == ASMTYPE.THUMB) { if (plainAddr == num) {//危険 +1 して、Thumbにするべき errorMessage = R._("危険なポインタです。\r\nThumb命令で呼び出すため、ポインタに1を足した値を書く必要があります。"); return(R._("危険なポインタ")); } } if (!U.isSafetyPointer(num)) { if (!U.is_RAMPointer(num)) { errorMessage = R._("無効なポインタです。\r\nこの設定は危険です。"); return(R._("無効なポインタ")); } } errorMessage = ""; string comment; if (Program.CommentCache.TryGetValue(U.toOffset(plainAddr), out comment)) {//ユーザー定義のコメントがある return(comment); } AsmMapFile map = GetAsmMapFile(); AsmMapFile.AsmMapSt a; if (!map.TryGetValue(U.toPointer(plainAddr), out a)) { return(""); } return(a.Name); }
static void ProcessSymbol(List <Address> list, string basefilename) { foreach (Address a in list) { if (a.DataType != Address.DataTypeEnum.Comment) { continue; } uint addr = a.Addr; addr = DisassemblerTrumb.ProgramAddrToPlain(addr); Program.CommentCache.Update(addr, a.Info); } }
void CheckLDRCache() { if (LDRCache != null) { return; } uint limit = Program.ROM.RomInfo.compress_image_borderline_address(); if (this.WriteOffset < limit) { limit = this.WriteOffset; } this.LDRCache = DisassemblerTrumb.MakeLDRMap(this.WriteROMData32MB, 0x100, limit, true); }
public string GetName(uint num) { if (num >= 0x08000000 && num <= 0x08000000) {//もし+1された奇数アドレスだったら、ASMとして元に戻します. num = DisassemblerTrumb.ProgramAddrToPlain(num); } string errorMessage; string name = GetASMName(num, ASMTYPE.NONE, out errorMessage); if (errorMessage == "") { return(name); } return(""); }
public static void AddFunction(List <Address> list, uint pointer, string strname) { uint addr = Program.ROM.u32(pointer); if (!U.isSafetyPointer(addr)) { return; } addr = DisassemblerTrumb.ProgramAddrToPlain(addr); list.Add(new Address(addr , 0 , pointer , strname , FEBuilderGBA.Address.DataTypeEnum.ASM)); }
public List <DisassemblerTrumb.LDRPointer> GetLDRMapCache() { if (this.LDRMapCache.Count <= 0) {//まだデータがないらしいので仕方ない更新する. List <DisassemblerTrumb.LDRPointer> ldrmap; ldrmap = DisassemblerTrumb.MakeLDRMap(Program.ROM.Data, 0x100); this.LDRMapCache = ldrmap; return(ldrmap); } #if DEBUG //一応、キャッシュと同じかどうかのテストをしておく. List <DisassemblerTrumb.LDRPointer> ldrmaplow = DisassemblerTrumb.MakeLDRMap(Program.ROM.Data, 0x100); Debug.Assert(this.LDRMapCache.Count == ldrmaplow.Count); #endif return(this.LDRMapCache); }
static uint CalcLengthAndCheck(uint addr, string name, ref List <Address> list, ref Dictionary <uint, bool> alreadyMatch) { uint start = addr; uint length = (uint)(Program.ROM.Data.Length - 4); while (addr < length) { uint p = Program.ROM.u32(addr); if ((p & (uint)0x88FFFF00) == 0x80000000) {//OAM term 0x8X0000XX // 0x800000XX or 0x810000XX or 0x820000XX or 0x840000XX addr += 4; break; } if ((p & (uint)0x70000000) > 0) { //OAM term //以下のように、先頭7が入っているものがある. p = (p & 0x0FFFFFFF); //78 67 EA 3B } if (!U.isSafetyPointer(p)) { //理解不能の命令があったのでOAMではない return(U.NOT_FOUND); } uint oam12Addr = U.toOffset(p); //多分奇数の場合 整数に直す??? まったくわからないがそう考えると都合がいい. oam12Addr = DisassemblerTrumb.ProgramAddrToPlain(oam12Addr); if (!alreadyMatch.ContainsKey(oam12Addr)) {//まだ知らない uint oam12length = CalcLengthAndCheckOAM12(oam12Addr); if (oam12length == U.NOT_FOUND) { return(U.NOT_FOUND); } FEBuilderGBA.Address.AddAddress(list, oam12Addr, oam12length, addr, name + "_OAM", FEBuilderGBA.Address.DataTypeEnum.OAMSP12); alreadyMatch.Add(oam12Addr, true); } addr += 4; } uint ret_length = addr - start; return(ret_length); }
string MakePatch() { if (!File.Exists(this.ComplieBinFilename)) { R.ShowStopError("コンパイルした結果のファイルがないので、パッチを作成できません。"); return(""); } uint addr = U.toOffset((uint)this.Address.Value); if (!U.CheckZeroAddressWrite(addr)) { return(""); } if (this.Method.SelectedIndex == 0) { return(""); } string patch = ""; patch += "NAME=<<PATCH NAME>>\r\n"; patch += "\r\n"; patch += "TYPE=BIN\r\n"; if (this.Method.SelectedIndex == 1) { byte[] bin = File.ReadAllBytes(this.ComplieBinFilename); patch += "PATCHED_IF:" + U.To0xHexString(addr) + "=" + U.HexDumpLiner0x(bin, 0, 32) + "\r\n"; patch += "BIN:" + U.To0xHexString(addr) + "=" + Path.GetFileName(this.ComplieBinFilename); } else { uint freeaddr = U.toOffset((uint)this.FREEAREA.Value); uint usereg = GetSaftyRegister(); byte[] jumpCode = DisassemblerTrumb.MakeInjectJump(addr, freeaddr, usereg); patch += "PATCHED_IF:" + U.To0xHexString(addr) + "=" + U.HexDumpLiner0x(jumpCode) + "\r\n"; patch += "BIN:$FREEAREA=" + Path.GetFileName(this.ComplieBinFilename); patch += "\r\nJUMP:" + U.To0xHexString(addr) + ":r" + usereg + "=" + Path.GetFileName(this.ComplieBinFilename); } return(patch); }
public static bool IsASMCode(uint asm) { if (U.IsValueOdd(asm)) { asm = asm - 1; } uint a = U.toOffset(asm); DisassemblerTrumb.VM vm = new DisassemblerTrumb.VM(); DisassemblerTrumb dis = new DisassemblerTrumb(); DisassemblerTrumb.Code code = dis.Disassembler(Program.ROM.Data, a, 0, vm); if (code.Type == DisassemblerTrumb.CodeType.Unknown) { return(false); } return(true); }
void LoadTargetROM(string filename) { ROM OtherROM = new ROM(); string version; if (OtherROM.Load(filename, out version)) { this.OtherROMASMMap = new AsmMapFile(OtherROM); } this.OtherROMFilename = filename; this.OtherROMData = File.ReadAllBytes(filename); this.OtherLoadName.Text = R._("別ゲームROM:{0}", Path.GetFileNameWithoutExtension(this.OtherROMFilename)); //自分のLDRMAPをここで作る. 相手のROMに探索に利用する this.LDRMAPs = Program.AsmMapFileAsmCache.GetLDRMapCache(); //相手のROMのLDRMAPを作る. this.OtherLDRMAPs = DisassemblerTrumb.MakeLDRMap(this.OtherROMData, 0x100, 0); }
void LoadSymbolNoDollGBASym(string symtxt) { string[] lines = File.ReadAllLines(symtxt); foreach (string line in lines) { //no$gba形式 //800109C MMBDrawInventoryObjs string[] sp = line.Split(' '); if (sp.Length < 2) { continue; } string name = sp[1]; uint addr = U.atoh(sp[0]); if (addr < 0x08000000 || addr > 0x0F000000) { continue; } if (name.Length <= 0) { continue; } //型指定は無視 if (name == ".thumb") { continue; } else if (name == ".arm") { continue; } else if (name.IndexOf(":") == 0) { continue; } addr = DisassemblerTrumb.ProgramAddrToPlain(addr); addr = U.toOffset(addr); this.Cache[addr] = name; } }
private void ParamLabel1_Click(object sender, EventArgs e) { uint addr = (uint)ParamSrc1.Value; addr = U.toOffset(addr); addr = DisassemblerTrumb.ProgramAddrToPlain(addr); if (!U.isSafetyOffset(addr)) { return; } HideFloatingControlpanel(); if (Navigation != null) { NavigationEventArgs arg = new NavigationEventArgs(); arg.IsNewTab = true; arg.Address = addr; Navigation(this, arg); } }
List <Address> SearchAllLZ77Data(InputFormRef.AutoPleaseWait wait) { //念のためパッチのCheckIFをスキャンをやり直す. PatchForm.ClearCheckIF(); wait.DoEvents("GrepAllStructPointers"); List <DisassemblerTrumb.LDRPointer> ldrmap = DisassemblerTrumb.MakeLDRMap(Program.ROM.Data, 0x100, Program.ROM.RomInfo.compress_image_borderline_address, true); List <Address> structList = U.MakeAllStructPointersList(false); U.AppendAllASMStructPointersList(structList , ldrmap , isPatchInstallOnly: true , isPatchPointerOnly: false , isPatchStructOnly: false , isUseOtherGraphics: false , isUseOAMSP: false ); AsmMapFile.InvalidateUNUNSED(structList); Dictionary <uint, bool> dupCheck = new Dictionary <uint, bool>(); List <Address> ret = new List <Address>(); foreach (Address a in structList) { if (!Address.IsLZ77(a.DataType)) { continue; } if (dupCheck.ContainsKey(a.Addr)) { continue; } ret.Add(a); dupCheck[a.Addr] = true; } ret.Sort((aa, bb) => { return((int)(aa.Addr - bb.Addr)); }); return(ret); }
private void ParamLabel_Clicked(object sender, EventArgs e) { EventScript.OneCode code; int selectID; int argindex; if (!Get_Select_ParamSrc_Object(sender, out code, out selectID, out argindex)) { return; } NumericUpDown src_object = ScriptEditSetTables[selectID].ParamSrc; EventScript.Arg arg = code.Script.Args[argindex]; uint value = EventScriptForm.GetValueOneScriptEditSetTables(ScriptEditSetTables[selectID], arg); if (arg.Type == EventScript.ArgType.POINTER_TEXT) { CStringForm f = (CStringForm)InputFormRef.JumpForm <CStringForm>(); f.Init(src_object); } else if (arg.Type == EventScript.ArgType.POINTER_PROCS) { ProcsScriptForm f = (ProcsScriptForm)InputFormRef.JumpForm <ProcsScriptForm>(U.NOT_FOUND); f.JumpTo(value); } else if (arg.Type == EventScript.ArgType.POINTER_ASM) { DisASMForm f = (DisASMForm)InputFormRef.JumpForm <DisASMForm>(U.NOT_FOUND); f.JumpTo(DisassemblerTrumb.ProgramAddrToPlain(value)); } else if (arg.Type == EventScript.ArgType.POINTER_AIUNIT) { AIUnitsForm f = (AIUnitsForm)InputFormRef.JumpFormLow <AIUnitsForm>(); f.JumpTo(value); f.ShowDialog(); U.SetActiveControl(src_object); U.ForceUpdate(src_object, f.GetBaseAddress()); } }
List <OtherROMLDRFuncSt> MakeOtherROMLDRFuncList(uint search_address) { List <OtherROMLDRFuncSt> list = new List <OtherROMLDRFuncSt>(); for (int i = 0; i < this.LDRMAPs.Count; i++) { DisassemblerTrumb.LDRPointer ldr = this.LDRMAPs[i]; if (ldr.ldr_data != search_address) { continue; } if (ldr.ldr_address <= SEARCH_PUSH_MAX) { continue; } DisassemblerTrumb Disassembler = new DisassemblerTrumb(); DisassemblerTrumb.VM vm = new DisassemblerTrumb.VM(); uint limit = ldr.ldr_address - SEARCH_PUSH_MAX; for (uint n = ldr.ldr_address - 2; n >= limit; n -= 2) { DisassemblerTrumb.Code code = Disassembler.Disassembler(Program.ROM.Data, n, (uint)Program.ROM.Data.Length, vm); if (code.Type == DisassemblerTrumb.CodeType.PUSH) { OtherROMLDRFuncSt pp = new OtherROMLDRFuncSt(); pp.FuncAddr = U.toPointer(n); pp.BackSize = ldr.ldr_address - n; list.Add(pp); } else if (code.Type == DisassemblerTrumb.CodeType.BXJMP) { break; } } } return(list); }
public static void MakeAllDataLength(List <Address> list, uint pointer, bool isDirectAddress) { InputFormRef InputFormRef = Init(null); if (isDirectAddress) { InputFormRef.ReInit(pointer); } else { InputFormRef.ReInitPointer(pointer); } FEBuilderGBA.Address.AddAddressButDoNotLengthPuls1(list , InputFormRef , "MenuDefinition" , new uint[] { 8, 12, 16, 20, 24, 28, 32 } , FEBuilderGBA.Address.DataTypeEnum.InputFormRef_MIX ); uint p = InputFormRef.BaseAddress; for (int i = 0; i < InputFormRef.DataCount; i++, p += InputFormRef.BlockSize) { string name = "MenuDef" + i + "_"; uint paddr; paddr = Program.ROM.p32(8 + p); if (!U.isSafetyOffset(paddr)) { continue; } MenuCommandForm.MakeAllDataLengthP(list, 8 + p, name); paddr = Program.ROM.p32(12 + p); FEBuilderGBA.Address.AddAddress(list, DisassemblerTrumb.ProgramAddrToPlain(paddr) , 0 //プログラムなので長さ不明 , p + 12 , name + "_HandleBPress" , FEBuilderGBA.Address.DataTypeEnum.ASM); paddr = Program.ROM.p32(16 + p); FEBuilderGBA.Address.AddAddress(list, DisassemblerTrumb.ProgramAddrToPlain(paddr) , 0 //プログラムなので長さ不明 , p + 16 , name + "_HandleRPress" , FEBuilderGBA.Address.DataTypeEnum.ASM); paddr = Program.ROM.p32(20 + p); FEBuilderGBA.Address.AddAddress(list, DisassemblerTrumb.ProgramAddrToPlain(paddr) , 0 //プログラムなので長さ不明 , p + 20 , name + "_Construction" , FEBuilderGBA.Address.DataTypeEnum.ASM); paddr = Program.ROM.p32(24 + p); FEBuilderGBA.Address.AddAddress(list, DisassemblerTrumb.ProgramAddrToPlain(paddr) , 0 //プログラムなので長さ不明 , p + 24 , name + "_Destruction" , FEBuilderGBA.Address.DataTypeEnum.ASM); paddr = Program.ROM.p32(28 + p); FEBuilderGBA.Address.AddAddress(list, DisassemblerTrumb.ProgramAddrToPlain(paddr) , 0 //プログラムなので長さ不明 , p + 28 , name + "_UnkP28" , FEBuilderGBA.Address.DataTypeEnum.ASM); paddr = Program.ROM.p32(32 + p); FEBuilderGBA.Address.AddAddress(list, DisassemblerTrumb.ProgramAddrToPlain(paddr) , 0 //プログラムなので長さ不明 , p + 32 , name + "_Unk32" , FEBuilderGBA.Address.DataTypeEnum.ASM); } }
public static void RunAllMakeMAPFileButton(Form self) { if (InputFormRef.IsPleaseWaitDialog(self)) {//2重割り込み禁止 return; } string title = R._("保存するファイル名を選択してください"); string filter = R._("MAP|*.map|TEXT|*.txt|All files|*"); SaveFileDialog save = new SaveFileDialog(); save.Title = title; save.Filter = filter; save.ShowDialog(); if (save.FileNames.Length <= 0 || !U.CanWriteFileRetry(save.FileNames[0])) { return; } using (InputFormRef.AutoPleaseWait wait = new InputFormRef.AutoPleaseWait(self)) using (StreamWriter writer = new StreamWriter(save.FileNames[0])) { writer.WriteLine(" Start Length Name Class"); wait.DoEvents("GrepAllStructPointers"); AsmMapFile asmMapFile = new AsmMapFile(Program.ROM); DisassemblerTrumb Disassembler = new DisassemblerTrumb(asmMapFile); List <DisassemblerTrumb.LDRPointer> ldrmap = Program.AsmMapFileAsmCache.GetLDRMapCache(); List <Address> structlist = U.MakeAllStructPointersList(false); //既存の構造体 U.AppendAllASMStructPointersList(structlist , ldrmap , isPatchInstallOnly: false , isPatchPointerOnly: false , isPatchStructOnly: false , isUseOtherGraphics: true , isUseOAMSP: true ); AsmMapFile.InvalidateUNUNSED(structlist); MakeFreeData(structlist); asmMapFile.AppendMAP(structlist); //コメントデータ Program.CommentCache.MakeAddressList(structlist); asmMapFile.AppendMAP(structlist); string line; Dictionary <uint, AsmMapFile.AsmMapSt> asmmap = asmMapFile.GetAsmMap(); foreach (var pair in asmmap) { if (pair.Key == 0x0 || pair.Key == U.NOT_FOUND) { continue; } if (pair.Key >= 0x08000000 && pair.Key <= 0x08000200) { continue; } //長いと不便なので、名前以外不要. string name = pair.Value.Name; name = U.term(name, "\t"); if (pair.Value.Length > 0) { line = string.Format(" 0000:{0} 0{1}H {2} DATA", U.ToHexString(pair.Key), pair.Value.Length.ToString("X08"), name); } else { line = string.Format(" 0000:{0} {1}", U.ToHexString(pair.Key), name); } writer.WriteLine(line); } } //エクスプローラで選択しよう U.SelectFileByExplorer(save.FileNames[0]); }
public static void MakeAllDisASMButton(Form self, string store_filename, bool notifyUpdateMessage) { uint addr = 0x100; using (InputFormRef.AutoPleaseWait wait = new InputFormRef.AutoPleaseWait(self)) using (StreamWriter writer = new StreamWriter(store_filename)) { writer.WriteLine("//FEBuilderGBA " + R._("逆アセンブラ")); if (notifyUpdateMessage) { writer.WriteLine("//" + DateTime.Now.ToString("yyyyMMdd") + " " + R._("ソースコードを更新する場合は、このファイル消すか、0バイトの空ファイルにしてください。")); } wait.DoEvents("GrepAllStructPointers"); AsmMapFile asmMapFile = new AsmMapFile(Program.ROM); DisassemblerTrumb Disassembler = new DisassemblerTrumb(asmMapFile); List <DisassemblerTrumb.LDRPointer> ldrmap = Program.AsmMapFileAsmCache.GetLDRMapCache(); List <Address> structlist = U.MakeAllStructPointersList(false); //既存の構造体 U.AppendAllASMStructPointersList(structlist , ldrmap , isPatchInstallOnly: false , isPatchPointerOnly: false , isPatchStructOnly: false , isUseOtherGraphics: true , isUseOAMSP: true ); AsmMapFile.InvalidateUNUNSED(structlist); UnpackBINByCode(structlist); MakeFreeData(structlist); asmMapFile.AppendMAP(structlist); //コメントデータ Program.CommentCache.MakeAddressList(structlist); asmMapFile.AppendMAP(structlist); {//設計をミスった。 綺麗なリストを作りたいので、もう一回読みこみなおそう... AsmMapFile asmMapFile2 = new AsmMapFile(Program.ROM); asmMapFile2.MakeAllDataLength(structlist); AsmMapFile.InvalidateUNUNSED(structlist); } uint limit = (uint)Program.ROM.Data.Length; int jisage = 0; //字下げする数 string jisageSpaceData = ""; //字下げに利用するマージンデータ List <uint> jmplabel = new List <uint>(); //ジャンプラベル 字下げに使う Dictionary <uint, uint> ldrtable = new Dictionary <uint, uint>(); //LDR参照データがある位置を記録します. コードの末尾などにあります. 数が多くなるのでマップする. AsmMapFile.MakeSwitchDataList(ldrtable, 0x100, 0); wait.DoEvents(R._("データを準備中...")); //探索を早くするために、データをアドレスへマッピングする. メモリを大量に使うが早い. Dictionary <uint, Address> lookupStructMap = MakeAllStructMapping(structlist); structlist = null; uint nextDoEvents = 0; bool prevPointer = false; //ひとつ前がポインタだった Address matchAddress; DisassemblerTrumb.VM vm = new DisassemblerTrumb.VM(); while (addr < limit) { if (addr > nextDoEvents) {//毎回更新するのは無駄なのである程度の間隔で更新して以降 wait.DoEvents(String.Format("{0}/{1}", addr, limit)); nextDoEvents = addr + 0xfff; } if (lookupStructMap.TryGetValue(addr, out matchAddress)) { if (matchAddress.Pointer <= addr && addr < matchAddress.Pointer + 4) {//ポインタ? writer.WriteLine(U.toPointer(addr).ToString("X08") + " " + U.MakeOPData(addr, 4) + " //POINTER " + matchAddress.Info); addr += 4; } else {//データ uint newaddr = U.Padding2(matchAddress.Addr + matchAddress.Length); uint length = (newaddr - addr); Debug.Assert(length < 10000000); writer.WriteLine("{0} - {1} //{2} ({3}bytes)", U.toPointer(addr).ToString("X08"), U.toPointer(newaddr).ToString("X08"), matchAddress.Info, length); addr = U.Padding4(newaddr); } prevPointer = true; continue; } //LDR参照とスイッチ参照 if (ldrtable.ContainsKey(addr)) {//LDR参照のポインタデータが入っている uint ldr = ldrtable[addr]; if (ldr == U.NOT_FOUND) {//switch case writer.WriteLine(U.toPointer(addr).ToString("X08") + " " + U.MakeOPData(addr, 4) + " //SWITCH CASE"); } else { writer.WriteLine(U.toPointer(addr).ToString("X08") + " " + U.MakeOPData(addr, 4) + " //LDRDATA"); } addr += 4; prevPointer = true; continue; } if (prevPointer) {//ひとつ前がポインタの場合、野生のポインタをチェック uint data = Program.ROM.u32(addr); if (U.isPointer(data)) { if (lookupStructMap.TryGetValue(U.toOffset(data), out matchAddress)) { writer.WriteLine(U.toPointer(addr).ToString("X08") + " " + U.MakeOPData(addr, 4) + " //Wild POINTER " + U.ToHexString8(data) + " " + matchAddress.Info); addr += 4; continue; } } } //ひとつ前はポインタではない. prevPointer = false; //Disassembler DisassemblerTrumb.Code code = Disassembler.Disassembler(Program.ROM.Data, addr, limit, vm); if (code.Type == DisassemblerTrumb.CodeType.BXJMP) {//関数の出口なので字下げをすべて取り消す. jisage = 0; jmplabel.Clear(); jisageSpaceData = ""; } else { for (int i = 0; i < jmplabel.Count;) { if (addr >= jmplabel[i]) { jmplabel.RemoveAt(i); jisage--; jisageSpaceData = U.MakeJisageSpace(jisage); i = 0; continue; } i++; } } writer.WriteLine(jisageSpaceData + U.toPointer(addr).ToString("X08") + " " + U.MakeOPData(addr, code.GetLength()) + " " + code.ASM.ToLower() + code.Comment); if (code.Type == DisassemblerTrumb.CodeType.CONDJMP //条件式なので字下げ開始 ) { uint jumplabel = U.toOffset(code.Data); if (addr < jumplabel) {//とび先が自分より後ろであること. 前方はすでに過ぎてしまったので字下げできない. jisage++; jmplabel.Add(jumplabel); jisageSpaceData = U.MakeJisageSpace(jisage); } } else if (code.Type == DisassemblerTrumb.CodeType.BXJMP) {//関数の終わりなので空行を入れる. writer.WriteLine(""); } if (code.Type == DisassemblerTrumb.CodeType.LDR) {//LDR参照位置を記録していく. ldrtable[code.Data2] = addr; } addr += code.GetLength(); } } if (self != null) { //エクスプローラで選択しよう U.SelectFileByExplorer(store_filename); } }
public static void AllMakeNoDollSymFile(Form self, string symfilename, InputFormRef.AutoPleaseWait wait) { Encoding encoding = U.GetSystemDefault(); using (StreamWriter writer = new StreamWriter(symfilename, false, encoding)) { wait.DoEvents("GrepAllStructPointers"); AsmMapFile asmMapFile = new AsmMapFile(Program.ROM); DisassemblerTrumb Disassembler = new DisassemblerTrumb(asmMapFile); List <DisassemblerTrumb.LDRPointer> ldrmap = Program.AsmMapFileAsmCache.GetLDRMapCache(); List <Address> structlist = new List <Address>(50000); //昔のno$gbaは32546lines以上の symを読みこむと落ちるので手加減する. U.AppendAllASMStructPointersList(structlist , ldrmap , isPatchInstallOnly: true , isPatchPointerOnly: false , isPatchStructOnly: false , isUseOtherGraphics: false , isUseOAMSP: false ); AsmMapFile.InvalidateUNUNSED(structlist); asmMapFile.AppendMAP(structlist); //コメントデータ Program.CommentCache.MakeAddressList(structlist); asmMapFile.AppendMAP(structlist); Dictionary <uint, AsmMapFile.AsmMapSt> asmmap = asmMapFile.GetAsmMap(); foreach (var pair in asmmap) { if (pair.Key == 0x0 || pair.Key == U.NOT_FOUND) { continue; } if (pair.Key >= 0x08000000 && pair.Key <= 0x08000200) { continue; } if (pair.Value.IsPointer) {//ポインタデータは不要 continue; } //長いと不便なので、名前以外不要. string name = pair.Value.Name; name = ConvertNoDollGBASymName(name); if (name == "") {//名前が空 continue; } if (pair.Value.TypeName == "ARM") { string line = string.Format("{0} .arm", U.ToHexString(pair.Key), ".arm"); writer.WriteLine(line); } else if (pair.Value.TypeName == "ASM" || U.toOffset(pair.Key) < Program.ROM.RomInfo.compress_image_borderline_address) { string line = string.Format("{0} .thumb", U.ToHexString(pair.Key)); writer.WriteLine(line); } { string line = string.Format("{0} {1}", U.ToHexString(pair.Key), name); writer.WriteLine(line); } } } }
AsmMapFile MakeFullLow() { AsmMapFile map = new AsmMapFile(this.BaseSymbol); if (IsStopFlag) { return(map); } //LDRマップのクリア this.LDRMapCache = new List <DisassemblerTrumb.LDRPointer>(0x1000); this.FELintCache = new Dictionary <uint, List <FELint.ErrorSt> >(); List <DisassemblerTrumb.LDRPointer> ldrmap; try { ldrmap = DisassemblerTrumb.MakeLDRMap(Program.ROM.Data, 0x100); this.LDRMapCache = ldrmap; if (IsStopFlag) { return(map); } } catch (Exception e) { Log.Error(e.ToString()); Debug.Assert(false); return(map); } try { MakeHardCodeWarning(); //ハードコーディングされているデータの警告 if (IsStopFlag) { return(map); } } catch (Exception e) { Log.Error(e.ToString()); Debug.Assert(false); } try { ScanFELintByThread(ldrmap); if (IsStopFlag) { return(map); } } catch (Exception e) { Log.Error(e.ToString()); Debug.Assert(false); return(map); } Dictionary <uint, bool> knownDic = new Dictionary <uint, bool>(); List <Address> structlist; try { structlist = U.MakeAllStructPointersList(false); //既存の構造体 if (IsStopFlag) { return(map); } } catch (Exception e) { Log.Error(e.ToString()); Debug.Assert(false); return(map); } try { PatchForm.MakePatchStructDataList(structlist, true, true, false); //パッチが知っている領域. if (IsStopFlag) { return(map); } } catch (Exception e) { Log.Error(e.ToString()); Debug.Assert(false); } try { //参照の逆追跡 this.VarsIDArray = U.MakeVarsIDArray(map); if (IsStopFlag) { return(map); } } catch (Exception e) { Log.Error(e.ToString()); Debug.Assert(false); } try { GraphicsToolForm.MakeLZ77DataList(structlist); //lz77で圧縮されたもの(主に画像) if (IsStopFlag) { return(map); } } catch (Exception e) { Log.Error(e.ToString()); Debug.Assert(false); } try { ProcsScriptForm.MakeAllDataLength(structlist, ldrmap); if (IsStopFlag) { return(map); } } catch (Exception e) { Log.Error(e.ToString()); Debug.Assert(false); } try { OAMSPForm.MakeAllDataLength(structlist, structlist, ldrmap); if (IsStopFlag) { return(map); } } catch (Exception e) { Log.Error(e.ToString()); Debug.Assert(false); } try { knownDic = AsmMapFile.MakeKnownListToDic(structlist); AsmMapFile.MakeFreeDataList(structlist, knownDic, 0x100, 0x00, 16); //フリー領域 if (IsStopFlag) { return(map); } } catch (Exception e) { Log.Error(e.ToString()); Debug.Assert(false); } try { AsmMapFile.MakeFreeDataList(structlist, knownDic, 0x100, 0xFF, 16); //フリー領域 if (IsStopFlag) { return(map); } } catch (Exception e) { Log.Error(e.ToString()); Debug.Assert(false); } try { map.AppendMAP(structlist); if (IsStopFlag) { return(map); } } catch (Exception e) { Log.Error(e.ToString()); Debug.Assert(false); } Dictionary <uint, uint> ldrtable = new Dictionary <uint, uint>(); //LDR参照データがある位置を記録します. コードの末尾などにあります. 数が多くなるのでマップする. try { AsmMapFile.MakeSwitchDataList(ldrtable, 0x100, 0); if (IsStopFlag) { return(map); } } catch (Exception e) { Log.Error(e.ToString()); Debug.Assert(false); } try { map.AppendMAP(ldrtable); if (IsStopFlag) { return(map); } } catch (Exception e) { Log.Error(e.ToString()); Debug.Assert(false); } //近場リスト生成. map.MakeNearSearchSortedList(); return(map); }
AsmMapFile MakeFullLow() { AsmMapFile map = MakeInstant(); if (IsStopFlag) { return(map); } //LDRマップのクリア this.LDRMapCache = new List <DisassemblerTrumb.LDRPointer>(); this.FELintCache = new Dictionary <uint, List <FELint.ErrorSt> >(); List <DisassemblerTrumb.LDRPointer> ldrmap; #if !DEBUG try { #endif ldrmap = DisassemblerTrumb.MakeLDRMap(Program.ROM.Data, 0x100); this.LDRMapCache = ldrmap; if (IsStopFlag) { return(map); } #if !DEBUG } catch (Exception e) { Log.Error(e.ToString()); return(map); } #endif #if !DEBUG try { #endif MakeHardCodeWarning(); //ハードコーディングされているデータの警告 if (IsStopFlag) { return(map); } #if !DEBUG } catch (Exception e) { Log.Error(e.ToString()); } #endif #if !DEBUG try { #endif ScanFELintByThread(ldrmap); if (IsStopFlag) { return(map); } #if !DEBUG } catch (Exception e) { Log.Error(e.ToString()); return(map); } #endif List <Address> structlist; #if !DEBUG try { #endif structlist = U.MakeAllStructPointersList(false); //既存の構造体 if (IsStopFlag) { return(map); } #if !DEBUG } catch (Exception e) { Log.Error(e.ToString()); return(map); } #endif #if !DEBUG try { #endif PatchForm.MakePatchStructDataList(structlist, true, true, false); //パッチが知っている領域. if (IsStopFlag) { return(map); } #if !DEBUG } catch (Exception e) { Log.Error(e.ToString()); } #endif #if !DEBUG try { #endif map.MakeTextIDArray(); //全テキストIDの検出 if (IsStopFlag) { return(map); } #if !DEBUG } catch (Exception e) { Log.Error(e.ToString()); } #endif #if !DEBUG try { #endif GraphicsToolForm.MakeLZ77DataList(structlist); //lz77で圧縮されたもの(主に画像) if (IsStopFlag) { return(map); } #if !DEBUG } catch (Exception e) { Log.Error(e.ToString()); } #endif #if !DEBUG try { #endif ProcsScriptForm.MakeAllDataLength(structlist, ldrmap); if (IsStopFlag) { return(map); } #if !DEBUG } catch (Exception e) { Log.Error(e.ToString()); } #endif #if !DEBUG try { #endif OAMSPForm.MakeAllDataLength(structlist, structlist, ldrmap); if (IsStopFlag) { return(map); } #if !DEBUG } catch (Exception e) { Log.Error(e.ToString()); } #endif #if !DEBUG try { #endif AsmMapFile.MakeFreeDataList(structlist, 0x100, 0x00, 16); //フリー領域 if (IsStopFlag) { return(map); } #if !DEBUG } catch (Exception e) { Log.Error(e.ToString()); } #endif #if !DEBUG try { #endif AsmMapFile.MakeFreeDataList(structlist, 0x100, 0xFF, 16); //フリー領域 if (IsStopFlag) { return(map); } #if !DEBUG } catch (Exception e) { Log.Error(e.ToString()); } #endif #if !DEBUG try { #endif map.AppendMAP(structlist); if (IsStopFlag) { return(map); } #if !DEBUG } catch (Exception e) { Log.Error(e.ToString()); } #endif Dictionary <uint, uint> ldrtable = new Dictionary <uint, uint>(); //LDR参照データがある位置を記録します. コードの末尾などにあります. 数が多くなるのでマップする. #if !DEBUG try { #endif AsmMapFile.MakeSwitchDataList(ldrtable, 0x100, 0); if (IsStopFlag) { return(map); } #if !DEBUG } catch (Exception e) { Log.Error(e.ToString()); } #endif #if !DEBUG try { #endif map.AppendMAP(ldrtable); if (IsStopFlag) { return(map); } #if !DEBUG } catch (Exception e) { Log.Error(e.ToString()); } #endif //近場リスト生成. map.MakeNearSearchSortedList(); return(map); }
private void RunButton_Click(object sender, EventArgs e) { this.ComplieBinFilename = ""; string fullpath = this.SRCFilename.Text; if (!File.Exists(fullpath)) { R.ShowStopError(("ファイルがありません。\r\nファイル名:{0}"), fullpath); return; } if (IsMakeLynEventMode() && this.Method.SelectedIndex != 0) { R.ShowStopError("lyn.eventを作成する時は、ROMに書き込むことはできません。"); return; } string result; string symbol; bool r = MainFormUtil.Compile(fullpath, out result, out symbol, GetCompileType()); if (r == false) { R.ShowStopError("エラーが返されました。\r\n{0}", result); return; } this.ComplieBinFilename = result; if (this.Method.SelectedIndex == 0) { SymbolUtil.ProcessSymbolByComment(fullpath, symbol, GetPlanOfDebugSymbol(), 0); //ROMに書き込まない場合、成果物を選択しよう. U.SelectFileByExplorer(result, false); return; } uint addr = U.toOffset((uint)this.Address.Value); if (!U.CheckZeroAddressWrite(addr)) { return; } if (!U.isSafetyOffset(addr)) { if (addr != Program.ROM.Data.Length) { R.ShowStopError("無効なポインタです。\r\nこの設定は危険です。"); return; } } if (!File.Exists(result)) { R.ShowStopError("ファイルがありません。\r\nファイル名:{0}", result); return; } byte[] bin = File.ReadAllBytes(result); if (bin.Length <= 0) { R.ShowStopError("ファイルがゼロバイトです。\r\nファイル名:{0}", result); return; } if (bin.Length > 1024 * 10) { DialogResult dr = R.ShowNoYes("このファイルは {0}バイトも書き換えますが、本当によろしいですか?\r\n\r\n(ORG指定を間違って利用していませんか?)\r\nファイル名:{1}", bin.Length, result); if (dr != System.Windows.Forms.DialogResult.Yes) { return; } } Undo.UndoData undodata = Program.Undo.NewUndoData(this); if (this.Method.SelectedIndex == 1) { uint newlength = addr + (uint)bin.Length; if (!U.isSafetyOffset(newlength)) { Program.ROM.write_resize_data(newlength); } Program.ROM.write_range(addr, bin, undodata); Program.CommentCache.RemoveRange(addr, addr + (uint)bin.Length); SymbolUtil.ProcessSymbolByComment(fullpath, symbol, GetPlanOfDebugSymbol(), addr); } else { uint freeaddr = U.toOffset((uint)this.FREEAREA.Value); if (!U.CheckZeroAddressWrite(freeaddr)) { return; } //フックに利用する場所 undodata.list.Add(new Undo.UndoPostion(addr, 2 * 4)); uint endaddr = freeaddr + (uint)bin.Length; undodata.list.Add(new Undo.UndoPostion(freeaddr, (uint)bin.Length)); if (endaddr > Program.ROM.Data.Length) {//長さが増える場合、ROMを増設する. Program.ROM.write_resize_data(endaddr); } Program.ROM.write_range(freeaddr, bin); uint usereg = GetSaftyRegister(); byte[] jumpCode = DisassemblerTrumb.MakeInjectJump(addr, freeaddr, usereg); Program.ROM.write_range(addr, jumpCode, undodata); Program.CommentCache.RemoveRange(freeaddr, freeaddr + (uint)bin.Length); SymbolUtil.ProcessSymbolByComment(fullpath, symbol, GetPlanOfDebugSymbol(), freeaddr); } Program.Undo.Push(undodata); InputFormRef.ShowWriteNotifyAnimation(this, addr); this.UndoButton.Show(); }