2

I'm looking for a programatic way to find the powerpc cpu type on Linux. Performing some google searches associated an answer suggesting the mfpvr instruction I found that this is available in the ELF AUX header, and sure enough I can obtain the POWER5 string for the machine I'm running on with the following:

#include <stdio.h>
#include <elf.h>

int main( int argc, char **argv, char **envp )
{
   /* walk past all env pointers */
   while ( *envp++ != NULL )
      ;

   /* and find ELF auxiliary vectors (if this was an ELF binary) */
#if 0
   Elf32_auxv_t * auxv = (Elf32_auxv_t *) envp ;
#else
   Elf64_auxv_t * auxv = (Elf64_auxv_t *) envp ;
#endif

   char * platform = NULL ;

   for ( ; auxv->a_type != AT_NULL ; auxv++ )
   {
      if ( auxv->a_type == AT_PLATFORM )
      {
         platform = (char *)auxv->a_un.a_val ;
         break;
      }
   }

   if ( platform )
   {
      printf( "%s\n", platform ) ;
   }

   return 0 ;
}

In the shared library context where I want to use this info I have no access to envp. Is there an alternate programatic method to find the beginning of the ELF AUX header?

Community
  • 1
  • 1
Peeter Joot
  • 7,848
  • 7
  • 48
  • 82

1 Answers1

1

You can get if from /proc/self/auxv file

According to man proc /proc/self/auxv is available since kernel level 2.6.0-test7.

Another option - get some (existing) environment variable - let say HOME, or PATH, or whatever. Please note that you'll get it's ADDRESS. From here you can go back and find previous env variable, then one before it, etc. After that you can likewise skip all argv arguments. And then you get to the last AUXV entry. Some steps back - and you should be able find your AT_PLATFORM.

EDIT: It looks like glibc now provides a programatic method to get at this info:

glibc-headers-2.17-106: /usr/include/sys/auxv.h : getauxinfo()

Example:

#include <sys/auxv.h>
#include <stdio.h>

int main()
{
   unsigned long v = getauxval( AT_PLATFORM ) ;
   printf( "%s\n", (char *)v ) ;

   return 0 ;
}
Peeter Joot
  • 7,848
  • 7
  • 48
  • 82
  • It's available even in 2.6.16 (and likely earlier). – Peeter Joot Aug 14 '12 at 19:22
  • 2.4.22 (Fedora Core 1) doesn't have /proc/self/auxv – Valery Reznic Aug 15 '12 at 07:34
  • For those still trying to link on outdated platforms (yes, me!): Using `getenv()` (or the global symbol `environ`) risks accessing unallocated memory if somebody has already called `setenv()` and caused that entry to be relocated. – sh1 Mar 22 '16 at 03:55