If you used GDB before, This means you used some kind of debuggin info in the ELF. one of the famous ones is DWARF. Wiki one-liner is

DWARF is a widely used, standardized debugging data format. DWARF was originally designed along with Executable and Linkable Format (ELF), although it is independent of object file formats

Dwarf information is divided into several ELF sections and described with Debugging Information Entry (DIE).

Let’s start with small example and commands to dump the dwarf DIE’s.

     1	
     2	void main(){
     3		int a,b;
     4	
     5		a = 1;
     6		b = 2;
     7		b = a + b;
     8	}
gcc -g main.c
dwarfdump a.out

Variables Link to heading

Variables and scopes DIE’s are defined in .debug_info section of the ELF. The DIE tag for variable a is defines as DW_TAG_variable and DW_AT_type points to the DIE for base type DW_TAG_base_type.

.debug_info


 26 < 2><0x0000004b>      DW_TAG_variable
 27                         DW_AT_name                  a
 28                         DW_AT_decl_file             0x00000001 /dwarf/main.c
 29                         DW_AT_decl_line             0x00000003
 30                         DW_AT_decl_column           0x00000006
 31                         DW_AT_type                  <0x00000066>
 32                         DW_AT_location              len 0x0002: 9168: DW_OP_fbreg -24

DW_TAG_base_type DIE is defined at 0x66 in the same section.

 40 < 1><0x00000066>    DW_TAG_base_type
 41                       DW_AT_byte_size             0x00000004
 42                       DW_AT_encoding              DW_ATE_signed
 43                       DW_AT_name                  int

Line info section Link to heading

another useful section is .debug_line. each lines maps address in the elf to line number in the compilation unit scope in the original file.

 45 .debug_line: line number info for a single cu
 46 Source lines (from CU-DIE at .debug_info offset 0x0000000b):
 47 
 48             NS new statement, BB new basic block, ET end of text sequence
 49             PE prologue end, EB epilogue begin
 50             IS=val ISA number, DI=val discriminator value
 51 <pc>        [lno,col] NS BB ET PE EB IS= DI= uri: "filepath"
 52 0x00001129  [   2,12] NS uri: "/Downloads/dwarf/main.c"
 53 0x00001131  [   5, 4] NS
 54 0x00001138  [   6, 4] NS
 55 0x0000113f  [   7, 4] NS
 56 0x00001145  [   8, 1] NS
 57 0x00001148  [   8, 1] NS ET

And using objdump, we can see that address for instructions 0x1129 and 0x1131

    1129:	f3 0f 1e fa          	endbr64 
    112d:	55                   	push   %rbp
    112e:	48 89 e5             	mov    %rsp,%rbp
	int a,b;

	a = 1;
    1131:	c7 45 f8 01 00 00 00 	movl   $0x1,-0x8(%rbp)