liveness-sweep.c 16.6 KB
Newer Older
Julian Kranz's avatar
Julian Kranz committed
1 2 3 4 5
/* vim:cindent:ts=2:sw=2:expandtab */

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
Julian Kranz's avatar
Julian Kranz committed
6 7
#include <getopt.h>
#include <unistd.h>
Julian Kranz's avatar
---  
Julian Kranz committed
8
#include <gdsl.h>
Julian Kranz's avatar
Julian Kranz committed
9 10
#include <sys/resource.h>

Julian Kranz's avatar
Julian Kranz committed
11 12 13 14 15 16
#include <err.h>
#include <fcntl.h>
#include <gelf.h>
#include <string.h>
#include <sysexits.h>

Julian Kranz's avatar
Julian Kranz committed
17 18
#include <time.h>

Julian Kranz's avatar
AVR  
Julian Kranz committed
19 20
#define NANOS 1000000000LL

Julian Kranz's avatar
Julian Kranz committed
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
char elf_section_boundary_get(char *path, size_t *offset, size_t *size) {
	char retval = 0;

	int fd = open(path, O_RDONLY);
	if(!fd) {
		retval = 8;
		goto end_0;
	}

	if(elf_version(EV_CURRENT) == EV_NONE) {
		retval = 2;
		goto end_0;
	}

	Elf *e = elf_begin(fd, ELF_C_READ, NULL);
	if(!e) {
		retval = 3;
		goto end_0;
	}

	if(elf_kind(e) != ELF_K_ELF) {
		retval = 4;
		goto end_1;
	}

	size_t shstrndx;
	if(elf_getshdrstrndx(e, &shstrndx) != 0) {
		retval = 5;
		goto end_1;
	}

	Elf_Scn *scn = NULL;

	char found = 0;
Julian Kranz's avatar
Julian Kranz committed
55
	while((scn = elf_nextscn(e, scn)) != NULL) {
Julian Kranz's avatar
Julian Kranz committed
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
		GElf_Shdr shdr;
		if(gelf_getshdr(scn, &shdr) != &shdr) {
			retval = 6;
			goto end_1;
		}

		char *name = elf_strptr(e, shstrndx, shdr.sh_name);
		if(!name) {
			retval = 7;
			goto end_1;
		}
		if(!strcmp(name, ".text")) {
			*offset = shdr.sh_offset;
			*size = shdr.sh_size;
			found = 1;
			break;
		}
//		printf("%s - %zu:%zu\n", name, shdr.sh_offset, shdr.sh_size);
	}

	if(!found)
		retval = 1;

	end_1: elf_end(e);

	end_0: close(fd);

	return retval;
}

Julian Kranz's avatar
Julian Kranz committed
86
enum p_option {
Julian Kranz's avatar
Julian Kranz committed
87
	OPTION_ELF, OPTION_OFFSET, OPTION_SINGLE, OPTION_CHILDREN, OPTION_FILE, OPTION_CLEANUP, OPTION_LATEX
Julian Kranz's avatar
Julian Kranz committed
88 89 90 91
};

enum mode {
	MODE_SINGLE, MODE_DEFAULT, MODE_CHILDREN
Julian Kranz's avatar
Julian Kranz committed
92 93 94 95 96
};

struct options {
	char elf;
	size_t offset;
Julian Kranz's avatar
Julian Kranz committed
97
	enum mode mode;
Julian Kranz's avatar
Julian Kranz committed
98 99 100
	char **files;
	size_t files_size;
	size_t files_length;
Julian Kranz's avatar
Julian Kranz committed
101
	char cleanup;
Julian Kranz's avatar
Julian Kranz committed
102
	char latex;
Julian Kranz's avatar
Julian Kranz committed
103 104 105 106 107
};

