mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	bpf: Create a new btf_name_by_offset() for non type name use case
The current btf_name_by_offset() is returning "(anon)" type name for the offset == 0 case and "(invalid-name-offset)" for the out-of-bound offset case. It fits well for the internal BTF verbose log purpose which is focusing on type. For example, offset == 0 => "(anon)" => anonymous type/name. Returning non-NULL for the bad offset case is needed during the BTF verification process because the BTF verifier may complain about another field first before discovering the name_off is invalid. However, it may not be ideal for the newer use case which does not necessary mean type name. For example, when logging line_info in the BPF verifier in the next patch, it is better to log an empty src line instead of logging "(anon)". The existing bpf_name_by_offset() is renamed to __bpf_name_by_offset() and static to btf.c. A new bpf_name_by_offset() is added for generic context usage. It returns "\0" for name_off == 0 (note that btf->strings[0] is "\0") and NULL for invalid offset. It allows the caller to decide what is the best output in its context. The new btf_name_by_offset() is overlapped with btf_name_offset_valid(). Hence, btf_name_offset_valid() is removed from btf.h to keep the btf.h API minimal. The existing btf_name_offset_valid() usage in btf.c could also be replaced later. Signed-off-by: Martin KaFai Lau <kafai@fb.com> Acked-by: Yonghong Song <yhs@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
		
							parent
							
								
									28c1272914
								
							
						
					
					
						commit
						23127b33ec
					
				
					 3 changed files with 22 additions and 14 deletions
				
			
		| 
						 | 
					@ -46,7 +46,6 @@ void btf_type_seq_show(const struct btf *btf, u32 type_id, void *obj,
 | 
				
			||||||
		       struct seq_file *m);
 | 
							       struct seq_file *m);
 | 
				
			||||||
int btf_get_fd_by_id(u32 id);
 | 
					int btf_get_fd_by_id(u32 id);
 | 
				
			||||||
u32 btf_id(const struct btf *btf);
 | 
					u32 btf_id(const struct btf *btf);
 | 
				
			||||||
bool btf_name_offset_valid(const struct btf *btf, u32 offset);
 | 
					 | 
				
			||||||
bool btf_type_is_reg_int(const struct btf_type *t, u32 expected_size);
 | 
					bool btf_type_is_reg_int(const struct btf_type *t, u32 expected_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_BPF_SYSCALL
 | 
					#ifdef CONFIG_BPF_SYSCALL
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -474,7 +474,7 @@ static bool btf_name_valid_identifier(const struct btf *btf, u32 offset)
 | 
				
			||||||
	return !*src;
 | 
						return !*src;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char *btf_name_by_offset(const struct btf *btf, u32 offset)
 | 
					static const char *__btf_name_by_offset(const struct btf *btf, u32 offset)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!offset)
 | 
						if (!offset)
 | 
				
			||||||
		return "(anon)";
 | 
							return "(anon)";
 | 
				
			||||||
| 
						 | 
					@ -484,6 +484,14 @@ const char *btf_name_by_offset(const struct btf *btf, u32 offset)
 | 
				
			||||||
		return "(invalid-name-offset)";
 | 
							return "(invalid-name-offset)";
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const char *btf_name_by_offset(const struct btf *btf, u32 offset)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (offset < btf->hdr.str_len)
 | 
				
			||||||
 | 
							return &btf->strings[offset];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const struct btf_type *btf_type_by_id(const struct btf *btf, u32 type_id)
 | 
					const struct btf_type *btf_type_by_id(const struct btf *btf, u32 type_id)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (type_id > btf->nr_types)
 | 
						if (type_id > btf->nr_types)
 | 
				
			||||||
