code to determine 64-bit vs 32-bit binaries?

code to determine 64-bit vs 32-bit binaries?

Post by Mohun Biswa » Sat, 29 May 2004 01:58:40



Can anyone post sample code showing how to determine, within a Solaris
process space, whether a program it's about to exec is a 64-bit or
32-bit executable? No use saying "man file"; I have to do it within the
current process. And of course the next obvious response is "take a look
at GNU or BSD file commands and see what they do". Unfortunately I've
tried that and it's not working right. So if any of you have ever had to
do this and have a few lines of C code to post, I'd appreciate it.

--
Thanks,
M.Biswas

 
 
 

code to determine 64-bit vs 32-bit binaries?

Post by Stephen L » Sat, 29 May 2004 02:48:14



> Can anyone post sample code showing how to determine, within a Solaris
> process space, whether a program it's about to exec is a 64-bit or
> 32-bit executable? No use saying "man file"; I have to do it within the
> current process. And of course the next obvious response is "take a look
> at GNU or BSD file commands and see what they do". Unfortunately I've
> tried that and it's not working right. So if any of you have ever had to
> do this and have a few lines of C code to post, I'd appreciate it.

> --
> Thanks,
> M.Biswas

1. Why does it matter?  `execv()' doesn't need
   any special handling for a 64-bit executable.
2. In your current process, if there is no
   C interface to find this info out for the
   program you're about to exec, what's wrong
   with running `popen(3C)' with an appropriate
   command string to determine that for you?
3. /bin/file, part of Solaris, _can_ tell you
   the difference in executables -->

file /bin/ls
/bin/ls:        ELF 32-bit MSB executable SPARC Version 1, dynamically
linked, stripped

HTH,

Stephen

 
 
 

code to determine 64-bit vs 32-bit binaries?

Post by Seongbae Par » Sat, 29 May 2004 03:00:34



> Can anyone post sample code showing how to determine, within a Solaris
> process space, whether a program it's about to exec is a 64-bit or
> 32-bit executable? No use saying "man file"; I have to do it within the
> current process. And of course the next obvious response is "take a look
> at GNU or BSD file commands and see what they do". Unfortunately I've
> tried that and it's not working right. So if any of you have ever had to
> do this and have a few lines of C code to post, I'd appreciate it.

See manpages for gelf_getclass(3ELF), gelf(3ELF) and elf(3ELF).

Seongbae

 
 
 

code to determine 64-bit vs 32-bit binaries?

Post by Dragan Cvetkovi » Sat, 29 May 2004 03:12:05




>> Can anyone post sample code showing how to determine, within a Solaris
>> process space, whether a program it's about to exec is a 64-bit or
>> 32-bit executable? No use saying "man file"; I have to do it within the
>> current process. And of course the next obvious response is "take a look
>> at GNU or BSD file commands and see what they do". Unfortunately I've
>> tried that and it's not working right. So if any of you have ever had to
>> do this and have a few lines of C code to post, I'd appreciate it.

> See manpages for gelf_getclass(3ELF), gelf(3ELF) and elf(3ELF).

Nice. Didn't know about them.