static char args_parse(int argc, char **argv, struct options *options) {
	options->elf = 0;
	options->offset = 0;
Julian Kranz's avatar
Julian Kranz committed
108
	options->mode = MODE_DEFAULT;
Julian Kranz's avatar
Julian Kranz committed
109 110 111
	options->files_size = 8;
	options->files = (char**)malloc(sizeof(char*) * options->files_size);
	options->files_length = 0;
Julian Kranz's avatar
Julian Kranz committed
112
	options->cleanup = 0;
Julian Kranz's avatar
Julian Kranz committed
113
	options->latex = 0;
Julian Kranz's avatar
Julian Kranz committed
114

Julian Kranz's avatar
Julian Kranz committed
115 116 117 118 119
	struct option long_options[] = { { "elf", no_argument, NULL, OPTION_ELF }, { "offset", required_argument, NULL,
			OPTION_OFFSET }, { "children",
	no_argument, NULL, OPTION_CHILDREN }, { "single", no_argument, NULL, OPTION_SINGLE }, { "file", required_argument,
	NULL, OPTION_FILE }, { "cleanup", no_argument, NULL, OPTION_CLEANUP }, { "latex", no_argument,
	NULL, OPTION_LATEX }, { 0, 0, 0, 0 }, };
Julian Kranz's avatar
Julian Kranz committed
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134

	while(1) {
		int result = getopt_long(argc, argv, "", long_options, NULL);
		if(result < 0)
			break;
		switch(result) {
			case OPTION_ELF: {
				options->elf = 1;
				break;
			}
			case OPTION_OFFSET: {
				sscanf(optarg, "%lu", &options->offset);
				break;
			}
			case OPTION_CHILDREN: {
Julian Kranz's avatar
Julian Kranz committed
135 136 137 138 139
				options->mode = MODE_CHILDREN;
				break;
			}
			case OPTION_SINGLE: {
				options->mode = MODE_SINGLE;
Julian Kranz's avatar
Julian Kranz committed
140 141
				break;
			}
Julian Kranz's avatar
Julian Kranz committed
142 143 144 145
			case OPTION_LATEX: {
				options->latex = 1;
				break;
			}
Julian Kranz's avatar
Julian Kranz committed
146
			case OPTION_FILE: {
Julian Kranz's avatar
Julian Kranz committed
147 148
				if(options->files_length == options->files_size) {
					options->files_size <<= 1;
Julian Kranz's avatar
Julian Kranz committed
149
					options->files = (char**)realloc(options->files, sizeof(char*) * options->files_size);
Julian Kranz's avatar
Julian Kranz committed
150 151
				}
				options->files[options->files_length++] = optarg;
Julian Kranz's avatar
Julian Kranz committed
152 153
				break;
			}
Julian Kranz's avatar
Julian Kranz committed
154 155 156 157
			case OPTION_CLEANUP: {
				options->cleanup = 1;
				break;
			}
Julian Kranz's avatar
Julian Kranz committed
158 159 160 161 162
			case '?':
				return 2;
		}
	}

Julian Kranz's avatar
Julian Kranz committed
163
	if(!options->files_length)
Julian Kranz's avatar
Julian Kranz committed
164 165 166 167 168
		return 1;

	return 0;
}

Julian Kranz's avatar
---  
Julian Kranz committed
169
obj_t translate_single(state_t state) {
Julian Kranz's avatar
---  
Julian Kranz committed
170
	if(setjmp(*gdsl_err_tgt(state)))
Julian Kranz's avatar
Julian Kranz committed
171
		return NULL;
Julian Kranz's avatar
Julian Kranz committed
172
	obj_t rreil_insns = gdsl_translateSingle(state, gdsl_config_default(state));
Julian Kranz's avatar
Julian Kranz committed
173 174 175
	return rreil_insns;
}

Julian Kranz's avatar
---  
Julian Kranz committed
176
obj_t translate(state_t state) {
Julian Kranz's avatar
---  
Julian Kranz committed
177
	if(setjmp(*gdsl_err_tgt(state)))
Julian Kranz's avatar
Julian Kranz committed
178
		return NULL;
Julian Kranz's avatar
Julian Kranz committed
179
	obj_t rreil_insns = gdsl_translateBlock(state, gdsl_config_default(state));
Julian Kranz's avatar
Julian Kranz committed
180 181 182
	return rreil_insns;
}

Julian Kranz's avatar
AVR  
Julian Kranz committed
183
translate_result_t translate_super(state_t state, obj_t *rreil_insns) {
Julian Kranz's avatar
---  
Julian Kranz committed
184
	if(setjmp(*gdsl_err_tgt(state)))
Julian Kranz's avatar
Julian Kranz committed
185
		return NULL;
Julian Kranz's avatar
Julian Kranz committed
186
	translate_result_t rreil_insns_succs = gdsl_translateSuperBlock(state, gdsl_config_default(state));
Julian Kranz's avatar
AVR  
Julian Kranz committed
187
	*rreil_insns = rreil_insns_succs->insns;
Julian Kranz's avatar
Julian Kranz committed
188 189 190
	return rreil_insns_succs;
}

