Comment 5 for bug 298139

Revision history for this message
Rogério Theodoro de Brito (rbrito) wrote :

Hi there.

I've been bitten by this one for almost a year and I just took some time to discover what the hell was happening here.

After bisecting here the git tree from upstream, I noticed an error: the commit 52fa52f93943a6154cf2ac9b473d6b4948d75a15 changes a cast from an unsigned long long int to a uintptr_t. This may have worked on some architectures, but it surely doesn't work on some 32-bit arches. In particular, on PowerPC, this leads to very bad results:

#include <stdio.h>

int main(void)
{
 printf("%llu\n", (unsigned long int) 42);
 printf("%llu\n", (unsigned long long int) 42);
 return 0;
}

produces here:

183609205424
42

The problem with the code is in libspectre/spectre-device.c, around line 240. Reverting the commit 52fa52f93943a6154cf2ac9b473d6b4948d75a15 fixes this here and makes everything work fine. I can confirm that the file that the original poster posted here works fine now.

BTW, just for the record, here are the sizes, in bytes, of the integral and pointer types in the 32 and 64-bit archictectures under Linux:

| | 32 bits arch | 64 bits arch |
| int | 4 | 4 |
| long | 4 | 8 |
| long long | 8 | 8 |
| pointer | 4 | 8 |
| short | 2 | 2 |

Sorry if this shows up messed up, but seeing with a fixed-width font makes things nicer---otherwise, see http://wiki.debian.org/ArchitectureSpecificsMemo.

In summary, we need the field to always be 8-bytes long and simply using a (unsigned) long is enough for, say, amd64, but not for powerpc. We really want a type that is 8-bytes wide in both arches and this should be a long long.

Otherwise, the instruction to use a format string of llu (or llx, for that matter) on a printf-like function makes the function read information that is not part of the integral argument being passed.

Regards,