| 
						 | 
					@ -576,7 +584,7 @@ __printf(4, 5) static void __btf_verifier_log_type(struct btf_verifier_env *env,
 | 
				
			||||||
	__btf_verifier_log(log, "[%u] %s %s%s",
 | 
						__btf_verifier_log(log, "[%u] %s %s%s",
 | 
				
			||||||
			   env->log_type_id,
 | 
								   env->log_type_id,
 | 
				
			||||||
			   btf_kind_str[kind],
 | 
								   btf_kind_str[kind],
 | 
				
			||||||
			   btf_name_by_offset(btf, t->name_off),
 | 
								   __btf_name_by_offset(btf, t->name_off),
 | 
				
			||||||
			   log_details ? " " : "");
 | 
								   log_details ? " " : "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (log_details)
 | 
						if (log_details)
 | 
				
			||||||
| 
						 | 
					@ -620,7 +628,7 @@ static void btf_verifier_log_member(struct btf_verifier_env *env,
 | 
				
			||||||
		btf_verifier_log_type(env, struct_type, NULL);
 | 
							btf_verifier_log_type(env, struct_type, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	__btf_verifier_log(log, "\t%s type_id=%u bits_offset=%u",
 | 
						__btf_verifier_log(log, "\t%s type_id=%u bits_offset=%u",
 | 
				
			||||||
			   btf_name_by_offset(btf, member->name_off),
 | 
								   __btf_name_by_offset(btf, member->name_off),
 | 
				
			||||||
			   member->type, member->offset);
 | 
								   member->type, member->offset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (fmt && *fmt) {
 | 
						if (fmt && *fmt) {
 | 
				
			||||||
| 
						 | 
					@ -1872,7 +1880,7 @@ static s32 btf_enum_check_meta(struct btf_verifier_env *env,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		btf_verifier_log(env, "\t%s val=%d\n",
 | 
							btf_verifier_log(env, "\t%s val=%d\n",
 | 
				
			||||||
				 btf_name_by_offset(btf, enums[i].name_off),
 | 
									 __btf_name_by_offset(btf, enums[i].name_off),
 | 
				
			||||||
				 enums[i].val);
 | 
									 enums[i].val);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1896,7 +1904,8 @@ static void btf_enum_seq_show(const struct btf *btf, const struct btf_type *t,
 | 
				
			||||||
	for (i = 0; i < nr_enums; i++) {
 | 
						for (i = 0; i < nr_enums; i++) {
 | 
				
			||||||
		if (v == enums[i].val) {
 | 
							if (v == enums[i].val) {
 | 
				
			||||||
			seq_printf(m, "%s",
 | 
								seq_printf(m, "%s",
 | 
				
			||||||
				   btf_name_by_offset(btf, enums[i].name_off));
 | 
									   __btf_name_by_offset(btf,
 | 
				
			||||||
 | 
												enums[i].name_off));
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -1954,11 +1963,11 @@ static void btf_func_proto_log(struct btf_verifier_env *env,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	btf_verifier_log(env, "%u %s", args[0].type,
 | 
						btf_verifier_log(env, "%u %s", args[0].type,
 | 
				
			||||||
			 btf_name_by_offset(env->btf,
 | 
								 __btf_name_by_offset(env->btf,
 | 
				
			||||||
					      args[0].name_off));
 | 
										      args[0].name_off));
 | 
				
			||||||
	for (i = 1; i < nr_args - 1; i++)
 | 
						for (i = 1; i < nr_args - 1; i++)
 | 
				
			||||||
		btf_verifier_log(env, ", %u %s", args[i].type,
 | 
							btf_verifier_log(env, ", %u %s", args[i].type,
 | 
				
			||||||
				 btf_name_by_offset(env->btf,
 | 
									 __btf_name_by_offset(env->btf,
 | 
				
			||||||
						      args[i].name_off));
 | 
											      args[i].name_off));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (nr_args > 1) {
 | 
						if (nr_args > 1) {
 | 
				
			||||||
| 
						 | 
					@ -1966,7 +1975,7 @@ static void btf_func_proto_log(struct btf_verifier_env *env,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (last_arg->type)
 | 
							if (last_arg->type)
 | 
				
			||||||
			btf_verifier_log(env, ", %u %s", last_arg->type,
 | 
								btf_verifier_log(env, ", %u %s", last_arg->type,
 | 
				
			||||||
					 btf_name_by_offset(env->btf,
 | 
										 __btf_name_by_offset(env->btf,
 | 
				
			||||||
							      last_arg->name_off));
 | 
												      last_arg->name_off));
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			btf_verifier_log(env, ", vararg");
 | 
								btf_verifier_log(env, ", vararg");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4910,8 +4910,8 @@ static int check_btf_line(struct bpf_verifier_env *env,
 | 
				
			||||||
			goto err_free;
 | 
								goto err_free;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!btf_name_offset_valid(btf, linfo[i].line_off) ||
 | 
							if (!btf_name_by_offset(btf, linfo[i].line_off) ||
 | 
				
			||||||
		    !btf_name_offset_valid(btf, linfo[i].file_name_off)) {
 | 
							    !btf_name_by_offset(btf, linfo[i].file_name_off)) {
 | 
				
			||||||
			verbose(env, "Invalid line_info[%u].line_off or .file_name_off\n", i);
 | 
								verbose(env, "Invalid line_info[%u].line_off or .file_name_off\n", i);
 | 
				
			||||||
			err = -EINVAL;
 | 
								err = -EINVAL;
 | 
				
			||||||
			goto err_free;
 | 
								goto err_free;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue