The problem is indeed obvious. I really wish there were a better way to
detect the bit-width of the process than looking at /proc/PID/exe, but
perhaps there really isn't.
What about just looking at the first 8 bytes of the auxv data? The first
element is never AT_NULL, so it will have a nonzero a_type. No a_type
value will ever be more than UINT32_MAX. So for big-endian, the first four
bytes being zero says it's 64-bit. For little-endian, it's not so easy
without assuming that the first a_val is nonzero. That's actually reliable
enough in practice, but it feels wrong. Maybe there is something better
for little-endian that I'm not thinking of.
+ ssize_t nread = read (fd, &buf, sizeof buf);
+ unsigned char buf;
+ close (fd);
+ if (nread != sizeof (buf) || buf != ELFMAG0 || buf != ELFMAG1
+ || buf != ELFMAG2 || buf != ELFMAG3
+ || (buf != ELFCLASS64 && buf != ELFCLASS32))
+ return -1;
+ return buf == ELFCLASS64 ? 64 : 32;
Please use the EI_* macros instead of literal indices and size.
I'd just make it return the [EI_CLASS] value and compare against
that in grovel_auxv.