| .. | .. | 
|---|
| 70 | 70 |   | 
|---|
| 71 | 71 |  	u32 ident; | 
|---|
| 72 | 72 |  	u32 checksum; | 
|---|
 | 73 | +#if CONFIG_CLANG_VERSION < 110000  | 
|---|
| 73 | 74 |  	u8 use_extra_checksum; | 
|---|
 | 75 | +#endif  | 
|---|
| 74 | 76 |  	u32 cfg_checksum; | 
|---|
| 75 | 77 |   | 
|---|
| 76 | 78 |  	u32 num_counters; | 
|---|
| 77 | 79 |  	u64 *counters; | 
|---|
 | 80 | +#if CONFIG_CLANG_VERSION < 110000  | 
|---|
| 78 | 81 |  	const char *function_name; | 
|---|
 | 82 | +#endif  | 
|---|
| 79 | 83 |  }; | 
|---|
| 80 | 84 |   | 
|---|
| 81 | 85 |  static struct gcov_info *current_info; | 
|---|
| .. | .. | 
|---|
| 105 | 109 |  } | 
|---|
| 106 | 110 |  EXPORT_SYMBOL(llvm_gcov_init); | 
|---|
| 107 | 111 |   | 
|---|
 | 112 | +#if CONFIG_CLANG_VERSION < 110000  | 
|---|
| 108 | 113 |  void llvm_gcda_start_file(const char *orig_filename, const char version[4], | 
|---|
| 109 | 114 |  		u32 checksum) | 
|---|
| 110 | 115 |  { | 
|---|
| .. | .. | 
|---|
| 113 | 118 |  	current_info->checksum = checksum; | 
|---|
| 114 | 119 |  } | 
|---|
| 115 | 120 |  EXPORT_SYMBOL(llvm_gcda_start_file); | 
|---|
 | 121 | +#else  | 
|---|
 | 122 | +void llvm_gcda_start_file(const char *orig_filename, u32 version, u32 checksum)  | 
|---|
 | 123 | +{  | 
|---|
 | 124 | +	current_info->filename = orig_filename;  | 
|---|
 | 125 | +	current_info->version = version;  | 
|---|
 | 126 | +	current_info->checksum = checksum;  | 
|---|
 | 127 | +}  | 
|---|
 | 128 | +EXPORT_SYMBOL(llvm_gcda_start_file);  | 
|---|
 | 129 | +#endif  | 
|---|
| 116 | 130 |   | 
|---|
 | 131 | +#if CONFIG_CLANG_VERSION < 110000  | 
|---|
| 117 | 132 |  void llvm_gcda_emit_function(u32 ident, const char *function_name, | 
|---|
| 118 | 133 |  		u32 func_checksum, u8 use_extra_checksum, u32 cfg_checksum) | 
|---|
| 119 | 134 |  { | 
|---|
| .. | .. | 
|---|
| 132 | 147 |   | 
|---|
| 133 | 148 |  	list_add_tail(&info->head, ¤t_info->functions); | 
|---|
| 134 | 149 |  } | 
|---|
 | 150 | +#else  | 
|---|
 | 151 | +void llvm_gcda_emit_function(u32 ident, u32 func_checksum, u32 cfg_checksum)  | 
|---|
 | 152 | +{  | 
|---|
 | 153 | +	struct gcov_fn_info *info = kzalloc(sizeof(*info), GFP_KERNEL);  | 
|---|
 | 154 | +  | 
|---|
 | 155 | +	if (!info)  | 
|---|
 | 156 | +		return;  | 
|---|
 | 157 | +  | 
|---|
 | 158 | +	INIT_LIST_HEAD(&info->head);  | 
|---|
 | 159 | +	info->ident = ident;  | 
|---|
 | 160 | +	info->checksum = func_checksum;  | 
|---|
 | 161 | +	info->cfg_checksum = cfg_checksum;  | 
|---|
 | 162 | +	list_add_tail(&info->head, ¤t_info->functions);  | 
|---|
 | 163 | +}  | 
|---|
 | 164 | +#endif  | 
