-1

Short question: Is there a way to print the address of function variables using elfread -a?


Explanation: I'm doing some work on a toy compiler, which generates a shared library using llvm c++ API. I tested it using dlopen() and lldb tools.

When I used elfread command to see the symbol table in my file (as shown below) and found the functions I declared (func1 func2 main), but not the variables inside those functions.

I am now wondering if I could get access to the variables' addresses during runtime? Or is there a way that I could already get them from these information? I'm rather new to this level of computing so any explanation on the elf format would also be much appreciated.

Symbol table '.dynsym' contains 8 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND [...]@GLIBC_2.2.5 (2)
     2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterT[...]
     3: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     4: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMC[...]
     5: 0000000000001120    16 FUNC    GLOBAL DEFAULT   12 func1
     6: 0000000000001160    75 FUNC    GLOBAL DEFAULT   12 main
     7: 0000000000001130    37 FUNC    GLOBAL DEFAULT   12 func2

Symbol table '.symtab' contains 27 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     ... ...
    15: 00000000000011ac     0 FUNC    LOCAL  DEFAULT   13 _fini
    16: 0000000000001000     0 FUNC    LOCAL  DEFAULT    9 _init
    17: 0000000000003df0     0 OBJECT  LOCAL  DEFAULT   18 _DYNAMIC
    18: 0000000000004030     0 OBJECT  LOCAL  DEFAULT   21 __TMC_END__
    19: 0000000000004000     0 OBJECT  LOCAL  DEFAULT   20 _GLOBAL_OFFSET_TABLE_
    20: 0000000000001120    16 FUNC    GLOBAL DEFAULT   12 func1
    21: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND __cxa_finalize@G[...]
    22: 0000000000001160    75 FUNC    GLOBAL DEFAULT   12 main
    23: 0000000000001130    37 FUNC    GLOBAL DEFAULT   12 func2
    24: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterT[...]
    25: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
    26: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMC[...]

PS: I've managed to add the variable's debug info into the shared library, which I could print using llvm-dwarfdump command:

0x0000000c: DW_TAG_compile_unit
              DW_AT_producer    ("demo3 Compiler")
              DW_AT_language    (DW_LANG_C)
              DW_AT_name        ("3-function.st")
              DW_AT_str_offsets_base    (0x00000008)
              DW_AT_stmt_list   (0x00000000)
              DW_AT_comp_dir    ("/root/Documents/llvm-compiler/ST_demo3/test/in")
              DW_AT_low_pc      (0x0000000000001120)
              DW_AT_high_pc     (0x00000000000011ab)
              DW_AT_addr_base   (0x00000008)
              DW_AT_loclists_base       (0x0000000c)

0x00000027:   DW_TAG_subprogram
                DW_AT_low_pc    (0x0000000000001120)
                DW_AT_high_pc   (0x0000000000001130)
                DW_AT_frame_base        (DW_OP_reg7 RSP)
                DW_AT_name      ("func1")
                DW_AT_decl_file ("/root/Documents/llvm-compiler/ST_demo3/test/in/3-function.st")
                DW_AT_decl_line (2)
                DW_AT_external  (true)

0x00000032:     DW_TAG_formal_parameter
                  DW_AT_location        (DW_OP_fbreg -4)
                  DW_AT_name    ("func1")
                  DW_AT_decl_file       ("/root/Documents/llvm-compiler/ST_demo3/test/in/3-function.st")
                  DW_AT_decl_line       (2)
                  DW_AT_type    (0x00000096 "int")

0x0000003d:     DW_TAG_formal_parameter
                  DW_AT_location        (DW_OP_fbreg -2)
                  DW_AT_name    ("var_2")
                  DW_AT_decl_file       ("/root/Documents/llvm-compiler/ST_demo3/test/in/3-function.st")
                  DW_AT_decl_line       (4)
                  DW_AT_type    (0x00000096 "int")

0x00000048:     NULL
Amor
  • 9
  • 2

1 Answers1

0

I am now wondering if I could get access to the variables' addresses during runtime?

You appear to be asking about local (aka automatic) variables. These variables are located at an offset from the current frame base (fbreg), and don't have an address until run time.

At run time, sure you can get the current frame base address (which may be different from run to run due to ASLR), and then compute the location of any local variable (provided it has an address).

This info is not stored in the symbol table, only in the debug info.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362