blob: 754364655abc4bc465bf20418954f36f0092c530 [file] [log] [blame]
/*
* Copyright (c) 2012 The Native Client Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/*
* Check ABI compliance, this is especially important for PNaCl.
* This test should cover at least all the types that appear in
* the core IRT interface (src/untrusted/irt/irt.h) as well as
* the base types.
*/
#include <dirent.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "gtest/gtest.h"
namespace {
class AbiTests : public ::testing::Test {
protected:
AbiTests() {
// You can do set-up work for each test here.
}
~AbiTests() override {
}
void SetUp() override {
}
void TearDown() override {
}
};
} //namespace
/* we expect this to be padded to 16 bytes of total size */
typedef struct {
double d;
float f;
} S1;
#define CHECK_SIZEOF(t, v) EXPECT_EQ(sizeof(t), (size_t)v) << "bad sizeof " #t
/* Helper Types so we can describe a type in one token */
typedef void (*FunctionPointer)(void);
typedef void *Pointer;
typedef long long long_long;
typedef long double long_double;
TEST_F(AbiTests, CheckSizes) {
CHECK_SIZEOF(char, 1);
CHECK_SIZEOF(short, 2);
CHECK_SIZEOF(int, 4);
CHECK_SIZEOF(long, 8);
CHECK_SIZEOF(long long, 8);
CHECK_SIZEOF(Pointer, 8);
CHECK_SIZEOF(FunctionPointer, 8);
CHECK_SIZEOF(float, 4);
CHECK_SIZEOF(double, 8);
CHECK_SIZEOF(long_double, 16);
CHECK_SIZEOF(S1, 16);
CHECK_SIZEOF(S1[2], 16*2);
CHECK_SIZEOF(dev_t, 8);
CHECK_SIZEOF(ino_t, 8);
CHECK_SIZEOF(mode_t, 4);
CHECK_SIZEOF(nlink_t, 8);
CHECK_SIZEOF(uid_t, 4);
CHECK_SIZEOF(gid_t, 4);
CHECK_SIZEOF(off_t, 8);
CHECK_SIZEOF(blksize_t, 8);
CHECK_SIZEOF(blkcnt_t, 8);
CHECK_SIZEOF(off_t, 8);
CHECK_SIZEOF(size_t, 8);
CHECK_SIZEOF(fpos_t, 16);
CHECK_SIZEOF(time_t, 8);
CHECK_SIZEOF(struct timezone, 8);
CHECK_SIZEOF(suseconds_t, 8);
CHECK_SIZEOF(clock_t, 8);
CHECK_SIZEOF(clockid_t, 4);
CHECK_SIZEOF(struct timeval, 16);
CHECK_SIZEOF(struct timespec, 16);
CHECK_SIZEOF(struct stat, 144);
CHECK_SIZEOF(struct dirent, 280);
}
#define CHECK_ALIGNMENT(T, a) do { \
typedef struct { char c; T x; } AlignStruct; \
EXPECT_EQ(offsetof(AlignStruct, x), (size_t)a) << "bad offsetof " #T; \
} while(0)
TEST_F(AbiTests, CheckAlignment) {
CHECK_ALIGNMENT(char, 1);
CHECK_ALIGNMENT(short, 2);
CHECK_ALIGNMENT(int, 4);
CHECK_ALIGNMENT(long, 8);
CHECK_ALIGNMENT(float, 4);
CHECK_ALIGNMENT(double, 8);
CHECK_ALIGNMENT(long_double, 16);
CHECK_ALIGNMENT(Pointer, 8);
CHECK_ALIGNMENT(FunctionPointer, 8);
CHECK_ALIGNMENT(long_long, 8);
CHECK_ALIGNMENT(struct stat, 8);
CHECK_ALIGNMENT(struct dirent, 8);
CHECK_ALIGNMENT(struct timeval, 8);
CHECK_ALIGNMENT(struct timespec, 8);
}
int AssertMemcmp(const char* name, unsigned char* p1, unsigned char* p2, int n) {
int i;
if (0 == memcmp(p1, p2, n)) {
return 0;
}
printf("ERROR: bad bitfield contents for %s\n", name);
printf("%-10s: ", "actual");
for (i = 0; i < n; ++i) {
printf(" %02x", p1[i]);
}
printf("\n");
printf("%-10s: ", "expected");
for (i = 0; i < n; ++i) {
printf(" %02x", p2[i]);
}
printf("\n");
return 1;
}
#define CHECK_BITFIELD(s1, s2, s3, v1, v2, v3, n, s) do { \
typedef struct { unsigned f1: s1; unsigned f2: s2; unsigned f3: s3; } BF; \
const char* name = #s1 ":" #s2 ":" #s3 "::" #v1 ":" #v2 ":" #v3; \
BF bf; \
memset(&bf, 0, sizeof(BF)); \
bf.f1 = v1; bf.f2 = v2; bf.f3 = v3; \
EXPECT_EQ(sizeof(bf), (size_t)n) << "unexpected bitfield size"; \
EXPECT_EQ(AssertMemcmp(name, (unsigned char *)&bf, (unsigned char *)s, n), 0); \
} while(0)
TEST_F(AbiTests, CheckBitfields) {
CHECK_BITFIELD(1, 1, 1, 0, 0, 1, 4,
"\x04\0\0\0");
CHECK_BITFIELD(2, 2, 2, 1, 2, 3, 4,
"\x39\0\0\0");
CHECK_BITFIELD(3, 3, 3, 1, 2, 7, 4,
"\xd1\x01\0\0");
CHECK_BITFIELD(7, 7, 7, 1, 2, 3, 4,
"\x01\xc1\0\0");
CHECK_BITFIELD(11, 11, 11, 1, 2, 3, 8,
"\x01\x10\x00\x00\x03\x00\x00\x00");
CHECK_BITFIELD(31, 31, 31, 1, 2, 3, 12,
"\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00");
}