Julian Kranz's avatar
AVR  
Julian Kranz committed
191 192 193
void print_succs(state_t state, translate_result_t translated, size_t size) {
	obj_t succ_a = translated->succ_a;
	obj_t succ_b = translated->succ_b;
Julian Kranz's avatar
Julian Kranz committed
194

Julian Kranz's avatar
---  
Julian Kranz committed
195 196 197 198 199
//	void print_succ(obj_t succ, char const *name) {
//		switch(x86_con_index(state, succ)) {
//			case __SO_SOME: {
//				obj_t succ_insns = __DECON(succ);
//				printf("Succ %s:\n", name);
Julian Kranz's avatar
---  
Julian Kranz committed
200
//				string_t fmt = gdsl_rreil_pretty(state, succ_insns);
Julian Kranz's avatar
---  
Julian Kranz committed
201 202 203 204 205 206 207 208 209 210
//				puts(fmt);
//				break;
//			}
//			case __SO_NONE: {
//				printf("Succ %s: __SO_NONE :-(\n", name);
//				break;
//			}
//		}
//	}

Julian Kranz's avatar
Ropes  
Julian Kranz committed
211
	string_t r = gdsl_merge_rope(state, gdsl_succ_pretty(state, succ_a, "a"));
Julian Kranz's avatar
---  
Julian Kranz committed
212 213
	printf("%s", r);

Julian Kranz's avatar
Ropes  
Julian Kranz committed
214
	r = gdsl_merge_rope(state, gdsl_succ_pretty(state, succ_b, "b"));
Julian Kranz's avatar
---  
Julian Kranz committed
215
	printf("%s", r);
Julian Kranz's avatar
Julian Kranz committed
216

Julian Kranz's avatar
---  
Julian Kranz committed
217 218
//	print_succ(succ_a, "a");
//	print_succ(succ_b, "b");
Julian Kranz's avatar
Julian Kranz committed
219 220
}

Julian Kranz's avatar
Julian Kranz committed
221 222 223 224 225 226 227
struct context {
	size_t native_instructions;
	size_t lines;
	size_t lines_opt;
	long time_non_opt;
	long time_opt;
};
Julian Kranz's avatar
Julian Kranz committed
228

Julian Kranz's avatar
Julian Kranz committed
229 230 231 232 233
void print_results(struct context *context) {
	printf("Statistics:\n");
	printf("Number of native instructions: %zu\n", context->native_instructions);
	printf("Number of lines without LV analysis: %zu\n", context->lines);
	printf("Number of lines with LV analysis: %zu\n", context->lines_opt);
Julian Kranz's avatar
Julian Kranz committed
234

Julian Kranz's avatar
Julian Kranz committed
235
	double reduction = 1 - (context->lines_opt / (double)context->lines);
Julian Kranz's avatar
Julian Kranz committed
236

Julian Kranz's avatar
Julian Kranz committed
237
	printf("Reduction: %lf%%\n", 100 * reduction);
Julian Kranz's avatar
Julian Kranz committed
238

Julian Kranz's avatar
Julian Kranz committed
239
	printf("Time needed for the decoding and the translation to RREIL: %lf seconds\n",
Julian Kranz's avatar
AVR  
Julian Kranz committed
240 241
			context->time_non_opt / (double)(NANOS));
	printf("Time needed for the lv analysis: %lf seconds\n", context->time_opt / (double)(NANOS));
Julian Kranz's avatar
Julian Kranz committed
242 243 244 245
}

static char *symbol_sz(size_t value) {
	if(value < 10 * 1000)
Julian Kranz's avatar
---  
Julian Kranz committed
246
		return "";
Julian Kranz's avatar
Julian Kranz committed
247
	if(value < 10 * 1000 * 1000)
Julian Kranz's avatar
---  
Julian Kranz committed
248
		return "";
Julian Kranz's avatar
Julian Kranz committed
249 250 251 252 253 254 255 256 257
	return "M";
}

static size_t fit_sz(size_t value) {
	if(value < 10 * 1000)
		return (value + 500) / 1000;
	if(value < 10 * 1000 * 1000)
		return (value + 500) / 1000;
	return (value + 500 * 1000) / (1000 * 1000);
Julian Kranz's avatar
Julian Kranz committed
258
}
Julian Kranz's avatar
Julian Kranz committed
259

Julian Kranz's avatar
Julian Kranz committed
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
static char *symbol_t(double value) {
	if(value < 2 * 60)
		return "s";
	if(value < 2 * 60 * 60)
		return "m";
	return "h";
}

static double fit_t(double value) {
	if(value < 2 * 60)
		return value;
	if(value < 2 * 60 * 60)
		return value / 60;
	return value / (60 * 60);
}

