why are multiple line numbers mapped to the same starting address in .debug_line?

72 Views Asked by At

It's ./drivers/net/virtio_net.c in linux kernel 6.0.0 and compiled to virtio_net.o with optimization -O2 and debuginfo(dwarf4). The readelf --debug-dump=decodedline drivers/net/virtio_net.o shows:

drivers/net/virtio_net.c:
virtio_net.c                                2070                0x55       5       x
virtio_net.c                                2082                0x55       6
virtio_net.c                                2072                0x63
virtio_net.c                                2070                0x6a
virtio_net.c                                2071                0x71               x
virtio_net.c                                2071                0x71       1
virtio_net.c                                2072                0x78               x
virtio_net.c                                2073                0x78       1       x
virtio_net.c                                2073                0x78       2

we can see line 2070 and 2082 are mapped to the same address 0x55

and the .c:

for (i = 0; i < vi->max_queue_pairs; i++) {
    u64 tpackets, tbytes, terrors, rpackets, rbytes, rdrops;
    struct receive_queue *rq = &vi->rq[i];
    struct send_queue *sq = &vi->sq[i];

    do {
        start = u64_stats_fetch_begin_irq(&sq->stats.syncp);
        tpackets = sq->stats.packets;  //line: 2070
        tbytes   = sq->stats.bytes;
        terrors  = sq->stats.tx_timeouts;
    } while (u64_stats_fetch_retry_irq(&sq->stats.syncp, start));

    do {
        start = u64_stats_fetch_begin_irq(&rq->stats.syncp);
        rpackets = rq->stats.packets;
        rbytes   = rq->stats.bytes;
        rdrops   = rq->stats.drops;
    } while (u64_stats_fetch_retry_irq(&rq->stats.syncp, start));

    tot->rx_packets += rpackets;  //line: 2082
    tot->tx_packets += tpackets;
    tot->rx_bytes   += rbytes;
    tot->tx_bytes   += tbytes;
    tot->rx_dropped += rdrops;
    tot->tx_errors  += terrors;
}

for objdump, when disassembling it with -l (show lines), it generates:

/root/linux-master/drivers/net/virtio_net.c:2082
      55:   48 03 98 a0 01 00 00    add    0x1a0(%rax),%rbx
      5c:   49 81 c4 58 04 00 00    add    $0x458,%r12
/root/linux-master/drivers/net/virtio_net.c:2072
      63:   4c 8b b5 b8 02 00 00    mov    0x2b8(%rbp),%r14
/root/linux-master/drivers/net/virtio_net.c:2070
      6a:   4c 8b bd 90 02 00 00    mov    0x290(%rbp),%r15
/root/linux-master/drivers/net/virtio_net.c:2071
      71:   4c 8b ad 98 02 00 00    mov    0x298(%rbp),%r13
/root/linux-master/drivers/net/virtio_net.c:2079
      78:   48 8b a8 b0 01 00 00    mov    0x1b0(%rax),%rbp
/root/linux-master/drivers/net/virtio_net.c:2072
      7f:   4c 89 34 24             mov    %r14,(%rsp)

it seems objdump think the instruction at address 0x55 should be corresponded with line 2082. I'm confused about it's approach.

And I'd like to know when facing this situation ( one instrucion map to multiple line within source code in debug info) , how do I decide which line is better to correspond the instrucion with

0

There are 0 best solutions below