| // SPDX-License-Identifier: GPL-2.0 | 
 | #include <ctype.h> | 
 | #include "symbol/kallsyms.h" | 
 | #include <stdio.h> | 
 | #include <stdlib.h> | 
 |  | 
 | u8 kallsyms2elf_type(char type) | 
 | { | 
 | 	type = tolower(type); | 
 | 	return (type == 't' || type == 'w') ? STT_FUNC : STT_OBJECT; | 
 | } | 
 |  | 
 | bool kallsyms__is_function(char symbol_type) | 
 | { | 
 | 	symbol_type = toupper(symbol_type); | 
 | 	return symbol_type == 'T' || symbol_type == 'W'; | 
 | } | 
 |  | 
 | int kallsyms__parse(const char *filename, void *arg, | 
 | 		    int (*process_symbol)(void *arg, const char *name, | 
 | 					  char type, u64 start)) | 
 | { | 
 | 	char *line = NULL; | 
 | 	size_t n; | 
 | 	int err = -1; | 
 | 	FILE *file = fopen(filename, "r"); | 
 |  | 
 | 	if (file == NULL) | 
 | 		goto out_failure; | 
 |  | 
 | 	err = 0; | 
 |  | 
 | 	while (!feof(file)) { | 
 | 		u64 start; | 
 | 		int line_len, len; | 
 | 		char symbol_type; | 
 | 		char *symbol_name; | 
 |  | 
 | 		line_len = getline(&line, &n, file); | 
 | 		if (line_len < 0 || !line) | 
 | 			break; | 
 |  | 
 | 		line[--line_len] = '\0'; /* \n */ | 
 |  | 
 | 		len = hex2u64(line, &start); | 
 |  | 
 | 		/* Skip the line if we failed to parse the address. */ | 
 | 		if (!len) | 
 | 			continue; | 
 |  | 
 | 		len++; | 
 | 		if (len + 2 >= line_len) | 
 | 			continue; | 
 |  | 
 | 		symbol_type = line[len]; | 
 | 		len += 2; | 
 | 		symbol_name = line + len; | 
 | 		len = line_len - len; | 
 |  | 
 | 		if (len >= KSYM_NAME_LEN) { | 
 | 			err = -1; | 
 | 			break; | 
 | 		} | 
 |  | 
 | 		err = process_symbol(arg, symbol_name, symbol_type, start); | 
 | 		if (err) | 
 | 			break; | 
 | 	} | 
 |  | 
 | 	free(line); | 
 | 	fclose(file); | 
 | 	return err; | 
 |  | 
 | out_failure: | 
 | 	return -1; | 
 | } |