void print_results_latex(char *file, struct context *single, struct context *intra, struct context *inter) {
Julian Kranz's avatar
Julian Kranz committed
277
	//netstat & 15k & 86k & 1.10s & 63k & 17.43s & 26.04\% & 53k & 39.98s & 38.51\%
Julian Kranz's avatar
---  
Julian Kranz committed
278
	double reduction_simple = 1 - (single->lines_opt / (double)single->lines);
Julian Kranz's avatar
Julian Kranz committed
279 280
	double reduction_inter = 1 - (inter->lines_opt / (double)inter->lines);
	double reduction_intra = 1 - (intra->lines_opt / (double)intra->lines);
Julian Kranz's avatar
Julian Kranz committed
281

Julian Kranz's avatar
---  
Julian Kranz committed
282 283 284 285 286
	double fac_non = single->lines / (double)single->native_instructions;
	double fac_single = single->lines_opt / (double)single->native_instructions;
	double fac_inta = intra->lines_opt / (double)single->native_instructions;
	double fac_inter = inter->lines_opt / (double)single->native_instructions;

Julian Kranz's avatar
Julian Kranz committed
287 288 289 290 291 292
	size_t file_offset = 0;
	for(size_t i = 0; file[i]; i++) {
		if(file[i] == '/')
			file_offset = i + 1;
	}

Julian Kranz's avatar
Julian Kranz committed
293
	printf(
Julian Kranz's avatar
---  
Julian Kranz committed
294
			"%s & %lu%s & %lu%s & %.1lf%s & %.1lf & %lu%s & %.1lf%s & %.0lf\\%% & %.1f & %lu%s & %.1lf%s & %.0lf\\%% & %.1f & %lu%s & %.1lf%s & %.0lf\\%% & %.1f \\\\\n",
Julian Kranz's avatar
Julian Kranz committed
295
			file + file_offset, fit_sz(inter->native_instructions), symbol_sz(inter->native_instructions),
Julian Kranz's avatar
AVR  
Julian Kranz committed
296 297
			fit_sz(inter->lines), symbol_sz(inter->lines), fit_t(inter->time_non_opt / (double)(NANOS)),
			symbol_t(inter->time_non_opt / (double)(NANOS)), fac_non,
Julian Kranz's avatar
---  
Julian Kranz committed
298

Julian Kranz's avatar
AVR  
Julian Kranz committed
299 300
			fit_sz(single->lines_opt), symbol_sz(single->lines_opt), fit_t(single->time_opt / (double)(NANOS)),
			symbol_t(single->time_opt / (double)(NANOS)), 100 * reduction_simple, fac_single,
Julian Kranz's avatar
---  
Julian Kranz committed
301

Julian Kranz's avatar
AVR  
Julian Kranz committed
302
			fit_sz(intra->lines_opt), symbol_sz(intra->lines_opt), fit_t(intra->time_opt / (double)(NANOS)),
Julian Kranz's avatar
Julian Kranz committed
303
			symbol_t(intra->time_opt / (double)(1000000000)), 100 * reduction_intra, fac_inta,
Julian Kranz's avatar
---  
Julian Kranz committed
304

Julian Kranz's avatar
AVR  
Julian Kranz committed
305 306
			fit_sz(inter->lines_opt), symbol_sz(inter->lines_opt), fit_t(inter->time_opt / (double)(NANOS)),
			symbol_t(inter->time_opt / (double)(NANOS)), 100 * reduction_inter, fac_inter);
Julian Kranz's avatar
Julian Kranz committed
307
}
Julian Kranz's avatar
Julian Kranz committed
308

