Compare commits

...

7 Commits

Author SHA1 Message Date
Marko Semet 8e9e45d8ee widl: support optional output for random state debugging
Signed-off-by: Marko Semet <marko@marko10-000.de>
2020-06-23 21:25:00 +02:00
Marko Semet 0b12b506b8 winebuild: support optional output for random state debugging
Signed-off-by: Marko Semet <marko@marko10-000.de>
2020-06-23 21:25:00 +02:00
Marko Semet f89d0be910 winegcc: support optional output for random state debugging
Signed-off-by: Marko Semet <marko@marko10-000.de>
2020-06-23 21:25:00 +02:00
Marko Semet 343032494a widl: generate deterministic temporary filenames
Using xorshift* as pseudorandom number generator. It get initialised
with the environment (sorted by name) and arguments.

Signed-off-by: Marko Semet <marko@marko10-000.de>
2020-06-23 21:25:00 +02:00
Marko Semet 89ccf6055d widl: use 'SOURCE_DATA_EPOCH' besides 'WIDL_TIME_OVERRIDE'
Helps to support reproducible builds.

Signed-off-by: Marko Semet <marko@marko10-000.de>
2020-06-23 21:25:00 +02:00
Marko Semet f2d9cae0f1 winebuild: generate deterministic temporary filenames
Using xorshift* as pseudorandom number generator. It get initialised
with the environment (sorted by name) and arguments.

Signed-off-by: Marko Semet <marko@marko10-000.de>
2020-06-23 21:25:00 +02:00
Marko Semet 60eed6ef13 winegcc: generate deterministic temporary filenames
Using xorshift* as pseudorandom number generator. It get initialised
with the environment (sorted by name) and arguments.

Signed-off-by: Marko Semet <marko@marko10-000.de>
2020-06-23 21:25:00 +02:00
11 changed files with 595 additions and 9 deletions

View File

@ -543,7 +543,7 @@ int do_import(char *fname)
line_number = 1;
name = xstrdup( "widl.XXXXXX" );
if((fd = mkstemps( name, 0 )) == -1)
if((fd = pseudorandom_tempfile(name)) == -1)
error("Could not generate a temp name from %s\n", name);
temp_name = name;
@ -584,7 +584,7 @@ static void switch_to_acf(void)
line_number = 1;
name = xstrdup( "widl.XXXXXX" );
if((fd = mkstemps( name, 0 )) == -1)
if((fd = pseudorandom_tempfile(name)) == -1)
error("Could not generate a temp name from %s\n", name);
temp_name = name;

View File

@ -474,3 +474,187 @@ void align_output( unsigned int align )
memset( output_buffer + output_buffer_pos, 0, size );
output_buffer_pos += size;
}
/* xorshift* random generator. Source: https://en.wikipedia.org/wiki/Xorshift#xorshift* */
static uint64_t pseudorandom_state = 1;
static const char* pseudorandom_source = NULL;
static size_t pseudorandom_source_size = 0;
static uint64_t pseudorandom_algo(uint64_t* generator_state, uint64_t add_to_state)
{
uint64_t tmp = (*generator_state) + add_to_state;
tmp ^= tmp >> 12;
tmp ^= tmp << 25;
tmp ^= tmp >> 27;
(*generator_state) = tmp;
return tmp * UINT64_C(0x2545F4914F6CDD1D);
}
uint64_t pseudorandom(uint64_t add_to_state)
{
return pseudorandom_algo(&pseudorandom_state, add_to_state);
}
char pseudorandom_char(void)
{
char tmp;
tmp = (char) (pseudorandom(0) % 62);
if (tmp < 10)
{
return '0' + tmp;
}
else if (tmp < 36)
{
return 'A' + (tmp - 10);
}
else
{
return 'a' + (tmp - 36);
}
}
int pseudorandom_tempfile(char* file)
{
/* variables */
int result;
int counter;
char *filename_pos;
char *debug_filename;
FILE *debug_file;
/* replaces Xs */
for (filename_pos = file; (*filename_pos) != 0; filename_pos++)
{
if ((*filename_pos) == 'X')
{
(*filename_pos) = pseudorandom_char();
}
}
/* try to open file */
counter = 0;
do
{
result = open(file, O_CREAT | O_EXCL | O_RDWR, 0600);
if (result != -1)
{
break;
}
sleep(5);
counter++;
} while (counter <= 12);
/* add deebug info */
if ((result != -1) && (getenv("SOURCE_RANDOM_DEBUG") != NULL))
{
debug_filename = strmake("%s.random_debug", file);
debug_file = fopen(debug_filename, "wb");
fwrite(pseudorandom_source, 1, pseudorandom_source_size, debug_file);
fclose(debug_file);
free(debug_filename);
}
return result;
}
void init_random_generator(int argc, char **argv)
{
/* variables */
uint64_t generator_state;
void *argv_data;
size_t argv_size;
unsigned int counter;
void *env_data;
size_t env_size;
char **tmp_envs;
char *buffer_pos;
char **env;
size_t length;
unsigned int i;
size_t j;
/* process environment */
generator_state = 1;
env_size = 0;
{
/* sort environment variables */
counter = 0;
for (env = environ; (*env) != NULL; env++)
{
counter++;
env_size += strlen(*env) + 1;
}
tmp_envs = (char**) malloc(sizeof(char*) * counter);
for (i = 0; i < counter; i++)
{
tmp_envs[i] = (char*) (environ[i]);
}
qsort(tmp_envs, counter, sizeof(char*), (int(*)(const void*, const void*)) &strcmp);
/* and copy them */
env_data = malloc(env_size * sizeof(char));
buffer_pos = env_data;
for (i = 0; i < counter; i++)
{
length = strlen(tmp_envs[i]) + 1;
memcpy(buffer_pos, tmp_envs[i], length);
buffer_pos += length;
}
/* add sorted environment to random generator */
for (j = 0; j < env_size; j++)
{
pseudorandom_algo(&generator_state, ((unsigned char*) env_data)[j]);
}
/* free temp environment */
free(tmp_envs);
}
/* copy argv */
argv_size = 0;
for (i = 0; i < argc; i++)
{
argv_size += strlen(argv[i]) + 1;
}
argv_data = malloc(sizeof(char) * argv_size);
buffer_pos = argv_data;
for (i = 0; i < argc; i++)
{
length = strlen(argv[i]) + 1;
memcpy(buffer_pos, argv[i], length);
buffer_pos += length;
}
/* add arguments to gnerator */
for (j = 0; j < argv_size; j++)
{
pseudorandom_algo(&generator_state, ((unsigned char*) argv_data)[j]);
}
/* add debug if required */
if (getenv("SOURCE_RANDOM_DEBUG") != NULL)
{
/* gen field */
pseudorandom_source_size = env_size + argv_size + sizeof(generator_state);
buffer_pos = malloc(sizeof(char) * pseudorandom_source_size);
pseudorandom_source = buffer_pos;
/* copy data into it */
memcpy(buffer_pos, env_data, env_size);
buffer_pos += env_size;
memcpy(buffer_pos, argv_data, argv_size);
buffer_pos += argv_size;
memcpy(buffer_pos, &generator_state, sizeof(generator_state));
}
/* set state and free rest */
free(env_data);
free(argv_data);
pseudorandom_state = generator_state;
}

View File

@ -24,6 +24,7 @@
#include "widltypes.h"
#include <stddef.h> /* size_t */
#include <stdint.h>
void *xmalloc(size_t);
void *xrealloc(void *, size_t);
@ -72,6 +73,11 @@ extern void put_pword( unsigned int val );
extern void put_str( int indent, const char *format, ... ) __attribute__((format (printf, 2, 3)));
extern void align_output( unsigned int align );
extern uint64_t pseudorandom(uint64_t add_to_state);
extern char pseudorandom_char(void);
extern int pseudorandom_tempfile(char* file);
extern void init_random_generator(int argc, char **argv);
/* typelibs expect the minor version to be stored in the higher bits and
* major to be stored in the lower bits */
#define MAKEVERSION(major, minor) ((((minor) & 0xffff) << 16) | ((major) & 0xffff))

View File