|---|
| 135 | 165 |  EXPORT_SYMBOL(llvm_gcda_emit_function); | 
|---|
| 136 | 166 |   | 
|---|
| 137 | 167 |  void llvm_gcda_emit_arcs(u32 num_counters, u64 *counters) | 
|---|
| .. | .. | 
|---|
| 262 | 292 |  		!list_is_last(&fn_ptr2->head, &info2->functions)) { | 
|---|
| 263 | 293 |  		if (fn_ptr1->checksum != fn_ptr2->checksum) | 
|---|
| 264 | 294 |  			return false; | 
|---|
 | 295 | +#if CONFIG_CLANG_VERSION < 110000  | 
|---|
| 265 | 296 |  		if (fn_ptr1->use_extra_checksum != fn_ptr2->use_extra_checksum) | 
|---|
| 266 | 297 |  			return false; | 
|---|
| 267 | 298 |  		if (fn_ptr1->use_extra_checksum && | 
|---|
| 268 | 299 |  			fn_ptr1->cfg_checksum != fn_ptr2->cfg_checksum) | 
|---|
| 269 | 300 |  			return false; | 
|---|
 | 301 | +#else  | 
|---|
 | 302 | +		if (fn_ptr1->cfg_checksum != fn_ptr2->cfg_checksum)  | 
|---|
 | 303 | +			return false;  | 
|---|
 | 304 | +#endif  | 
|---|
| 270 | 305 |  		fn_ptr1 = list_next_entry(fn_ptr1, head); | 
|---|
| 271 | 306 |  		fn_ptr2 = list_next_entry(fn_ptr2, head); | 
|---|
| 272 | 307 |  	} | 
|---|
| .. | .. | 
|---|
| 292 | 327 |   | 
|---|
| 293 | 328 |  		for (i = 0; i < sfn_ptr->num_counters; i++) | 
|---|
| 294 | 329 |  			dfn_ptr->counters[i] += sfn_ptr->counters[i]; | 
|---|
 | 330 | +  | 
|---|
 | 331 | +		sfn_ptr = list_next_entry(sfn_ptr, head);  | 
|---|
| 295 | 332 |  	} | 
|---|
| 296 | 333 |  } | 
|---|
| 297 | 334 |   | 
|---|
 | 335 | +#if CONFIG_CLANG_VERSION < 110000  | 
|---|
| 298 | 336 |  static struct gcov_fn_info *gcov_fn_info_dup(struct gcov_fn_info *fn) | 
|---|
| 299 | 337 |  { | 
|---|
| 300 | 338 |  	size_t cv_size; /* counter values size */ | 
|---|
| .. | .. | 
|---|
| 322 | 360 |  	kfree(fn_dup); | 
|---|
| 323 | 361 |  	return NULL; | 
|---|
| 324 | 362 |  } | 
|---|
 | 363 | +#else  | 
|---|
 | 364 | +static struct gcov_fn_info *gcov_fn_info_dup(struct gcov_fn_info *fn)  | 
|---|
 | 365 | +{  | 
|---|
 | 366 | +	size_t cv_size; /* counter values size */  | 
|---|
 | 367 | +	struct gcov_fn_info *fn_dup = kmemdup(fn, sizeof(*fn),  | 
|---|
 | 368 | +			GFP_KERNEL);  | 
|---|
 | 369 | +	if (!fn_dup)  | 
|---|
 | 370 | +		return NULL;  | 
|---|
 | 371 | +	INIT_LIST_HEAD(&fn_dup->head);  | 
|---|
 | 372 | +  | 
|---|
 | 373 | +	cv_size = fn->num_counters * sizeof(fn->counters[0]);  | 
|---|
 | 374 | +	fn_dup->counters = vmalloc(cv_size);  | 
|---|
 | 375 | +	if (!fn_dup->counters) {  | 
|---|
 | 376 | +		kfree(fn_dup);  | 
|---|
 | 377 | +		return NULL;  | 
|---|
 | 378 | +	}  | 
|---|
 | 379 | +  | 
|---|
 | 380 | +	memcpy(fn_dup->counters, fn->counters, cv_size);  | 
|---|
 | 381 | +  | 
|---|
 | 382 | +	return fn_dup;  | 
|---|
 | 383 | +}  | 
|---|
 | 384 | +#endif  | 