Julian Kranz's avatar
Julian Kranz committed
309 310
char analyze(char *file, char print, enum mode mode, char cleanup, size_t file_offset, size_t size_max,
		size_t user_offset, struct context *context) {
Julian Kranz's avatar
Julian Kranz committed
311 312
	size_t size = 16 * 1024 * 1024;
	char *fmt = (char*)malloc(size);
Julian Kranz's avatar
Julian Kranz committed
313

Julian Kranz's avatar
Julian Kranz committed
314
	FILE *f = fopen(file, "r");
Julian Kranz's avatar
Julian Kranz committed
315 316 317 318 319
	if(!f) {
		printf("Unable to open file.\n");
		return 1;
	}

Julian Kranz's avatar
Julian Kranz committed
320
	fseek(f, file_offset, SEEK_SET);
Julian Kranz's avatar
Julian Kranz committed
321

Julian Kranz's avatar
Julian Kranz committed
322
	size_t buffer_size = 128;
Julian Kranz's avatar
Julian Kranz committed
323
	unsigned char *buffer = NULL;
Julian Kranz's avatar
Julian Kranz committed
324 325 326
	size_t buffer_length = 0;
	do {
		buffer_size *= 2;
Julian Kranz's avatar
Julian Kranz committed
327
		buffer = (unsigned char*)realloc(buffer, buffer_size);
Julian Kranz's avatar
Julian Kranz committed
328
		buffer_length += fread(buffer + buffer_length, 1, buffer_size - buffer_length, f);
Julian Kranz's avatar
Julian Kranz committed
329
	} while(!feof(f) && (!size_max || buffer_length < size_max));
Julian Kranz's avatar
Julian Kranz committed
330 331

	fclose(f);
Julian Kranz's avatar
Julian Kranz committed
332

Julian Kranz's avatar
Julian Kranz committed
333 334 335 336 337
	//printf("size_max: %lu, buffer_length: %lu\n", size_max, buffer_length);

	if(size_max && buffer_length > size_max)
		buffer_length = size_max;

Julian Kranz's avatar
Julian Kranz committed
338 339
	if(buffer_length == buffer_size) {
		buffer_size++;
Julian Kranz's avatar
Julian Kranz committed
340
		buffer = (unsigned char*)realloc(buffer, buffer_size);
Julian Kranz's avatar
Julian Kranz committed
341
	}
Julian Kranz's avatar
Julian Kranz committed
342
	buffer[buffer_length++] = 0xc3; //Last instruction should be a jump (ret) ;-).
Julian Kranz's avatar
Julian Kranz committed
343

Julian Kranz's avatar
Julian Kranz committed
344 345 346
	struct timespec start;
	struct timespec end;

Julian Kranz's avatar
Julian Kranz committed
347
//	printf("buffer_length=%zu\n", buffer_length);
Julian Kranz's avatar
Julian Kranz committed
348

Julian Kranz's avatar
Julian Kranz committed
349
	uint64_t consumed = user_offset;
Julian Kranz's avatar
Julian Kranz committed
350
//	uint64_t consumed = 228;
Julian Kranz's avatar
Julian Kranz committed
351
//	uint64_t consumed = 0;
Julian Kranz's avatar
Julian Kranz committed
352

Julian Kranz's avatar
---  
Julian Kranz committed
353 354
	obj_t state = gdsl_init();

Julian Kranz's avatar
Julian Kranz committed
355
	gdsl_set_code(state, (char*)buffer, buffer_length, 0);
Julian Kranz's avatar
---  
Julian Kranz committed
356

Julian Kranz's avatar
Julian Kranz committed
357
	while(consumed < buffer_length) {
Julian Kranz's avatar
Julian Kranz committed
358 359
		if(print)
			printf("### Next block (@offset %lu): ###\n\n", consumed);
Julian Kranz's avatar
Julian Kranz committed
360

Julian Kranz's avatar
---  
Julian Kranz committed
361 362
//		obj_t state = __createState(buffer + consumed, buffer_length - consumed,
//				consumed, 0);
Julian Kranz's avatar
---  
Julian Kranz committed
363 364
//		gdsl_set_code(state, buffer + consumed, buffer_length - consumed, 0);
		gdsl_seek(state, consumed);
Julian Kranz's avatar
Julian Kranz committed
365

Julian Kranz's avatar
---  
Julian Kranz committed
366 367
		obj_t translated = NULL;
		obj_t rreil_insns = NULL;
Julian Kranz's avatar
AVR  
Julian Kranz committed
368
		clock_gettime(CLOCK_REALTIME, &start);
Julian Kranz's avatar
Julian Kranz committed
369 370
		switch(mode) {
			case MODE_SINGLE: {
Julian Kranz's avatar
---  
Julian Kranz committed
371
				translated = rreil_insns = translate_single(state);
Julian Kranz's avatar
Julian Kranz committed
372 373 374
				break;
			}
			case MODE_DEFAULT: {
Julian Kranz's avatar
---  
Julian Kranz committed
375
				translated = rreil_insns = translate(state);
Julian Kranz's avatar
Julian Kranz committed
376 377 378
				break;
			}
			case MODE_CHILDREN: {
Julian Kranz's avatar
---  
Julian Kranz committed
379
				translated = translate_super(state, &rreil_insns);
Julian Kranz's avatar
Julian Kranz committed
380 381 382
				break;
			}
		}
Julian Kranz's avatar
AVR  
Julian Kranz committed
383
		clock_gettime(CLOCK_REALTIME, &end);
Julian Kranz's avatar
Julian Kranz committed
384
		long diff = end.tv_sec * NANOS + end.tv_nsec - start.tv_nsec - start.tv_sec * NANOS;
Julian Kranz's avatar
AVR  
Julian Kranz committed
385
		context->time_non_opt += diff;
Julian Kranz's avatar
Julian Kranz committed
386

Julian Kranz's avatar
---  
Julian Kranz committed
387 388 389 390 391
		if(translated == NULL || rreil_insns == NULL) {
			printf("Translation or decoding error, aborting...");
			break;
		}

Julian Kranz's avatar
Julian Kranz committed
392 393 394 395 396 397 398
		/*
		 * Todo: Fix
		 */
//		if(!__isNil(rreil_insns)) {
//			__fatal("TranslateBlock failed");
//			goto end;
//		}
Julian Kranz's avatar
Julian Kranz committed
399
		if(print && mode == MODE_CHILDREN)
Julian Kranz's avatar
---  
Julian Kranz committed
400
			print_succs(state, translated, size);
Julian Kranz's avatar
Julian Kranz committed
401

Julian Kranz's avatar
Julian Kranz committed
402
		int_t native_instruction_count = gdsl_select_ins_count(state);
Julian Kranz's avatar
---  
Julian Kranz committed
403
		context->native_instructions += native_instruction_count;
Julian Kranz's avatar
Julian Kranz committed
404

Julian Kranz's avatar
Julian Kranz committed
405
		//printf("%x\n", buffer[consumed]);
Julian Kranz's avatar
Julian Kranz committed
406

Julian Kranz's avatar
Julian Kranz committed
407 408
		if(print)
			printf("Initial RREIL instructions:\n");
Julian Kranz's avatar
---  
Julian Kranz committed
409
		//__pretty(__rreil_pretty__, rreil_insns, fmt, size);
Julian Kranz's avatar
Ropes  
Julian Kranz committed
410
		string_t fmt = gdsl_merge_rope(state, gdsl_rreil_pretty(state, rreil_insns));
Julian Kranz's avatar
Julian Kranz committed
411 412 413 414
		if(print) {
			puts(fmt);
			printf("\n");
		}
Julian Kranz's avatar
Julian Kranz committed
415

Julian Kranz's avatar
Julian Kranz committed
416 417
		for(size_t i = 0; fmt[i]; i++)
			if(fmt[i] == '\n')
Julian Kranz's avatar
Julian Kranz committed
418
				context->lines++;
Julian Kranz's avatar
Julian Kranz committed
419

Julian Kranz's avatar
AVR  
Julian Kranz committed
420 421
		lv_super_result_t lv_result;
		clock_gettime(CLOCK_REALTIME, &start);
Julian Kranz's avatar
Julian Kranz committed
422

Julian Kranz's avatar
Julian Kranz committed
423 424
		switch(mode) {
			case MODE_CHILDREN: {
Julian Kranz's avatar
---  
Julian Kranz committed
425
				lv_result = gdsl_liveness_super(state, translated);
Julian Kranz's avatar
Julian Kranz committed
426 427 428
				break;
			}
			default: {
Julian Kranz's avatar
---  
Julian Kranz committed
429
				lv_result = gdsl_liveness(state, translated);
Julian Kranz's avatar
Julian Kranz committed
430 431 432
				break;
			}
		}
Julian Kranz's avatar
AVR  
Julian Kranz committed
433
		obj_t rreil_instructions_greedy = gdsl_select_live(state);
Julian Kranz's avatar
Julian Kranz committed
434 435 436 437 438 439 440 441
		/*
		 * Todo: Fix
		 */
//		if(!__isNil(rreil_instructions_greedy)) {
//			__fatal("Liveness failed (no greedy instructions)");
//			goto end;
//		}
		if(cleanup) {
Julian Kranz's avatar
Julian Kranz committed
442 443 444 445 446 447 448
			/*
			 * Move the output somewhere else (so that it does not disturb the time measurement)
			 */
//			printf("RREIL instructions after LV (greedy), before cleanup:\n");
//			__pretty(__rreil_pretty__, rreil_instructions_greedy, fmt, size);
//			puts(fmt);
//			printf("\n");
Julian Kranz's avatar
---  
Julian Kranz committed
449
			rreil_instructions_greedy = gdsl_cleanup(state, rreil_instructions_greedy);
Julian Kranz's avatar
Julian Kranz committed
450 451
		}

Julian Kranz's avatar
AVR  
Julian Kranz committed
452
		clock_gettime(CLOCK_REALTIME, &end);
Julian Kranz's avatar
Julian Kranz committed
453
		diff = end.tv_sec * NANOS + end.tv_nsec - start.tv_nsec - start.tv_sec * NANOS;
Julian Kranz's avatar
AVR  
Julian Kranz committed
454
		context->time_opt += diff;
Julian Kranz's avatar
Julian Kranz committed
455 456 457 458
//		if(!__isNil(greedy_state)) {
//			__fatal("Liveness failed");
//			goto end;
//		}
Julian Kranz's avatar
Julian Kranz committed
459

Julian Kranz's avatar
Julian Kranz committed
460
		if(print && mode == MODE_CHILDREN) {
Julian Kranz's avatar
Julian Kranz committed
461
			printf("Liveness initial state:\n");
Julian Kranz's avatar
AVR  
Julian Kranz committed
462
			fmt = gdsl_merge_rope(state, gdsl_lv_pretty(state, lv_result->initial));
Julian Kranz's avatar
Julian Kranz committed
463 464 465
			puts(fmt);
			printf("\n");
		}
Julian Kranz's avatar
Julian Kranz committed
466

Julian Kranz's avatar
---  
Julian Kranz committed
467
		obj_t greedy_state;
Julian Kranz's avatar
Julian Kranz committed
468

Julian Kranz's avatar
Julian Kranz committed
469 470
		switch(mode) {
			case MODE_CHILDREN: {
Julian Kranz's avatar
AVR  
Julian Kranz committed
471
				greedy_state = lv_result->after;
Julian Kranz's avatar
Julian Kranz committed
472 473 474 475 476 477 478
				break;
			}
			default: {
				greedy_state = lv_result;
				break;
			}
		}
Julian Kranz's avatar
Julian Kranz committed
479 480
		if(print) {
			printf("Liveness greedy state:\n");
Julian Kranz's avatar
Ropes  
Julian Kranz committed
481
			fmt = gdsl_merge_rope(state, gdsl_lv_pretty(state, greedy_state));
Julian Kranz's avatar
Julian Kranz committed
482 483
			puts(fmt);
			printf("\n");
Julian Kranz's avatar
Julian Kranz committed
484
		}
Julian Kranz's avatar
Julian Kranz committed
485

Julian Kranz's avatar
Julian Kranz committed
486 487 488
		if(cleanup) {
			if(print) {
				printf("RREIL instructions after LV (greedy), before cleanup:\n");
Julian Kranz's avatar
Ropes  
Julian Kranz committed
489
				fmt = gdsl_merge_rope(state, gdsl_rreil_pretty(state, rreil_instructions_greedy));
Julian Kranz's avatar
Julian Kranz committed
490 491 492 493
				puts(fmt);
				printf("\n");
			}

Julian Kranz's avatar
---  
Julian Kranz committed
494
			rreil_instructions_greedy = gdsl_cleanup(state, rreil_instructions_greedy);
Julian Kranz's avatar
Julian Kranz committed
495 496
		}

Julian Kranz's avatar
Julian Kranz committed
497 498
		if(print)
			printf("RREIL instructions after LV (greedy):\n");
Julian Kranz's avatar
Ropes  
Julian Kranz committed
499
		fmt = gdsl_merge_rope(state, gdsl_rreil_pretty(state, rreil_instructions_greedy));
Julian Kranz's avatar
Julian Kranz committed
500 501 502 503
		if(print) {
			puts(fmt);
			printf("\n");
		}
Julian Kranz's avatar
Julian Kranz committed
504

Julian Kranz's avatar
Julian Kranz committed
505 506
		for(size_t i = 0; fmt[i]; i++)
			if(fmt[i] == '\n')
Julian Kranz's avatar
Julian Kranz committed
507
				context->lines_opt++;
Julian Kranz's avatar
Julian Kranz committed
508

Julian Kranz's avatar
---  
Julian Kranz committed
509 510
		//consumed += __getBlobIndex(state) - consumed;
		consumed = gdsl_get_ip_offset(state);
Julian Kranz's avatar
Julian Kranz committed
511

Julian Kranz's avatar
---  
Julian Kranz committed
512 513
		gdsl_reset_heap(state);

Julian Kranz's avatar
Julian Kranz committed
514
		//printf("consumed: %lu, buffer_length: %lu\n", consumed, buffer_length);
Julian Kranz's avatar
Julian Kranz committed
515
	}
Julian Kranz's avatar
Julian Kranz committed
516

Julian Kranz's avatar
Julian Kranz committed
517 518
	if(context->native_instructions)
		context->native_instructions--;
Julian Kranz's avatar
Julian Kranz committed
519

Julian Kranz's avatar
Julian Kranz committed
520 521
	free(buffer);
	free(fmt);
Julian Kranz's avatar
Julian Kranz committed
522

Julian Kranz's avatar
---  
Julian Kranz committed
523 524
	gdsl_destroy(state);

Julian Kranz's avatar
Julian Kranz committed
525 526
	return 0;
}
Julian Kranz's avatar
Julian Kranz committed
527

