strip.c 17.7 KB
Newer Older
Camil Staps's avatar
Camil Staps committed
1 2 3 4
#include <stdlib.h>
#include <string.h>

#include "abc_instructions.h"
5
#include "bcgen_instructions.h"
Camil Staps's avatar
Camil Staps committed
6 7 8 9
#include "bytecode.h"
#include "strip.h"
#include "util.h"

10 11 12
enum data_label_type {
	DLT_NORMAL,
	DLT_STRING,
13 14
	DLT_STRING_WITH_DESCRIPTOR,
	DLT_CAF
15 16 17
};

struct s_label { /* source label */
Camil Staps's avatar
Camil Staps committed
18 19
	int32_t offset;
	char *name;
20 21
	struct label *bcgen_label;
	enum data_label_type label_type;
Camil Staps's avatar
Camil Staps committed
22 23
};

24
struct s_relocation { /* source relocation */
Camil Staps's avatar
Camil Staps committed
25 26
	int32_t relocation_offset;
	uint32_t relocation_label;
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
	struct s_label *relocation_belongs_to_label;
};

struct label_queue { /* source labels that are to be activated */
	uint32_t writer;
	uint32_t reader;
	uint32_t size;
	struct s_label *labels[0];
};

struct incoming_labels {
	uint32_t label_id;
	struct incoming_labels *next;
};

struct code_index { /* auxiliary information about code indices */
	int32_t byte_index; /* index in width-optimised bytecode */
	struct incoming_labels *incoming_labels;
Camil Staps's avatar
Camil Staps committed
45 46
};

47 48
static struct program *pgrm;

Camil Staps's avatar
Camil Staps committed
49
static uint8_t *code;
50
static struct code_index *code_indices;
Camil Staps's avatar
Camil Staps committed
51 52
static uint64_t *data;

Camil Staps's avatar
Camil Staps committed
53
static uint32_t n_labels;
54
static uint32_t n_global_labels;
55
static struct s_label *labels;
Camil Staps's avatar
Camil Staps committed
56 57

static uint32_t code_reloc_size;
58
static struct s_relocation *code_relocations;
Camil Staps's avatar
Camil Staps committed
59
static uint32_t data_reloc_size;
60
static struct s_relocation *data_relocations;
Camil Staps's avatar
Camil Staps committed
61

62
struct label_queue *queue;
Camil Staps's avatar
Camil Staps committed
63

64 65
static int export_all_labels;
static int include_symbol_table=0;
66
static int export_label(const char *label) {
67
	if (export_all_labels)
68 69 70 71 72
		return 1;
	else if (!strcmp(label, "__ARRAY__"))
		return 1;
	else if (!strcmp(label, "__STRING__"))
		return 1;
73
	else if (!strcmp(label, "INT"))
74 75 76 77 78 79 80
		return 1;
	else if (!strcmp(label, "BOOL"))
		return 1;
	else if (!strcmp(label, "CHAR"))
		return 1;
	else if (!strcmp(label, "REAL"))
		return 1;
81 82 83 84 85
	else if (!include_symbol_table)
		return 0;
	else if (!label[0])
		return 0;
	else if (!strncmp(label, "_internal", 9))
86
		return 0;
87 88
	else
		return 1;
89 90
}

Camil Staps's avatar
Camil Staps committed
91
static void init_label_queue(void) {
92 93 94 95 96 97
	queue=safe_malloc(sizeof(struct label_queue)+2*sizeof(char*));
	queue->writer=0;
	queue->reader=0;
	queue->size=2;
}

Camil Staps's avatar
Camil Staps committed
98
static void add_label_to_queue(struct s_label *label) {
99 100 101 102 103
	if (label->bcgen_label!=NULL)
		return;

	if (label->name[0]!='\0') {
		label->bcgen_label=enter_label(label->name);
104 105
		if (export_label(label->name))
			make_label_global(label->bcgen_label);
106 107
	} else
		label->bcgen_label=new_internal_label();
108 109 110 111 112 113 114 115 116 117 118 119

	queue->labels[queue->writer++]=label;
	queue->writer%=queue->size;

	if (queue->writer==queue->reader) {
		queue->writer=queue->size;
		queue->size*=2;
		queue->reader=0;
		queue=safe_realloc(queue, sizeof(struct label_queue)+queue->size*sizeof(struct s_label*));
	}
}