@ -607,9 +607,20 @@ int main(int argc,char *argv[])
#ifdef SIGHUP
signal( SIGHUP, exit_on_signal );
#endif
init_random_generator(argc, argv);
init_argv0_dir( argv[0] );
now = time(NULL);
{
const char* source_time = getenv("SOURCE_DATE_EPOCH");
if (source_time == NULL)
{
now = time(NULL);
}
else
{
now = atol(source_time);
}
}
while((optc = getopt_long_only(argc, argv, short_options, long_options, &opti)) != EOF) {
switch(optc) {
@ -938,7 +949,7 @@ int main(int argc,char *argv[])
strcpy( name, header_name );
strcat( name, ".XXXXXX" );
if ((fd = mkstemps( name, 0 )) == -1)
if ((fd = pseudorandom_tempfile(name)) == -1)
error("Could not generate a temp name from %s\n", name);
temp_name = name;

View File

@ -2747,8 +2747,10 @@ int create_msft_typelib(typelib_t *typelib)
/* midl adds two sets of custom data to the library: the current unix time
and midl's version number */
time_override = getenv( "WIDL_TIME_OVERRIDE");
time_override = getenv("SOURCE_DATE_EPOCH");
cur_time = time_override ? atol( time_override) : time(NULL);
time_override = getenv( "WIDL_TIME_OVERRIDE");
cur_time = time_override ? atol( time_override) : cur_time;
sprintf(info_string, "Created by WIDL version %s at %s\n", PACKAGE_VERSION, ctime(&cur_time));
set_custdata(msft, &midl_info_guid, VT_BSTR, info_string, &msft->typelib_header.CustomDataOffset);
set_custdata(msft, &midl_time_guid, VT_UI4, &cur_time, &msft->typelib_header.CustomDataOffset);

View File

@ -27,6 +27,7 @@
# error You must include config.h to use this header
#endif
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -352,6 +353,11 @@ extern void put_qword( unsigned int val );
extern void put_pword( unsigned int val );
extern void align_output( unsigned int align );
extern uint64_t pseudorandom(uint64_t add_to_state);
extern char pseudorandom_char(void);
extern int pseudorandom_tempfile(char* file);
extern void init_random_generator(int argc, char **argv);
/* global variables */
extern int current_line;

View File

@ -666,6 +666,7 @@ int main(int argc, char **argv)
signal( SIGTERM, exit_on_signal );
signal( SIGINT, exit_on_signal );
init_random_generator(argc, argv);
argv = parse_options( argc, argv, spec );
atexit( cleanup ); /* make sure we remove the output file on exit */

View File

@ -514,13 +514,13 @@ char *get_temp_file_name( const char *prefix, const char *suffix )
strcpy( name + (ext - prefix), ".XXXXXX" );
strcat( name, suffix );
if ((fd = mkstemps( name, strlen(suffix) )) == -1)
if ((fd = pseudorandom_tempfile(name)) == -1)
{
strcpy( name, "/tmp/" );
memcpy( name + 5, basename, ext - basename );
strcpy( name + 5 + (ext - basename), ".XXXXXX" );
strcat( name, suffix );
if ((fd = mkstemps( name, strlen(suffix) )) == -1)
if ((fd = pseudorandom_tempfile(name)) == -1)
fatal_error( "could not generate a temp file\n" );
}
@ -1275,3 +1275,187 @@ const char *get_asm_string_section(void)
default: return ".section .rodata";
}
}
/* xorshift* random generator. Source: https://en.wikipedia.org/wiki/Xorshift#xorshift* */
static uint64_t pseudorandom_state = 1;
static const char* pseudorandom_source = NULL;
static size_t pseudorandom_source_size = 0;
static uint64_t pseudorandom_algo(uint64_t* generator_state, uint64_t add_to_state)
{
uint64_t tmp = (*generator_state) + add_to_state;
tmp ^= tmp >> 12;
tmp ^= tmp << 25;
tmp ^= tmp >> 27;
(*generator_state) = tmp;
return tmp * UINT64_C(0x2545F4914F6CDD1D);
}
uint64_t pseudorandom(uint64_t add_to_state)
{
return pseudorandom_algo(&pseudorandom_state, add_to_state);
}
char pseudorandom_char(void)
{
char tmp;
tmp = (char) (pseudorandom(0) % 62);
if (tmp < 10)
{
return '0' + tmp;
}
else if (tmp < 36)
{
return 'A' + (tmp - 10);
}
else
{
return 'a' + (tmp - 36);
}
}
int pseudorandom_tempfile(char* file)
{
/* variables */
int result;
int counter;
char *filename_pos;
char *debug_filename;
FILE *debug_file;
/* replaces Xs */
for (filename_pos = file; (*filename_pos) != 0; filename_pos++)
{
if ((*filename_pos) == 'X')
{
(*filename_pos) = pseudorandom_char();
}
}
/* try to open file */
counter = 0;
do
{
result = open(file, O_CREAT | O_EXCL | O_RDWR, 0600);
if (result != -1)
{
break;
}
sleep(5);
counter++;
} while (counter <= 12);
/* add deebug info */
if ((result != -1) && (getenv("SOURCE_RANDOM_DEBUG") != NULL))
{
debug_filename = strmake("%s.random_debug", file);
debug_file = fopen(debug_filename, "wb");
fwrite(pseudorandom_source, 1, pseudorandom_source_size, debug_file);
fclose(debug_file);
free(debug_filename);
}
return result;
}
void init_random_generator(int argc, char **argv)
{
/* variables */
uint64_t generator_state;
void *argv_data;
size_t argv_size;
unsigned int counter;
void *env_data;
size_t env_size;
char **tmp_envs;
char *buffer_pos;
char **env;
size_t length;
unsigned int i;
size_t j;
/* process environment */
generator_state = 1;
env_size = 0;
{
/* sort environment variables */
counter = 0;
for (env = environ; (*env) != NULL; env++)
{
counter++;
env_size += strlen(*env) + 1;
}
tmp_envs = (char**) malloc(sizeof(char*) * counter);
for (i = 0; i < counter; i++)
{
tmp_envs[i] = (char*) (environ[i]);
}
qsort(tmp_envs, counter, sizeof(char*), (int(*)(const void*, const void*)) &strcmp);
/* and copy them */
env_data = malloc(env_size * sizeof(char));
buffer_pos = env_data;
for (i = 0; i < counter; i++)
{
length = strlen(tmp_envs[i]) + 1;
memcpy(buffer_pos, tmp_envs[i], length);
buffer_pos += length;
}
/* add sorted environment to random generator */
for (j = 0; j < env_size; j++)
{
pseudorandom_algo(&generator_state, ((unsigned char*) env_data)[j]);
}
/* free temp environment */
free(tmp_envs);
}
/* copy argv */
argv_size = 0;
for (i = 0; i < argc; i++)
{
argv_size += strlen(argv[i]) + 1;
}
argv_data = malloc(sizeof(char) * argv_size);
buffer_pos = argv_data;
for (i = 0; i < argc; i++)
{
length = strlen(argv[i]) + 1;
memcpy(buffer_pos, argv[i], length);
buffer_pos += length;
}
/* add arguments to gnerator */
for (j = 0; j < argv_size; j++)
{
pseudorandom_algo(&generator_state, ((unsigned char*) argv_data)[j]);
}
/* add debug if required */
if (getenv("SOURCE_RANDOM_DEBUG") != NULL)
{
/* gen field */
pseudorandom_source_size = env_size + argv_size + sizeof(generator_state);
buffer_pos = malloc(sizeof(char) * pseudorandom_source_size);
pseudorandom_source = buffer_pos;
/* copy data into it */
memcpy(buffer_pos, env_data, env_size);
buffer_pos += env_size;
memcpy(buffer_pos, argv_data, argv_size);
buffer_pos += argv_size;
memcpy(buffer_pos, &generator_state, sizeof(generator_state));
}
/* set state and free rest */
free(env_data);
free(argv_data);
pseudorandom_state = generator_state;
}

