aclements / libelfin

C++11 ELF/DWARF parser
MIT License
317 stars 99 forks source link

Fix line_table::find_address when the address is the last entry #25

Open boyou opened 6 years ago

boyou commented 6 years ago

If this extra check is missing, in case the last valid entry in the line table matches the given address, end will still be returned.

boyou commented 6 years ago

@aclements , I'm not sure this is about non standard conforming binaries.

For the sample program

void f() {
  int i = 0;
  i += 1;
  i += 2;
}

int main() {
  while (1) {
    f();
  }
  return 0;
}

if I compile with gcc main.c -g -Wall -o main -gdwarf-4 -O0, the assembly code will look like

00000000004004ec <main>:
  4004ec:       55                      push   rbp
  4004ed:       48 89 e5                mov    rbp,rsp
  4004f0:       b8 00 00 00 00          mov    eax,0x0
  4004f5:       e8 dc ff ff ff          call   4004d6 <f>
  4004fa:       eb f4                   jmp    4004f0 <main+0x4>
  4004fc:       0f 1f 40 00             nop    DWORD PTR [rax+0x0]

` and the line number is

.debug_line: line number info for a single cu
Source lines (from CU-DIE at .debug_info offset 0x0000000b):

<pc>        [row,col] NS BB ET PE EB IS= DI= uri: "filepath"
NS new statement, BB new basic block, ET end of text sequence
PE prologue end, EB epilogue begin
IA=val ISA number, DI=val discriminator value
0x004004d6  [   1, 0] NS uri: "/tmp/pull-request-test/main.c"
0x004004da  [   2, 0] NS
0x004004e1  [   3, 0] NS
0x004004e5  [   4, 0] NS
0x004004e9  [   5, 0] NS
0x004004ec  [   7, 0] NS
0x004004f0  [   9, 0] NS DI=0x1
0x004004fa  [  10, 0] NS DI=0x1
0x004004fc  [  10, 0] NS ET

IIUC, 0x004004fa corresponds to line 10 (the ending brace for the while loop).

Without the change, find_address(0x004004fa) will return end() instead of the entry. See whole program at https://paste.ubuntu.com/p/24F7N6jSyN/.

Does it mean the end sequence is missing, or do I get anything wrong?

aclements commented 4 years ago

I'm not sure how to interpret that line number table dump you pasted. It looks like it's already been rather processed, which makes it hard to tell what's going on at a low level. The "ET" on the last line suggests there is an end_sequence. Can you post a more raw dump, for example from objdump --dwarf=rawline?