Ethin wrote:Did I ever say that it wasn't a perfectly legitimate usage of ANSI C? I've used it before -- I know exactly what goto does and I'm okay with its use. It just makes it a bit more troublesome to port it to other language because it requires violating the DRY principal when those languages don't possess that keyword.
Ahhhhhh. My issue was that you called that "troublesome". Just for you, here's a patch that removes that single goto.
Code: Select all
if(dbg_cmd[0]=='n') {
- dbg_regs[31]=disasm(dbg_regs[31]?dbg_regs[31]:dbg_regs[30],NULL);
- dbg_cmd[0]='i';
- goto dis;
+ os=oe=dbg_regs[31]=disasm(dbg_regs[31]?dbg_regs[31]:dbg_regs[30],NULL);
+ while(os<=oe) {
+ a=os;
+ os=disasm(os,str);
+ dbg_printf("%8x:",a);
+ for(j = 32; a < os; a++, j -= 3) {
+ dbg_printf(" %02x",*((unsigned char*)a));
+ }
+ for(; j > 0; j--)
+ dbg_printf(" ");
+ dbg_printf("%s\n",str);
+ }
+ continue;
} else
And voilá, dbg_main is entirely, 100% goto-free. This is the modification that you called "troublesome". And for the sprintf, as I've said you can pick
any implementation that you like, you're not tied to that minimal implementation minidbg is shipped with. You probably already have a printf / sprintf in your klib anyway.
Ethin wrote:The difference is that's a single x86 disassembler and it supports a lot more functionality than yours does.
That's exactly why it sucks big time. A disassembler has one, and only one job: decode instruction into a mnemonic without using further libraries or allocating memory. That's all.
Ethin wrote:So, as you can see, the disassembler is highly customizable and you can configure precisely what you want.
Functionality that nobody needs and nobody wants. Say what happens if you forget to configure something in and it won't be able to disassemble instructions because of that? See? Useless and just asks for trouble. A disassembler should decode instructions, as many as possible, with as little effort and memory footprint and dependencies as possible. Every dependency and configuration complexity is just a punch to the face of portability.
Ethin wrote:Have you ever seen a compiler that does not include or generate stdint.h?
Of course I have. MSVC likes to use its own defines instead of the standard ones. But to gave you an exact example within OSDev realm, you don't have stdint.h neither the uint*_t defines in an UEFI environment (yes, you can integrate my debugger into an UEFI loader too). But just for you, I've added ifdef guards around the typedefs.
Ethin wrote:but you have to admit that this is definitely a neat project.
I can't. It is exactly that kind of bloated software full with useless and unnecessary features and additional library dependencies that I can't stand. Seriously, iced depends on Google Hashing? WTF? And does iced require dynamic memory allocation? I bet it does, so how do you call it from an ISR? Or what would you do if you have to debug the memory allocation in your kernel? (Which is a valid use case, and don't tell me that Rust has its own allocator, because the Linux guys right now
having a really hard time replacing Rust "alloc" with a kernel-provided one because the standard crate is buggy as hell and causes kernel panic.)
Plus there's really no need for op_code_info and instr_info and all the other stuff in a debugger. That's why code analysis is a compile time C header generation feature in my disassembler, because I never turn this feature on. (But if you want, you can generate a version of my disassembler that outputs detailed instruction info into a JSON string
without any additional dependencies, it will add a few kilobytes to the code, still not megabytes.)
Cheers,
bzt