Julian Kranz's avatar
Julian Kranz committed
528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570
static void file_bounds_set(struct options options, size_t *offset, size_t *size_max, char *file) {
	if(options.elf) {
		char e = elf_section_boundary_get(file, offset, size_max);
		if(e)
			exit(2);
	} else {
		*offset = 0;
		*size_max = 0;
	}
}

static void run(struct options options, size_t *offset, size_t *size_max, double *single_red_cum, double *intra_red_cum,
		double *inter_red_cum, size_t index, char print) {
	if(options.latex) {
		struct context inter;
		memset(&inter, 0, sizeof(inter));
		struct context intra;
		memset(&intra, 0, sizeof(intra));
		struct context single;
		memset(&single, 0, sizeof(single));

		file_bounds_set(options, offset, size_max, options.files[index]);

		analyze(options.files[index], print, MODE_SINGLE, options.cleanup, *offset, *size_max, options.offset, &single);
		analyze(options.files[index], print, MODE_DEFAULT, options.cleanup, *offset, *size_max, options.offset, &intra);
		analyze(options.files[index], print, MODE_CHILDREN, options.cleanup, *offset, *size_max, options.offset, &inter);

		print_results_latex(options.files[index], &single, &intra, &inter);

		*single_red_cum += 1 - (single.lines_opt / (double)single.lines);
		*intra_red_cum += 1 - (intra.lines_opt / (double)intra.lines);
		*inter_red_cum += 1 - (inter.lines_opt / (double)inter.lines);
	} else {

		struct context context;
		memset(&context, 0, sizeof(context));
		file_bounds_set(options, offset, size_max, options.files[index]);
		analyze(options.files[index], print, options.mode, options.cleanup, *offset, *size_max, options.offset, &context);

		print_results(&context);
	}
}

