Consider the following part of output from dump of a binary file (amd64):
$ objdump -D /lib/modules/4.16.0-1-amd64/kernel/drivers/usb/class/cdc-acm.ko
...
25f0: e8 00 00 00 00 callq 25f5 <acm_port_dtr_rts+0x5>
25f5: 53 push %rbx
25f6: 48 89 fb mov %rdi,%rbx
25f9: 48 83 ef 20 sub $0x20,%rdi
25fd: 85 f6 test %esi,%esi
25ff: 74 3c je 263d <acm_port_dtr_rts+0x4d>
2601: b8 03 00 00 00 mov $0x3,%eax
2606: b9 03 00 00 00 mov $0x3,%ecx
260b: f6 83 60 08 00 00 40 testb $0x40,0x860(%rbx)
2612: 89 83 94 07 00 00 mov %eax,0x794(%rbx)
2618: 75 18 jne 2632 <acm_port_dtr_rts+0x42>
261a: 48 8d 73 e8 lea -0x18(%rbx),%rsi
261e: 45 31 c9 xor %r9d,%r9d
2621: 45 31 c0 xor %r8d,%r8d
2624: ba 22 00 00 00 mov $0x22,%edx
2629: e8 32 eb ff ff callq 1160 <acm_ctrl_msg.isra.10>
262e: 85 c0 test %eax,%eax
2630: 74 09 je 263b <acm_port_dtr_rts+0x4b>
2632: f6 83 1c 08 00 00 02 testb $0x2,0x81c(%rbx)
2639: 75 08 jne 2643 <acm_port_dtr_rts+0x53>
263b: 5b pop %rbx
263c: c3 retq
263d: 89 f1 mov %esi,%ecx
263f: 31 c0 xor %eax,%eax
2641: eb c8 jmp 260b <acm_port_dtr_rts+0x1b>
2643: 48 8b 7b e8 mov -0x18(%rbx),%rdi
2647: 48 c7 c6 00 00 00 00 mov $0x0,%rsi
264e: 5b pop %rbx
264f: 48 83 c7 30 add $0x30,%rdi
2653: e9 00 00 00 00 jmpq 2658 <acm_port_dtr_rts+0x68>
2658: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
265f: 00
...
The following part from cdc-acm.c corresponds to above dump:
static void acm_port_dtr_rts(struct tty_port *port, int raise)
{
struct acm *acm = container_of(port, struct acm, port);
int val;
int res;
if (raise)
val = ACM_CTRL_DTR | ACM_CTRL_RTS;
else
val = 0;
acm->ctrlout = val;
res = acm_set_control(acm, val);
if (res && (acm->ctrl_caps & USB_CDC_CAP_LINE))
dev_err(&acm->control->dev, "failed to set dtr/rts\n");
}
Also, the following constants are used here:
#define ACM_CTRL_DTR 0x01
#define ACM_CTRL_RTS 0x02
How to find out which line in the dump corresponds to the following line from source code?
val = ACM_CTRL_DTR | ACM_CTRL_RTS;
EDIT
The following procedure was used to change the binary:
hexdump -v -e "1/1 \" %02x\n\"" cdc-acm.ko.orig >text_file
<edit text_file>
xxd -r -p text_file cdc-acm.ko
If you compiled with debug info, then objdump -d -S
to interleave source lines with asm. gdb
can use external debug symbols (like from linux-image-4.16.0-1-amd64-dbg
) but I don't think that's useful for disassembling kernel modules.
I'm not sure how to tell objdump
to look for / use them. See https://www.technovelty.org/code/separate-debug-info.html for some more info about separate debug info, but it doesn't say anything about objdump -S
using them, only gdb.
Otherwise, ACM_CTRL_DTR | ACM_CTRL_RTS
is 0x3
, and there's a test/je that skips over a couple mov $3, %eax
/ mov $3, %ecx
instructions when something %esi
is zero, so that's if(raise)
branch. The 2nd integer function arg is passed in RSI/ESI in the x86-64 System V calling convention, so that's raise
unless it's been clobbered by an earlier call
or some other thing you hid with ...
.
The two mov
instructions are probably explained by assigning val
to something else, but I haven't tried to fully follow the logic.