forked from Mirrors/wine-wine
widl: add pseudo random build file generation
Signed-off-by: Marko Semet <marko@marko10-000.de>feature/deterministic
parent
d361a52e51
commit
9162745496
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -607,6 +607,7 @@ int main(int argc,char *argv[])
|
|||
#ifdef SIGHUP
|
||||
signal( SIGHUP, exit_on_signal );
|
||||
#endif
|
||||
init_random_generator(argc, argv);
|
||||
init_argv0_dir( argv[0] );
|
||||
|
||||
{
|
||||
|
@ -948,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;
|
||||
|
|
Loading…
Reference in New Issue