|---|
| 325 | 385 |   | 
|---|
| 326 | 386 |  /** | 
|---|
| 327 | 387 |   * gcov_info_dup - duplicate profiling data set | 
|---|
| .. | .. | 
|---|
| 362 | 422 |   * gcov_info_free - release memory for profiling data set duplicate | 
|---|
| 363 | 423 |   * @info: profiling data set duplicate to free | 
|---|
| 364 | 424 |   */ | 
|---|
 | 425 | +#if CONFIG_CLANG_VERSION < 110000  | 
|---|
| 365 | 426 |  void gcov_info_free(struct gcov_info *info) | 
|---|
| 366 | 427 |  { | 
|---|
| 367 | 428 |  	struct gcov_fn_info *fn, *tmp; | 
|---|
| .. | .. | 
|---|
| 375 | 436 |  	kfree(info->filename); | 
|---|
| 376 | 437 |  	kfree(info); | 
|---|
| 377 | 438 |  } | 
|---|
 | 439 | +#else  | 
|---|
 | 440 | +void gcov_info_free(struct gcov_info *info)  | 
|---|
 | 441 | +{  | 
|---|
 | 442 | +	struct gcov_fn_info *fn, *tmp;  | 
|---|
 | 443 | +  | 
|---|
 | 444 | +	list_for_each_entry_safe(fn, tmp, &info->functions, head) {  | 
|---|
 | 445 | +		vfree(fn->counters);  | 
|---|
 | 446 | +		list_del(&fn->head);  | 
|---|
 | 447 | +		kfree(fn);  | 
|---|
 | 448 | +	}  | 
|---|
 | 449 | +	kfree(info->filename);  | 
|---|
 | 450 | +	kfree(info);  | 
|---|
 | 451 | +}  | 
|---|
 | 452 | +#endif  | 
|---|
| 378 | 453 |   | 
|---|
| 379 | 454 |  #define ITER_STRIDE	PAGE_SIZE | 
|---|
| 380 | 455 |   | 
|---|
| .. | .. | 
|---|
| 460 | 535 |   | 
|---|
| 461 | 536 |  	list_for_each_entry(fi_ptr, &info->functions, head) { | 
|---|
| 462 | 537 |  		u32 i; | 
|---|
| 463 |  | -		u32 len = 2;  | 
|---|
| 464 |  | -  | 
|---|
| 465 |  | -		if (fi_ptr->use_extra_checksum)  | 
|---|
| 466 |  | -			len++;  | 
|---|
| 467 | 538 |   | 
|---|
| 468 | 539 |  		pos += store_gcov_u32(buffer, pos, GCOV_TAG_FUNCTION); | 
|---|
| 469 |  | -		pos += store_gcov_u32(buffer, pos, len);  | 
|---|
 | 540 | +#if CONFIG_CLANG_VERSION < 110000  | 
|---|
 | 541 | +		pos += store_gcov_u32(buffer, pos,  | 
|---|
 | 542 | +			fi_ptr->use_extra_checksum ? 3 : 2);  | 
|---|
 | 543 | +#else  | 
|---|
 | 544 | +		pos += store_gcov_u32(buffer, pos, 3);  | 
|---|
 | 545 | +#endif  | 
|---|
| 470 | 546 |  		pos += store_gcov_u32(buffer, pos, fi_ptr->ident); | 
|---|
| 471 | 547 |  		pos += store_gcov_u32(buffer, pos, fi_ptr->checksum); | 
|---|
 | 548 | +#if CONFIG_CLANG_VERSION < 110000  | 
|---|
| 472 | 549 |  		if (fi_ptr->use_extra_checksum) | 
|---|
| 473 | 550 |  			pos += store_gcov_u32(buffer, pos, fi_ptr->cfg_checksum); | 
|---|
 | 551 | +#else  | 
|---|
 | 552 | +		pos += store_gcov_u32(buffer, pos, fi_ptr->cfg_checksum);  | 
|---|
 | 553 | +#endif  | 
|---|
| 474 | 554 |   | 
|---|
| 475 | 555 |  		pos += store_gcov_u32(buffer, pos, GCOV_TAG_COUNTER_BASE); | 
|---|
| 476 | 556 |  		pos += store_gcov_u32(buffer, pos, fi_ptr->num_counters * 2); | 
|---|