1

I'm writing an x86-64 interpreter and as a way to debug and test my program I need to record the process as list of assembly instruction preferably in at&t syntax and also ignoring dynamic library function calls. and also record the cpu registers

do you know of any tool that could help.

I tried to use gdb record save ... command but the output file is very large compared to the source program

int main() {
  return 42;
}

and after disassembling the file the instruction address is wrong.

my desired output format is something like this for the above program (compiled with tcc)

  400300: 31 ed                    xor    %ebp,%ebp
  400302: 49 89 d1                 mov    %rdx,%r9
  400305: 5e                       pop    %rsi
  400306: 48 89 e2                 mov    %rsp,%rdx
  400309: 48 83 e4 f0              and    $0xfffffffffffffff0,%rsp
  40030d: 50                       push   %rax
  40030e: 54                       push   %rsp
  40030f: 4c 8b 05 62 02 20 00     mov    0x200262(%rip),%r8        # 600578
  400316: 48 8b 0d 63 02 20 00     mov    0x200263(%rip),%rcx           # 600580
  40031d: 48 8b 3d 64 02 20 00     mov    0x200264(%rip),%rdi        # 600588
  400324: ff 15 66 02 20 00        callq  *0x200266(%rip)        # 600590
__libc_start_main
  400331: 55                       push   %rbp
  400332: 48 89 e5                 mov    %rsp,%rbp
  400335: 48 81 ec 00 00 00 00     sub    $0x0,%rsp
  40033c: b8 2a 00 00 00           mov    $0x2a,%eax
  400341: c9                       leaveq
  400342: c3                       retq
  40032a: f4                       hlt
42
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
raoof
  • 538
  • 1
  • 6
  • 12
  • 1
    Program startup includes dynamic linking, and a bunch of CRT code that runs before `main`. That's totally normal. If you don't like it, try static linking, or only trace `main`. Or write `_start` yourself in asm. [Number of executed Instructions different for Hello World program Nasm Assembly and C](https://stackoverflow.com/a/35210404) (See also Michael Petch's answer there). Also [How do I determine the number of x86 machine instructions executed in a C program?](https://stackoverflow.com/q/54355631) Those are counts, not traces, but they explain the large amount of dynamic-linker code – Peter Cordes Oct 11 '20 at 00:52
  • @PeterCordes can you give an example of how to record after main. I don't know gdb enough to figure it out. thanks. – raoof Oct 11 '20 at 07:13
  • Not something I've done either, but presumably start with `start` or `b main` / `run` to get to the top of main *before* running `record save ...`, if that works. (If you do this, compile with `-fno-plt` to force eager, not lazy, dynamic linking.) – Peter Cordes Oct 11 '20 at 07:17

1 Answers1

1

I find a partial solution using qemu.

qemu-x86_64 -singlestep -d in_asm,cpu,fpu -dfilter beg..end myProgram 2>&1 | vim -

replace beg and end with the first and last instruction address of your program you can find them with

objdump -d yourProgram | vim -

notice that the output file for my very simple program that draw a rectangle is 55MB. and it was slow to run.

raoof
  • 538
  • 1
  • 6
  • 12
  • "draw a rectangle"? You mean in a GUI window? Not surprised that took a lot of insns. If you just make a `write()` system call to print text on a terminal, you could write that much more compactly. – Peter Cordes Oct 11 '20 at 23:31
  • I tried my program with simpler example, it couldn't run this example and also without ```,cpu,fpu``` the file size is 388K so it's going to be large with ```cpu,fpu``` anyway. – raoof Oct 12 '20 at 06:38