Camil Staps's avatar
Camil Staps committed
120
static struct s_label *next_label_from_queue(void) {
121 122 123 124 125 126 127
	if (queue->reader==queue->writer)
		return NULL;
	struct s_label *label=queue->labels[queue->reader];
	queue->reader++;
	queue->reader%=queue->size;
	return label;
}
Camil Staps's avatar
Camil Staps committed
128 129 130 131 132 133 134 135 136

static inline int instruction_ends_block(int16_t instr) {
	switch (instr) {
		case Cjmp:
		case Cjmp_ap1:
		case Cjmp_ap2:
		case Cjmp_ap3:
		case Cjmp_ap4:
		case Cjmp_ap5:
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
		case Cjmp_ap6:
		case Cjmp_ap7:
		case Cjmp_ap8:
		case Cjmp_ap9:
		case Cjmp_ap10:
		case Cjmp_ap11:
		case Cjmp_ap12:
		case Cjmp_ap13:
		case Cjmp_ap14:
		case Cjmp_ap15:
		case Cjmp_ap16:
		case Cjmp_ap17:
		case Cjmp_ap18:
		case Cjmp_ap19:
		case Cjmp_ap20:
		case Cjmp_ap21:
		case Cjmp_ap22:
		case Cjmp_ap23:
		case Cjmp_ap24:
		case Cjmp_ap25:
		case Cjmp_ap26:
		case Cjmp_ap27:
		case Cjmp_ap28:
		case Cjmp_ap29:
		case Cjmp_ap30:
		case Cjmp_ap31:
		case Cjmp_ap32:
Camil Staps's avatar
Camil Staps committed
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
		case Cjmp_eval:
		case Cjmp_eval_upd:
		case Cpop_a_jmp:
		case Cpop_b_jmp:

		case Cfill_a01_pop_rtn:
		case Cpop_a_rtn:
		case Cpop_ab_rtn:
		case Cpop_b_rtn:
		case Crtn:

		case Cadd_arg0:
		case Cadd_arg1:
		case Cadd_arg2:
		case Cadd_arg3:
		case Cadd_arg4:
		case Cadd_arg5:
		case Cadd_arg6:
		case Cadd_arg7:
		case Cadd_arg8:
		case Cadd_arg9:
		case Cadd_arg10:
		case Cadd_arg11:
		case Cadd_arg12:
		case Cadd_arg13:
		case Cadd_arg14:
		case Cadd_arg15:
		case Cadd_arg16:
		case Cadd_arg17:
		case Cadd_arg18:
		case Cadd_arg19:
		case Cadd_arg20:
		case Cadd_arg21:
		case Cadd_arg22:
		case Cadd_arg23:
		case Cadd_arg24:
		case Cadd_arg25:
		case Cadd_arg26:
		case Cadd_arg27:
		case Cadd_arg28:
		case Cadd_arg29:
		case Cadd_arg30:
		case Cadd_arg31:

		case Chalt:

			return 1;

		default:
			return 0;
	}
}

Camil Staps's avatar
Camil Staps committed
217
static struct s_relocation *find_relocation_by_offset(struct s_relocation *relocs, uint32_t n_relocs, uint32_t offset) {
218 219 220 221 222 223 224 225 226 227
	int l=0;
	int r=n_relocs-1;
	while (l<=r) {
		int i=(l+r)/2;
		if (relocs[i].relocation_offset<offset)
			l=i+1;
		else if (relocs[i].relocation_offset>offset)
			r=i-1;
		else
			return &relocs[i];
Camil Staps's avatar
Camil Staps committed
228
	}
229
	return NULL;
230
}
Camil Staps's avatar
Camil Staps committed
231

