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...
-
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
-
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.
-
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,
-
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
-
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
-
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.