Btw, someone needs to correct the example there (it seems I am picking on
examples in sun's man pages lately):

    void
     main(int argc, char **argv)

should, of course, be

     int
      main(int argc, char **argv)

Dragan

--
Dragan Cvetkovic,

To be or not to be is true. G. Boole      No it isn't.  L. E. J. Brouwer

!!! Sender/From address is bogus. Use reply-to one !!!

 
 
 

code to determine 64-bit vs 32-bit binaries?

Post by Seongbae Par » Sat, 29 May 2004 03:37:10


...

Quote:> Btw, someone needs to correct the example there (it seems I am picking on
> examples in sun's man pages lately):

>     void
>      main(int argc, char **argv)

> should, of course, be

>      int
>       main(int argc, char **argv)

> Dragan

Maybe the example is too realistic :)

Seongbae

 
 
 

code to determine 64-bit vs 32-bit binaries?

Post by Mohun Biswa » Sat, 29 May 2004 12:04:25



> See manpages for gelf_getclass(3ELF), gelf(3ELF) and elf(3ELF).

Thank you, I just wrote up a test program using gelf_getclass() and it
works beautifully.

--
Thanks,
M.Biswas

 
 
 

code to determine 64-bit vs 32-bit binaries?

Post by James Carlso » Sat, 29 May 2004 22:56:43



> Btw, someone needs to correct the example there (it seems I am picking on
> examples in sun's man pages lately):

>     void
>      main(int argc, char **argv)

> should, of course, be

>      int
>       main(int argc, char **argv)

The ANSI C standard intentionally requires hosted implementations not
to have a prototype for main() (5.1.2.2.1), and even permits return
from main() without a value to have "undefined" semantics (5.1.2.2.3).

This means that you can define "void main()" and, as long as you
either call exit(2) rather than returning or falling off the end, or
if the hosted environment doesn't care about the exit status, you're
on relatively safe ground.  So the example isn't entirely wrong.

For what it's worth, gcc's -Wall will moan about 'void' as being a bad
idea.

In contrast to C, C++ appears to require "int main()."  But, then, I
hope that's not the issue here.  ;-}

In any event, yeah, I agree that it ought to be 'int' rather than
'void', just to encourage correct exit status usage and generally good
programming hygiene.

--

Sun Microsystems / 1 Network Drive         71.234W   Vox +1 781 442 2084
MS UBUR02-212 / Burlington MA 01803-2757   42.497N   Fax +1 781 442 1677

 
 
 

code to determine 64-bit vs 32-bit binaries?

Post by Mohun Biswa » Sat, 29 May 2004 22:57:29




>>Can anyone post sample code showing how to determine, within a Solaris
>>process space, whether a program it's about to exec is a 64-bit or
>>32-bit executable? No use saying "man file"; I have to do it within the
>>current process. And of course the next obvious response is "take a look
>>at GNU or BSD file commands and see what they do". Unfortunately I've
>>tried that and it's not working right. So if any of you have ever had to
>>do this and have a few lines of C code to post, I'd appreciate it.

> 1. Why does it matter?  `execv()' doesn't need
>    any special handling for a 64-bit executable.

Yes it does. There is a conceptual flaw in Suns's 32/64 bit strategy in
that it's not fully compatible with traditional SVR4 LD_* semantics. For
instance, say you set LD_PRELOAD=/somedir/somelibrary.so and then exec.
This works fine *if* the program you're executing is in the same ELF
class as somelibrary.so. If it turns out the lib is 32-bit and the
program is 64, you're SOL. You can't even catch the exec failure and try
again with a 64-bit library, because in this case it's the runtime
linker that fails *after* the exec has succeeded. The only solution is
to know what type of program you're about to execute and then set the
LD_ variable to point to the corresponding class (this applies to other
LD_* env vars, not just LD_PRELOAD).

It seems to me the only thing Sun could do to work around this problem
is to add a form of wildcarding to the LD_* EVs, e.g.:

        LD_PRELOAD=/somedir/{32,64}/somelibrary.so
or
        LD_PRELOAD=/somedir/*/somelibrary.so

but I'm not holding my breath.

Quote:> 2. In your current process, if there is no
>    C interface to find this info out for the
>    program you're about to exec, what's wrong
>    with running `popen(3C)' with an appropriate
>    command string to determine that for you?
> 3. /bin/file, part of Solaris, _can_ tell you
>    the difference in executables -->

Perhaps you missed the place where I said "I have to do it within the
current process"? Can /bin/file answer my question _without a fork_? I
thought not.

--
Thanks,
M.Biswas

 
 
 

code to determine 64-bit vs 32-bit binaries?

Post by Dragan Cvetkovi » Sat, 29 May 2004 23:51:53




>> Btw, someone needs to correct the example there (it seems I am picking on
>> examples in sun's man pages lately):

>>     void
>>      main(int argc, char **argv)

>> should, of course, be

>>      int
>>       main(int argc, char **argv)

> The ANSI C standard intentionally requires hosted implementations not
> to have a prototype for main() (5.1.2.2.1), and even permits return
> from main() without a value to have "undefined" semantics (5.1.2.2.3).

> This means that you can define "void main()" and, as long as you
> either call exit(2) rather than returning or falling off the end, or
> if the hosted environment doesn't care about the exit status, you're
> on relatively safe ground.  So the example isn't entirely wrong.

Except that there was no exit(2) (or exit(3c)) in the mentioned program :-)

Quote:> In any event, yeah, I agree that it ought to be 'int' rather than
> 'void', just to encourage correct exit status usage and generally good
> programming hygiene.

Hear hear.

Thanks for support James.

Bye, Dragan

--
Dragan Cvetkovic,

To be or not to be is true. G. Boole      No it isn't.  L. E. J. Brouwer

!!! Sender/From address is bogus. Use reply-to one !!!

 
 
 

code to determine 64-bit vs 32-bit binaries?

Post by Alan Coopersmit » Sun, 30 May 2004 00:42:56



|Yes it does. There is a conceptual flaw in Suns's 32/64 bit strategy in
|that it's not fully compatible with traditional SVR4 LD_* semantics. For
|instance, say you set LD_PRELOAD=/somedir/somelibrary.so and then exec.
|This works fine *if* the program you're executing is in the same ELF
|class as somelibrary.so. If it turns out the lib is 32-bit and the
|program is 64, you're SOL. You can't even catch the exec failure and try
|again with a 64-bit library, because in this case it's the runtime
|linker that fails *after* the exec has succeeded. The only solution is
|to know what type of program you're about to execute and then set the
|LD_ variable to point to the corresponding class (this applies to other
|LD_* env vars, not just LD_PRELOAD).

The much simpler solution is to set the _32 & _64 versions of the LD_*
instead of the old non-specific versions.  Only put 32-bit libraries in
LD_PRELOAD_32 and 64-bit libraries in LD_PRELOAD_64 and don't set
LD_PRELOAD at all.

--
________________________________________________________________________


  Working for, but definitely not speaking for, Sun Microsystems, Inc.

 
 
 

code to determine 64-bit vs 32-bit binaries?

Post by James Carlso » Sun, 30 May 2004 04:33:44



> The much simpler solution is to set the _32 & _64 versions of the LD_*
> instead of the old non-specific versions.  Only put 32-bit libraries in
> LD_PRELOAD_32 and 64-bit libraries in LD_PRELOAD_64 and don't set
> LD_PRELOAD at all.

And before someone grumbles about the man pages, it's already there.
ld.so.1(1) says:

     Each environment variable can be specified with a _32 or _64
     suffix.   This  makes  the  environment  variable  specific,
     respectively, to 32-bit or 64-bit processes.  This  environ-
     ment  variable  overrides  any  non-suffixed  version of the
     environment variable that may be in effect.

--

Sun Microsystems / 1 Network Drive         71.234W   Vox +1 781 442 2084
MS UBUR02-212 / Burlington MA 01803-2757   42.497N   Fax +1 781 442 1677

 
 
 

code to determine 64-bit vs 32-bit binaries?

Post by Casper H.S. Di » Wed, 02 Jun 2004 17:29:09



>Yes it does. There is a conceptual flaw in Suns's 32/64 bit strategy in
>that it's not fully compatible with traditional SVR4 LD_* semantics. For
>instance, say you set LD_PRELOAD=/somedir/somelibrary.so and then exec.
>This works fine *if* the program you're executing is in the same ELF
>class as somelibrary.so. If it turns out the lib is 32-bit and the
>program is 64, you're SOL. You can't even catch the exec failure and try
>again with a 64-bit library, because in this case it's the runtime
>linker that fails *after* the exec has succeeded. The only solution is
>to know what type of program you're about to execute and then set the
>LD_ variable to point to the corresponding class (this applies to other
>LD_* env vars, not just LD_PRELOAD).

There are several solutions to this problem:

        - if the object relies in a standard directory, use it without
          a pathname like so:


                LD_PRELOAD=watchmalloc.so.1
                LD_PRELOAD=libumem.so.1

        - if you have no choice but specify a full pathname because
          the runtime path does not include the proper directory, use th
          _32 or _64 variables:

                LD_PRELOAD_64=/somedir/64/mylibrary.so
                LD_PRELOAD_32=/somedir/32/mylibrary.so

Casper
--
Expressed in this posting are my opinions.  They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.

 
 
 

1. Determining whether 64-bit or 32-bit kernel is running?

I had a question from another sysadmin the other day that stumped me;
is there a way in Solaris to reliably determine if the machine is
currently running the 64-bit or the 32-bit kernel?  Preferably without
crashing the machine or doing some sort of kernel debug.  The question
comes from someone who is trying to write a script to determine which
version of a freeware package to install in an automated fashion (as
some, like pidentd, do not work if the 32-bit-compiled version is used
on a 64-bit machine and vice versa).  We checked in a couple places
you might guess, like uname, prtdiag, and /etc/release, but none of
those contain that information, and we didn't see anything useful in
/proc either.  Any ideas?

--
Steve Hilberg <Necromancer>               CITES Workstation Support Group  

      Member, APAGear                   I don't even know what CITES stands
   http://www.apagear.org            for, so I don't speak for them.
-----------------------------------------------------------------------------
"As we were forged we shall return, perhaps some day.      | VNV Nation,
I will remember you and wonder who we were."               |    "Further"

2. Titan-Tool

3. Compiling 64-bit code on 32-bit machine

4. SUN-RPC performance problems

5. 64-bit instructions in 32-bit code

6. NIS package availiable on Solaris 2.x

7. 32-bit code on 64-bit RS/6000

8. /etc/inittab: no more processes

9. Performance Issues on Sun Solaris 64-bit vs. 32-bit

10. Solaris 2.x :- How to tell if & configure 64-bit vs 32-bit

11. Performance Issues on Sun Solaris 64-bit vs. 32-bit

12. SBus-based drivers (32-bit vs 64-bit Solais Kernels)

13. Detecting 32-bit vs. 64-bit