Linux: detecting a 64-bit kernel (long mode) from a 32-bit user-mode program

What is the best and most reliable way to determine if a 32-bit user-mode program is running in a 64-bit kernel or not (that is, if the system is in "long mode")? I prefer not to call external programs if possible (or load any kernel modules).

Note. I want to determine if a 64-bit kernel is used (or whether the processor is in long mode), and not just if there is a 64-bit processor ( /proc/cpuinfotells me that the 64-bit feature is not used).

The kernel fakes a 32-bit processor if uname32-bit is compiled or in use setarch i686.

+5
source share
3 answers

Call the function uname()and check the return string machine, which will be x86_64for the 64-bit Intel platform.

One way to reverse the effect of use setarchis to reset the identity:

#include <stdio.h>
#include <sys/utsname.h>
#include <sys/personality.h>

int main()
{
    struct utsname u;

    personality(PER_LINUX);

    uname(&u);
    puts(u.machine);
    return 0;
}

This shows the correct results when compiling in 32-bit mode and runs on a 64-bit system:

$ gcc -m32 -o u u.c
$ ./u
x86_64
$ setarch i686 ./u
x86_64

EDIT: fixed code for the opposite effect setarch.

Link .

+6
source

Assuming uname () is modifying, there are several more mechanisms. One way is to check the width of the address of any of the kernel characters.

#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char **argv) {
  char *inputline = malloc(1024);
  char *oinputline = inputline;
  int fd = open("/proc/kallsyms", O_RDONLY);
  int numnibbles = 0;
  if (fd == -1) {
      perror("open");
      free(inputline);
      exit(1);
  }
  read(fd, inputline, 1024);
  close(fd);
  while(!isspace(*inputline)) {
      numnibbles++;
      inputline++;
  }
  printf("%dbit\n", numnibbles*4);
  free(oinputline);
  exit (0);
}
+1
source

If the kernel is configured for it, you can read the kernel configuration from /proc/config.gz

zcat /proc/config.gz | grep CONFIG_64BIT
# CONFIG_64BIT is not set

I'm not sure how portable you need it - this doesn't seem like a super generic configuration option.

0
source

All Articles