How can I get a variable's address from dwarfdump and elfdump - SGI

This is a discussion on How can I get a variable's address from dwarfdump and elfdump - SGI ; Hello, Can you tell me how to determine a variable's address using object code and the system commands dwarfdump and elfdump? The command dwarfdump exists on SGI systems, and elfdump can be found on linux machines. Thank you, Christopher Lusardi...

+ Reply to Thread
Results 1 to 6 of 6

Thread: How can I get a variable's address from dwarfdump and elfdump

  1. How can I get a variable's address from dwarfdump and elfdump

    Hello,

    Can you tell me how to determine a variable's address using
    object code and the system commands dwarfdump and elfdump?

    The command dwarfdump exists on SGI systems, and elfdump can
    be found on linux machines.

    Thank you,
    Christopher Lusardi

  2. Re: How can I get a variable's address from dwarfdump and elfdump

    clusardi2k@aol.com (Christopher M. Lusardi) writes:

    > Can you tell me how to determine a variable's address using
    > object code and the system commands dwarfdump and elfdump?


    No, because neither provides sufficient info (at least not for
    shared libraries).

    Assumig you want an address of a global variable, you need several
    pieces of info: the address of the variable in the load module
    (use nm or readelf to get it), the address where the module is loaded
    (use gdb or /proc//maps to find it), and whether the module is
    ET_EXEC or ET_DYN (affects its relocation). For example (on Linux):

    echo "int global; int main() { return 0; }" > junk.c
    gcc -g junk.c
    nm a.out | grep global

    08049504 B global

    Since this is ET_EXEC, the address of global will be 0x08049504.

    nm /lib/libc.so.6 | grep errno
    000f0d60 B errno

    Since this is ET_DYN, it will be at 0x000f0d60 + libc.so.6-load-address:

    gdb a.out
    b main
    run
    info shared
    From To Syms Read Shared Object Library
    0x4001a000 0x4010e85c Yes /lib/libc.so.6
    0x40000000 0x40013ed0 Yes /lib/ld-linux.so.2

    So I expect &errno to be 0x4001a000+0x000f0d60 == 0x4010ad60

    p &errno
    $3 = ( *) 0x4010ad60

    Things get a bit more complicated with newer versions of gdb,
    which print address of the .text section instead of the load address
    (e.g. gdb-6 on the same exe produces:

    (gdb) info shared
    From To Syms Read Shared Object Library
    0x40032650 0x400fa988 Yes /lib/libc.so.6
    0x40001990 0x400104ed Yes /lib/ld-linux.so.2

    so you have to subtract &.text (== 0x00018650 on my system) from
    0x40032650 to find the load address), and also with "prelinked"
    shared libraries (such as libc.so on RedHat-9, and everything on
    Fedora Core1).

    Cheers,
    --
    In order to understand recursion you must first understand recursion.
    Remove /-nsp/ for email.

  3. Re: How can I get a variable's address from dwarfdump and elfdump

    First, how do I find the address of the load module on SGI machines?

    Second, if I create a c program with global variables (int, double, float,
    char *, char, and char[...]) can I just add the load module address to the
    variable address and put the result in a corrsponding pointer variable?

    EG:
    int *int_ptr;

    read (/* load module address */);
    read (/* global variable address of int in Fortran 77 */

    int_ptr = /* load module address */ + /* global variable address */;

    *(int_ptr) = 12;

    Third, will this algorithm work for global variables defined in c and
    Fortran?

    Thank you,
    Christopher Lusardi


    Paul Pluzhnikov wrote in message news:...
    > clusardi2k@aol.com (Christopher M. Lusardi) writes:
    >
    > > Can you tell me how to determine a variable's address using
    > > object code and the system commands dwarfdump and elfdump?

    >
    > No, because neither provides sufficient info (at least not for
    > shared libraries).
    >
    > Assumig you want an address of a global variable, you need several
    > pieces of info: the address of the variable in the load module
    > (use nm or readelf to get it), the address where the module is loaded
    > (use gdb or /proc//maps to find it), and whether the module is
    > ET_EXEC or ET_DYN (affects its relocation). For example (on Linux):
    >
    > echo "int global; int main() { return 0; }" > junk.c
    > gcc -g junk.c
    > nm a.out | grep global
    >
    > 08049504 B global
    >
    > Since this is ET_EXEC, the address of global will be 0x08049504.
    >
    > nm /lib/libc.so.6 | grep errno
    > 000f0d60 B errno
    >
    > Since this is ET_DYN, it will be at 0x000f0d60 + libc.so.6-load-address:
    >
    > gdb a.out
    > b main
    > run
    > info shared
    > From To Syms Read Shared Object Library
    > 0x4001a000 0x4010e85c Yes /lib/libc.so.6
    > 0x40000000 0x40013ed0 Yes /lib/ld-linux.so.2
    >
    > So I expect &errno to be 0x4001a000+0x000f0d60 == 0x4010ad60
    >
    > p &errno
    > $3 = ( *) 0x4010ad60
    >
    > Things get a bit more complicated with newer versions of gdb,
    > which print address of the .text section instead of the load address
    > (e.g. gdb-6 on the same exe produces:
    >
    > (gdb) info shared
    > From To Syms Read Shared Object Library
    > 0x40032650 0x400fa988 Yes /lib/libc.so.6
    > 0x40001990 0x400104ed Yes /lib/ld-linux.so.2
    >
    > so you have to subtract &.text (== 0x00018650 on my system) from
    > 0x40032650 to find the load address), and also with "prelinked"
    > shared libraries (such as libc.so on RedHat-9, and everything on
    > Fedora Core1).
    >
    > Cheers,


  4. Re: How can I get a variable's address from dwarfdump and elfdump

    In article ,
    Christopher M. Lusardi wrote:
    >First, how do I find the address of the load module on SGI machines?
    >
    > Second, if I create a c program with global variables (int, double, float,
    >char *, char, and char[...]) can I just add the load module address to the
    >variable address and put the result in a corrsponding pointer variable?
    >
    > EG:
    > int *int_ptr;
    >
    > read (/* load module address */);
    > read (/* global variable address of int in Fortran 77 */
    >
    > int_ptr = /* load module address */ + /* global variable address */;
    >
    > *(int_ptr) = 12;
    >
    > Third, will this algorithm work for global variables defined in c and
    >Fortran?
    >
    > Thank you,
    > Christopher Lusardi


    I'm unable to hazard a guess at what you are *really* trying to do.
    Trying to access a variable? Why the extra mess, why not just name it?
    Trying to access a variable in some other process?
    Trying to use gdb on an IRIX process?
    Mysterious, or it seems so to me. Maybe I missed something?

    >Paul Pluzhnikov wrote in message news:...

    [ good advice deleted to save space]

    'load module' is not a well defined term (Paul Pluzhnikov
    deals with what you most probably mean).


    Executable, shared-library, and process are well defined, not 'load module',
    at least for IRIX.


    Sign me puzzled.
    David B. Anderson davea at sgi dot com http://reality.sgiweb.org/davea


  5. Re: How can I get a variable's address from dwarfdump and elfdump

    davea@quasar.engr.sgi.com (David Anderson) wrote in message news:...
    > In article ,
    > Christopher M. Lusardi wrote:
    > >First, how do I find the address of the load module on SGI machines?
    > >
    > > Second, if I create a c program with global variables (int, double, float,
    > >char *, char, and char[...]) can I just add the load module address to the
    > >variable address and put the result in a corrsponding pointer variable?
    > >
    > > EG:
    > > int *int_ptr;
    > >
    > > read (/* load module address */);
    > > read (/* global variable address of int in Fortran 77 */
    > >
    > > int_ptr = /* load module address */ + /* global variable address */;
    > >
    > > *(int_ptr) = 12;
    > >
    > > Third, will this algorithm work for global variables defined in c and
    > >Fortran?
    > >
    > > Thank you,
    > > Christopher Lusardi

    >
    > I'm unable to hazard a guess at what you are *really* trying to do.
    > Trying to access a variable? Why the extra mess, why not just name it?
    > Trying to access a variable in some other process?
    > Trying to use gdb on an IRIX process?
    > Mysterious, or it seems so to me. Maybe I missed something?
    >
    > >Paul Pluzhnikov wrote in message news:...

    > [ good advice deleted to save space]
    >
    > 'load module' is not a well defined term (Paul Pluzhnikov
    > deals with what you most probably mean).
    >
    >
    > Executable, shared-library, and process are well defined, not 'load module',
    > at least for IRIX.
    >
    >
    > Sign me puzzled.
    > David B. Anderson davea at sgi dot com http://reality.sgiweb.org/davea


    I sympathize with your puzzlement, but!

    I'm puzzled also. My superior tells me to use the address of the load module
    and offsets within "dwarfdump -i" (or something such as that) to set and show
    contents of variables. The reason he wants me to do this is my own initial
    solution involves too much code.

    My solution would be to get to Fortran's common blocks in C via using "external
    struct" code (declaring common variables in a c struct for each common block)
    and a pair of routines to set and show contents of variables; So, if I have
    2000 global variables that's 2,000 times 27 lines of code for each variable
    etc., etc. I leave out other fine details!

    Thus, I have been in a sense instructed to use the load module address plus
    common block offsets to variables to shorten the code.

    The reason I'm confused is that gdb on SGI boxes will give me the load module
    address, but how do I get that address while my above program is running.
    For example, how do I use gdb in batch mode to get the load module address?

    Can you tell me the best way to determine the load module address? Is what I
    want to do the easiest way to do what I want to do? Again, I am trying to find
    the address of variables, so that I can display their contents etc.

    I guess I am writing a debugger that will work with different load modules.
    I define a load module to be a set of files that I compile and link together
    into an executable program. I cannot use "nm" to get the address of the
    variable because I am not allowed to change how my load module is compiled.
    I.E.: When I compile the programs, "nm" doesn't show me the variable's
    offset within the load module. So, even though you and I are puzzled I have
    to shorten my solution to the problem.

    I have to get my debugger to work on SGI and Linux machines. Consequently, I
    have other concerns. On Linux, can I safely and efficiently get the address of
    load modules in /proc/pid/map? The utility readelf on Linux doesn't give me
    common block address'. How do I get Fortran common block address's on Linux.

    Can you explain to me how will my debugger change when I do all the above and
    "switch" from Fortran 77 generated load modules to C load modules. In other
    words, I have to run my debugger both on Fortran and C code.

    An aside is, "Can I determine the address of c and Fortran 77 local variables?
    How do I do that!"

    Still trying,
    Christopher Lusardi

  6. Re: How can I get a variable's address from dwarfdump and elfdump

    clusardi2k@aol.com (Christopher M. Lusardi) writes:

    > My solution would be to get to Fortran's common blocks in C via using "external
    > struct" code (declaring common variables in a c struct for each common block)
    > and a pair of routines to set and show contents of variables; So, if I have
    > 2000 global variables that's 2,000 times 27 lines of code for each variable
    > etc., etc. I leave out other fine details!
    >
    > Thus, I have been in a sense instructed to use the load module address plus
    > common block offsets to variables to shorten the code.


    So instead of writing 27*2000 lines of transparent code (which
    could be generated automatically with a bit of perl), you'll use a
    table of 2000 offsets (which could also be generated). Sounds reasonable.

    > but how do I get that address while my above program is running.


    You can query dynamic linker: "man rld", look for __rld_obj_head, which
    points to the list of currently loaded modules with their name and
    the address of their ELF header.

    On Linux you achieve the same result with:

    #include
    #include
    int main() {
    struct link_map *lm = (struct link_map *)dlopen(0, RTLD_LAZY);
    while (lm) {
    /* use lm->l_name, lm->l_addr */
    lm = lm->l_next;
    }
    ...

    However, this is complicated by "prelinking" as I mentioned before.

    > I guess I am writing a debugger that will work with different load modules.


    Do you mean an 'in-process debugger' or an 'external' one?
    If the latter, you've got *a lot* more to worry about then finding
    the load addresses.

    Cheers,
    --
    In order to understand recursion you must first understand recursion.
    Remove /-nsp/ for email.

+ Reply to Thread