View File

@ -384,3 +384,187 @@ int spawn(const strarray* prefix, const strarray* args, int ignore_errors)
strarray_free(arr);
return status;
}
/* xorshift* random generator. Source: https://en.wikipedia.org/wiki/Xorshift#xorshift* */
static uint64_t pseudorandom_state = 1;
static const char* pseudorandom_source = NULL;
static size_t pseudorandom_source_size = 0;
static uint64_t pseudorandom_algo(uint64_t* generator_state, uint64_t add_to_state)
{
uint64_t tmp = (*generator_state) + add_to_state;
tmp ^= tmp >> 12;
tmp ^= tmp << 25;
tmp ^= tmp >> 27;
(*generator_state) = tmp;
return tmp * UINT64_C(0x2545F4914F6CDD1D);
}
uint64_t pseudorandom(uint64_t add_to_state)
{
return pseudorandom_algo(&pseudorandom_state, add_to_state);
}
char pseudorandom_char(void)
{
char tmp;
tmp = (char) (pseudorandom(0) % 62);
if (tmp < 10)
{
return '0' + tmp;
}
else if (tmp < 36)
{
return 'A' + (tmp - 10);
}
else
{
return 'a' + (tmp - 36);
}
}
int pseudorandom_tempfile(char* file)
{
/* variables */
int result;
int counter;
char *filename_pos;
char *debug_filename;
FILE *debug_file;
/* replaces Xs */
for (filename_pos = file; (*filename_pos) != 0; filename_pos++)
{
if ((*filename_pos) == 'X')
{
(*filename_pos) = pseudorandom_char();
}
}
/* try to open file */
counter = 0;
do
{
result = open(file, O_CREAT | O_EXCL | O_RDWR, 0600);
if (result != -1)
{
break;
}
sleep(5);
counter++;
} while (counter <= 12);
/* add deebug info */
if ((result != -1) && (getenv("SOURCE_RANDOM_DEBUG") != NULL))
{
debug_filename = strmake("%s.random_debug", file);
debug_file = fopen(debug_filename, "wb");
fwrite(pseudorandom_source, 1, pseudorandom_source_size, debug_file);
fclose(debug_file);
free(debug_filename);
}
return result;
}
void init_random_generator(int argc, char **argv)
{
/* variables */
uint64_t generator_state;
void *argv_data;
size_t argv_size;
unsigned int counter;
void *env_data;
size_t env_size;
char **tmp_envs;
char *buffer_pos;
char **env;
size_t length;
unsigned int i;
size_t j;
/* process environment */
generator_state = 1;
env_size = 0;
{
/* sort environment variables */
counter = 0;
for (env = environ; (*env) != NULL; env++)
{
counter++;
env_size += strlen(*env) + 1;
}
tmp_envs = (char**) malloc(sizeof(char*) * counter);
for (i = 0; i < counter; i++)
{
tmp_envs[i] = (char*) (environ[i]);
}
qsort(tmp_envs, counter, sizeof(char*), (int(*)(const void*, const void*)) &strcmp);
/* and copy them */
env_data = malloc(env_size * sizeof(char));
buffer_pos = env_data;
for (i = 0; i < counter; i++)
{
length = strlen(tmp_envs[i]) + 1;
memcpy(buffer_pos, tmp_envs[i], length);
buffer_pos += length;
}
/* add sorted environment to random generator */
for (j = 0; j < env_size; j++)
{
pseudorandom_algo(&generator_state, ((unsigned char*) env_data)[j]);
}
/* free temp environment */
free(tmp_envs);
}
/* copy argv */
argv_size = 0;
for (i = 0; i < argc; i++)
{
argv_size += strlen(argv[i]) + 1;
}
argv_data = malloc(sizeof(char) * argv_size);
buffer_pos = argv_data;
for (i = 0; i < argc; i++)
{
length = strlen(argv[i]) + 1;
memcpy(buffer_pos, argv[i], length);
buffer_pos += length;
}
/* add arguments to gnerator */
for (j = 0; j < argv_size; j++)
{
pseudorandom_algo(&generator_state, ((unsigned char*) argv_data)[j]);
}
/* add debug if required */
if (getenv("SOURCE_RANDOM_DEBUG") != NULL)
{
/* gen field */
pseudorandom_source_size = env_size + argv_size + sizeof(generator_state);
buffer_pos = malloc(sizeof(char) * pseudorandom_source_size);
pseudorandom_source = buffer_pos;
/* copy data into it */
memcpy(buffer_pos, env_data, env_size);
buffer_pos += env_size;
memcpy(buffer_pos, argv_data, argv_size);
buffer_pos += argv_size;
memcpy(buffer_pos, &generator_state, sizeof(generator_state));
}
/* set state and free rest */
free(env_data);
free(argv_data);
pseudorandom_state = generator_state;
}