232 233
static void activate_label(struct s_label *label) {
	struct s_relocation *reloc;
234 235
	if (label->bcgen_label->label_offset!=-1)
		return;
Camil Staps's avatar
Camil Staps committed
236

237 238 239
	if (label->offset==-1) {
		return;
	} else if (label->offset & 1) { /* data */
240 241 242 243 244 245
		uint64_t *block=&data[(label->offset-1)>>2];
		uint32_t arity=block[0];

		switch (label->label_type) {
			case DLT_NORMAL:
				if ((arity & 0xffff) > 256) { /* record */
246
					uint64_t *type_string=&block[2];
247 248 249 250 251 252

					store_data_l(block[-2]);
					store_data_l(block[-1]);
					label->bcgen_label->label_offset=(pgrm->data_size<<2)+1;
					store_data_l(block[0]);

253
					store_string((char*)type_string,type_string[-1]-1,1);
254 255 256 257 258 259 260 261

					int n_desc_labels=0;
					for (char *ts=(char*)type_string; *ts; ts++)
						if (*ts=='{')
							n_desc_labels++;
					uint64_t *desc_labels=&block[2+(type_string[-1]+sizeof(uint64_t)-1)/sizeof(uint64_t)];
					for (; n_desc_labels; n_desc_labels--) {
						reloc=find_relocation_by_offset(data_relocations, data_reloc_size, desc_labels-data);
262 263
						add_label_to_queue(&labels[reloc->relocation_label]);
						add_data_relocation(labels[reloc->relocation_label].bcgen_label, pgrm->data_size);
264 265 266 267 268
						store_data_l(*desc_labels++);
					}

					uint64_t *name_string=desc_labels+1;
					store_string((char*)name_string,name_string[-1],0);
269
				} else if ((arity & 0xffff) > 0 && (arity>>16)==0) { /* string */
270 271
					label->bcgen_label->label_offset=(pgrm->data_size<<2)+1;
					store_string((char*)&block[1], block[0], 0);
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
				} else { /* no record */
					arity>>=3+16;

					if (arity==0) { /* desc0, descn or string */
						if (block[0]==0 || block[0]==1 || (block[0]>>16)>0) { /* desc0 or descn */
							store_data_l(block[-3]);
							store_data_l(block[-2]);
							reloc=find_relocation_by_offset(data_relocations, data_reloc_size, &block[-1]-data);
							add_label_to_queue(&labels[reloc->relocation_label]);
							add_data_relocation(labels[reloc->relocation_label].bcgen_label, pgrm->data_size);
							store_data_l(block[-1]);
							label->bcgen_label->label_offset=(pgrm->data_size<<2)+1;
							store_data_l(block[0]);
							store_data_l(block[1]);
							if (block[2]!=0) { /* descn */
								store_string((char*)&block[3], block[2], 0);
							} else { /* desc0 */
								store_data_l(block[2]);
								store_string((char*)&block[4], block[3], 0);
							}
						} else { /* string */
							store_string((char*)&block[1], block[0], 0);
294
						}
295
					} else { /* descs or normal descriptor */
296 297 298 299 300 301 302
						store_data_l(block[-2]);
						reloc=find_relocation_by_offset(data_relocations, data_reloc_size, &block[-1]-data);
						add_label_to_queue(&labels[reloc->relocation_label]);
						add_data_relocation(labels[reloc->relocation_label].bcgen_label, pgrm->data_size);
						store_data_l(block[-1]);
						label->bcgen_label->label_offset=(pgrm->data_size<<2)+1;

303 304
						int include_last_words=1;

305 306 307 308 309 310 311
						if (arity==1 && (block[1]>>2) > 0) { /* descs */
							store_data_l(block[0]);
							store_data_l(block[1]);
						} else {
							for (int i=0; i<arity; i++) {
								store_data_l(block[i*2]);
								reloc=find_relocation_by_offset(data_relocations, data_reloc_size, &block[i*2+1]-data);
312 313 314 315 316 317
								if (reloc==NULL && i==0) { /* descn */
									store_data_l(block[1]);
									store_string((char*)&block[3], block[2], 0);
									include_last_words=0;
									break;
								}
318 319 320 321
								add_label_to_queue(&labels[reloc->relocation_label]);
								add_data_relocation(labels[reloc->relocation_label].bcgen_label, pgrm->data_size);
								store_data_l(block[i*2+1]);
							}
322 323
						}

324 325 326 327 328 329
						if (include_last_words) {
							store_data_l(block[2*arity]);
							store_data_l(block[2*arity+1]);
							store_data_l(block[2*arity+2]);
							store_string((char*)&block[2*arity+4],block[2*arity+3],0);
						}
330
					}
Camil Staps's avatar
Camil Staps committed
331
				}
332 333 334 335 336 337 338 339 340 341 342 343 344
				break;
			case DLT_STRING:
				label->bcgen_label->label_offset=(pgrm->data_size<<2)+1;
				store_string((char*)&block[1], block[0], 0);
				break;
			case DLT_STRING_WITH_DESCRIPTOR:
				label->bcgen_label->label_offset=(pgrm->data_size<<2)+1;
				reloc=find_relocation_by_offset(data_relocations, data_reloc_size, block-data);
				add_label_to_queue(&labels[reloc->relocation_label]);
				add_data_relocation(labels[reloc->relocation_label].bcgen_label, pgrm->data_size);
				store_data_l(block[0]);
				store_string((char*)&block[2], block[1], 0);
				break;
345 346 347 348 349 350 351 352 353 354 355 356 357
			case DLT_CAF:
				{
					int s=block[-1];
					if (s==0) {
						s=block[-2];
						store_data_l(block[-2]);
					}
					store_data_l(block[-1]);
					label->bcgen_label->label_offset=(pgrm->data_size<<2)+1;
					for (; s; s--)
						store_data_l(0);
				}
				break;
Camil Staps's avatar
Camil Staps committed
358
		}
359
	} else { /* code */
Camil Staps's avatar
Camil Staps committed
360
		int ci=label->offset>>2;
361

362
		/* since the label may point to the middle of a block, first find the beginning */
363 364
		do {
			do { ci--; } while (ci>=0 && code_indices[ci].byte_index==-1);
365 366
		} while (ci>0 && !instruction_ends_block(*(int16_t*)&code[code_indices[ci].byte_index]));
		if (ci>0)
367
			do { ci++; } while (code_indices[ci].byte_index==-1);
368 369
		else
			ci=0;
370

371
		uint8_t *code_block=&code[code_indices[ci].byte_index];
Camil Staps's avatar
Camil Staps committed
372

373
		while (1) {
374
			for (struct incoming_labels *ilabs=code_indices[ci].incoming_labels; ilabs!=NULL; ilabs=ilabs->next) {
375 376 377 378
				struct s_label *lab=&labels[ilabs->label_id];
				if (lab->bcgen_label==NULL) {
					if (lab->name[0] != '\0') {
						lab->bcgen_label=enter_label(lab->name);
379
						if (export_label(lab->name))
380
							make_label_global(lab->bcgen_label);
381
					} else
382
						lab->bcgen_label=new_label_at_offset(pgrm->code_size<<2);
383
				} else if (lab->bcgen_label->label_offset!=-1 && lab->bcgen_label->label_offset!=(pgrm->code_size<<2)) {
384
					EPRINTF("Error: overwriting label '%s'\n",lab->bcgen_label->label_name);
385
					EXIT(NULL,1);
386 387 388 389
				}
				lab->bcgen_label->label_offset=pgrm->code_size<<2;
			}

Camil Staps's avatar
Camil Staps committed
390
			int16_t instr=*(int16_t*)code_block;
391
			store_code_elem(2, instr);
Camil Staps's avatar
Camil Staps committed
392 393 394 395 396 397
			code_block+=2;
			const char *type=instruction_type(instr);
			ci++;
			for (; *type; type++) {
				switch (*type) {
					case 'c': /* Char */
398
						store_code_elem(1, *(uint8_t*)code_block);
Camil Staps's avatar
Camil Staps committed
399 400 401 402 403 404
						code_block+=1;
						break;
					case 'I': /* Instruction */
					case 'n': /* Stack index */
					case 'N': /* Stack index, optimised to byte width */
					case 'a': /* Arity */
405
						store_code_elem(2, *(uint16_t*)code_block);
Camil Staps's avatar
Camil Staps committed
406 407 408
						code_block+=2;
						break;
					case 'l': /* Label */
409
						reloc=find_relocation_by_offset(code_relocations, code_reloc_size, ci);
Camil Staps's avatar
Camil Staps committed
410 411 412 413 414 415 416
						/* Only labels in .n/.nu directives (i.e., CA_data_*)
						 * may be NULL; otherwise, throw an error. */
						if (instr<CA_data_IIIla && reloc==NULL) {
							EPRINTF("Error: label for %s was NULL\n",instruction_name(instr));
							EXIT(NULL,1);
						}
						if (reloc!=NULL) {
417 418 419
							add_label_to_queue(&labels[reloc->relocation_label]);
							add_code_relocation(labels[reloc->relocation_label].bcgen_label, pgrm->code_size);
						}
420 421
						store_code_elem(2, *(uint32_t*)code_block);
						code_block+=2;
Camil Staps's avatar
Camil Staps committed
422
						break;
423 424 425 426 427
					case 'C': /* CAF label */
						reloc=find_relocation_by_offset(code_relocations, code_reloc_size, ci);
						add_label_to_queue(&labels[reloc->relocation_label]);
						labels[reloc->relocation_label].label_type=DLT_CAF;
						add_code_relocation(labels[reloc->relocation_label].bcgen_label, pgrm->code_size);
428 429
						store_code_elem(2, *(uint32_t*)code_block);
						code_block+=2;
430
						break;
431 432 433 434 435 436
					case 'S': /* String with __STRING__ label */
					case 's': /* Plain string label */
						reloc=find_relocation_by_offset(code_relocations, code_reloc_size, ci);
						add_label_to_queue(&labels[reloc->relocation_label]);
						labels[reloc->relocation_label].label_type=*type=='S' ? DLT_STRING_WITH_DESCRIPTOR : DLT_STRING;
						add_code_relocation(labels[reloc->relocation_label].bcgen_label, pgrm->code_size);
437 438
						store_code_elem(2, *(uint32_t*)code_block);
						code_block+=2;
Camil Staps's avatar
Camil Staps committed
439 440 441
						break;
					case 'r': /* Real */
					case 'i': /* Int */
442
						store_code_elem(8, *(uint64_t*)code_block);
Camil Staps's avatar
Camil Staps committed
443 444
						code_block+=8;
						break;
445
					case 'R': /* Double-position Real */
446 447 448 449
						store_code_elem(4, *(uint32_t*)code_block);
						code_block+=4;
						store_code_elem(4, *(uint32_t*)code_block);
						code_block+=4;
450 451
						ci++;
						break;
Camil Staps's avatar
Camil Staps committed
452 453
					default:
						EPRINTF("error in activate_label\n");
454
						EXIT(NULL,-1);
Camil Staps's avatar
Camil Staps committed
455 456 457
				}
				ci++;
			}
458 459 460

			if (instruction_ends_block(instr))
				break;
Camil Staps's avatar
Camil Staps committed
461 462 463 464
		}
	}
}