Julian Kranz's avatar
Julian Kranz committed
571 572 573
int main(int argc, char** argv) {
	struct options options;
	if(args_parse(argc, argv, &options)) {
Julian Kranz's avatar
Julian Kranz committed
574
		printf("Usage: liveness-sweep [--children] [--offset offset] [--elf] [--cleanup] --file file\n");
Julian Kranz's avatar
Julian Kranz committed
575 576
		return 42;
	}
Julian Kranz's avatar
Julian Kranz committed
577

Julian Kranz's avatar
Julian Kranz committed
578 579
//	printf("elf=%d, offset=%lu, children=%d, file=%s, cleanup=%d\n", options.elf,
//			options.offset, options.children_consider, options.file, options.cleanup);
Julian Kranz's avatar
Julian Kranz committed
580

Julian Kranz's avatar
Julian Kranz committed
581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614
	const rlim_t kStackSize = 4096L * 1024L * 1024L;
	struct rlimit rl;
	int result;

	result = getrlimit(RLIMIT_STACK, &rl);
	if(result == 0) {
		if(rl.rlim_cur < kStackSize) {
			rl.rlim_cur = kStackSize;
			result = setrlimit(RLIMIT_STACK, &rl);
			if(result != 0) {
				fprintf(stderr, "setrlimit returned result = %d\n", result);
			}
		}
	}

	size_t offset;
	size_t size_max;

//	if(argc == 3) {
//		if(strcmp(argv[1], "--elf"))
//			return 1;
//		char e = elf_section_boundary_get(argv[2], &offset, &size_max);
//		if(e)
//			return 2;
//	} else if(argc != 2) {
//		printf("Usage: liveness-sweep [--elf] file\n");
//		return 1;
//	} else {
//		offset = 0;
//		size_max = 0;
//	}

//	FILE *f = fopen(argv[1 + (argc == 3)], "r");

Julian Kranz's avatar
---  
Julian Kranz committed
615 616 617 618 619
	size_t count = 0;
	double single_red_cum = 0.0d;
	double intra_red_cum = 0.0d;
	double inter_red_cum = 0.0d;

Julian Kranz's avatar
Julian Kranz committed
620
	if(options.files_length == 1) {
Julian Kranz's avatar
Julian Kranz committed
621
		run(options, &offset, &size_max, &single_red_cum, &intra_red_cum, &inter_red_cum, 0, 1);
Julian Kranz's avatar
---  
Julian Kranz committed
622
		count = 1;
Julian Kranz's avatar
Julian Kranz committed
623 624 625 626
	} else {
		for(size_t i = 0; i < options.files_length; ++i) {
			if(!options.latex)
				printf("$$$$$$ File %s:\n", options.files[i]);
Julian Kranz's avatar
Julian Kranz committed
627
			run(options, &offset, &size_max, &single_red_cum, &intra_red_cum, &inter_red_cum, i, 0);
Julian Kranz's avatar
Julian Kranz committed
628
		}
Julian Kranz's avatar
---  
Julian Kranz committed
629
		count = options.files_length;
Julian Kranz's avatar
Julian Kranz committed
630 631 632 633
	}

	free(options.files);

Julian Kranz's avatar
---  
Julian Kranz committed
634
	if(count > 1) {
Julian Kranz's avatar
---  
Julian Kranz committed
635 636 637
		printf("Average single reduction: %.3lf%%\n", 100 * single_red_cum / count);
		printf("Average intra reduction: %.3lf%%\n", 100 * intra_red_cum / count);
		printf("Average inter reduction: %.3lf%%\n", 100 * inter_red_cum / count);
Julian Kranz's avatar
---  
Julian Kranz committed
638 639
	}

Julian Kranz's avatar
Julian Kranz committed
640
//	end:
Julian Kranz's avatar
Julian Kranz committed
641

Julian Kranz's avatar
Julian Kranz committed
642
	return (0);
Julian Kranz's avatar
Julian Kranz committed
643 644
}