View File

@ -25,6 +25,8 @@
#define __attribute__(X)
#endif
#include <stdint.h>
#ifndef DECLSPEC_NORETURN
# if defined(_MSC_VER) && (_MSC_VER >= 1200) && !defined(MIDL_PASS)
# define DECLSPEC_NORETURN __declspec(noreturn)
@ -90,3 +92,8 @@ const char *find_binary( const strarray* prefix, const char *name );
int spawn(const strarray* prefix, const strarray* arr, int ignore_errors);
extern int verbose;
uint64_t pseudorandom(uint64_t add_to_state);
char pseudorandom_char(void);
int pseudorandom_tempfile(char* file);
void init_random_generator(int argc, char **argv);

View File

@ -299,7 +299,7 @@ static char* get_temp_file(const char* prefix, const char* suffix)
/* block signals while manipulating the temp files list */
sigprocmask( SIG_BLOCK, &signal_mask, &old_set );
#endif
fd = mkstemps( tmp, strlen(suffix) );
fd = pseudorandom_tempfile(tmp);
if (fd == -1)
{
/* could not create it in current directory, try in TMPDIR */
@ -308,7 +308,7 @@ static char* get_temp_file(const char* prefix, const char* suffix)
free(tmp);
if (!(tmpdir = getenv("TMPDIR"))) tmpdir = "/tmp";
tmp = strmake("%s/%s-XXXXXX%s", tmpdir, prefix, suffix);
fd = mkstemps( tmp, strlen(suffix) );
fd = pseudorandom_tempfile(tmp);
if (fd == -1) error( "could not create temp file\n" );
}
close( fd );
@ -1603,6 +1603,7 @@ int main(int argc, char **argv)
sigaddset( &signal_mask, SIGTERM );
sigaddset( &signal_mask, SIGINT );
#endif
init_random_generator(argc, argv);
init_argv0_dir( argv[0] );
/* setup tmp file removal at exit */