465 466
static struct s_label *find_label_by_name(const char *name) {
	int l=0;
467
	int r=n_global_labels-1;
468 469 470 471 472 473 474 475 476 477
	while (l<=r) {
		int i=(l+r)/2;
		struct s_label *label=&labels[i];
		int c=strcmp(label->name, name);
		if (c<0)
			l=i+1;
		else if (c>0)
			r=i-1;
		else
			return label;
Camil Staps's avatar
Camil Staps committed
478
	}
479
	EPRINTF("error in find_label_by_name (%s)\n",name);
480
	EXIT(NULL,1);
481
	return NULL;
Camil Staps's avatar
Camil Staps committed
482 483
}

484 485 486 487
void prepare_strip_bytecode(uint32_t *bytecode,
		int _include_symbol_table, int activate_start_label) {
	include_symbol_table=_include_symbol_table;
	export_all_labels=0;
488

489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507
	if (bytecode[0]!=ABC_MAGIC_NUMBER) {
		EPRINTF("file to strip does not start with right magic number\n");
		EXIT(NULL,-1);
	}
	code=&((uint8_t*)bytecode)[bytecode[1]+8];
	if (bytecode[2]!=ABC_VERSION) {
		EPRINTF("file to strip ABC* version does not match\n");
		EXIT(NULL,-1);
	}

	uint32_t code_size=bytecode[3];
	/*uint32_t words_in_strings=bytecode[4];*/
	uint32_t strings_size=bytecode[5];
	uint32_t data_size=bytecode[6];
	n_labels=bytecode[7];
	/*uint32_t global_label_string_count=bytecode[8];*/
	code_reloc_size=bytecode[9];
	data_reloc_size=bytecode[10];
	uint32_t start_label_id=bytecode[11];
Camil Staps's avatar
Camil Staps committed
508

509
	code_indices=safe_malloc(sizeof(struct code_index)*code_size);
Camil Staps's avatar
Camil Staps committed
510 511 512 513 514

	int ci=0;
	int i=0;
	while (ci<code_size) {
		uint16_t instr=*(uint16_t*)&code[i];
515 516 517
		code_indices[ci].byte_index=i;
		code_indices[ci].incoming_labels=NULL;
		ci++;
Camil Staps's avatar
Camil Staps committed
518
		i+=2;
Camil Staps's avatar
Camil Staps committed
519
		const char *type=instruction_type(instr);
Camil Staps's avatar
Camil Staps committed
520
		for (; *type; type++) {
521 522 523
			code_indices[ci].byte_index=-1;
			code_indices[ci].incoming_labels=NULL;
			ci++;
Camil Staps's avatar
Camil Staps committed
524 525 526 527 528 529 530 531 532
			switch (*type) {
				case 'c': /* Char */
					i+=1;
					break;
				case 'I': /* Instruction */
				case 'n': /* Stack index */
				case 'N': /* Stack index, optimised to byte width */
				case 'a': /* Arity */
				case 'l': /* Label */
533
				case 'C': /* CAF label */
Camil Staps's avatar
Camil Staps committed
534 535
				case 'S': /* String label */
				case 's': /* String label */
536
					i+=2;
Camil Staps's avatar
Camil Staps committed
537 538 539 540 541
					break;
				case 'r': /* Real */
				case 'i': /* Int */
					i+=8;
					break;
542
				case 'R': /* Double-position Real */
543 544 545 546
					i+=4;
					code_indices[ci].byte_index=-1;
					code_indices[ci].incoming_labels=NULL;
					i+=4;
547 548
					ci++;
					break;
Camil Staps's avatar
Camil Staps committed
549 550
				default:
					EPRINTF("error in strip_bytecode\n");
551
					EXIT(NULL,-1);
Camil Staps's avatar
Camil Staps committed
552 553 554 555 556 557 558 559 560
			}
		}
	}

	bytecode=(uint32_t*)&code[i];
	bytecode+=strings_size;
	data=(uint64_t*)bytecode;
	bytecode=(uint32_t*)&data[data_size];

561 562 563
	init_label_queue();
	pgrm=initialize_code();

Camil Staps's avatar
Camil Staps committed
564
	char *labels_in_bytecode=(char*)bytecode;
565
	labels=safe_malloc(sizeof(struct s_label)*n_labels);
Camil Staps's avatar
Camil Staps committed
566
	for (int i=0; i<n_labels; i++) {
Camil Staps's avatar
Camil Staps committed
567 568
		labels[i].offset=*(int32_t*)labels_in_bytecode;
		labels[i].name=&labels_in_bytecode[4];
569 570
		if (labels[i].name[0]!='\0')
			n_global_labels=i;
571 572 573 574 575 576 577 578
		labels[i].bcgen_label=NULL;
		labels[i].label_type=DLT_NORMAL;
		if (!(labels[i].offset & 1)) {
			struct incoming_labels *ilabs=safe_malloc(sizeof(struct incoming_labels));
			ilabs->next=code_indices[labels[i].offset>>2].incoming_labels;
			ilabs->label_id=i;
			code_indices[labels[i].offset>>2].incoming_labels=ilabs;
		}
579 580 581 582
		if (activate_start_label && i==start_label_id) {
			add_label_to_queue(&labels[i]);
			code_start(labels[i].name);
		}
Camil Staps's avatar
Camil Staps committed
583 584 585
		labels_in_bytecode+=4;
		while (*labels_in_bytecode++);
	}
Camil Staps's avatar
Camil Staps committed
586 587
	bytecode=(uint32_t*)labels_in_bytecode;

588
	code_relocations=safe_malloc(sizeof(struct s_relocation)*code_reloc_size);
Camil Staps's avatar
Camil Staps committed
589 590 591 592 593 594
	for (int i=0; i<code_reloc_size; i++) {
		code_relocations[i].relocation_offset=bytecode[0];
		code_relocations[i].relocation_label=bytecode[1];
		code_relocations[i].relocation_belongs_to_label=NULL;
		bytecode+=2;
	}
595
	data_relocations=safe_malloc(sizeof(struct s_relocation)*data_reloc_size);
Camil Staps's avatar
Camil Staps committed
596 597 598 599 600 601
	for (int i=0; i<data_reloc_size; i++) {
		data_relocations[i].relocation_offset=bytecode[0];
		data_relocations[i].relocation_label=bytecode[1];
		data_relocations[i].relocation_belongs_to_label=NULL;
		bytecode+=2;
	}
602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618

	/* Give unnamed labels a name when there is a label with the same offset to
	 * avoid generating superfluous labels. */
	for (int ci=0; ci<code_size; ci++) {
		if (code_indices[ci].byte_index==-1)
			continue;
		char *name=NULL;
		for (struct incoming_labels *ilabs=code_indices[ci].incoming_labels; ilabs!=NULL; ilabs=ilabs->next)
			if (labels[ilabs->label_id].name[0]!='\0') {
				name=labels[ilabs->label_id].name;
				break;
			}
		if (name!=NULL)
			for (struct incoming_labels *ilabs=code_indices[ci].incoming_labels; ilabs!=NULL; ilabs=ilabs->next)
				if (labels[ilabs->label_id].name[0]=='\0')
					labels[ilabs->label_id].name=name;
	}
619
}
Camil Staps's avatar
Camil Staps committed
620

621
char *finish_strip_bytecode(uint32_t *result_size) {
622
	struct s_label *label;
623
	while ((label=next_label_from_queue())!=NULL)
624
		activate_label(label);
Camil Staps's avatar
Camil Staps committed
625

626 627 628
	return write_program_to_string(result_size);
}

629
void strip_bytecode(int _include_symbol_table,
630
		uint32_t *bytecode, struct clean_string **descriptors,
631
		uint32_t *result_size, char **result) {
632 633
	prepare_strip_bytecode(bytecode, _include_symbol_table, 0);
	export_all_labels=1;
634 635 636 637

	for (int i=0; i<((BC_WORD*)descriptors)[-2]; i++)
		add_label_to_queue(find_label_by_name(descriptors[i]->cs_characters));

638
	*result=finish_strip_bytecode(result_size);
Camil Staps's avatar
Camil Staps committed
639
}