Lines Matching refs:linker

158 static int init_output_elf(struct bpf_linker *linker, const char *file);
160 static int linker_load_obj_file(struct bpf_linker *linker, const char *filename,
169 static int linker_append_sec_data(struct bpf_linker *linker, struct src_obj *obj);
170 static int linker_append_elf_syms(struct bpf_linker *linker, struct src_obj *obj);
171 static int linker_append_elf_sym(struct bpf_linker *linker, struct src_obj *obj,
173 static int linker_append_elf_relos(struct bpf_linker *linker, struct src_obj *obj);
174 static int linker_append_btf(struct bpf_linker *linker, struct src_obj *obj);
175 static int linker_append_btf_ext(struct bpf_linker *linker, struct src_obj *obj);
177 static int finalize_btf(struct bpf_linker *linker);
178 static int finalize_btf_ext(struct bpf_linker *linker);
180 void bpf_linker__free(struct bpf_linker *linker) in bpf_linker__free() argument
184 if (!linker) in bpf_linker__free()
187 free(linker->filename); in bpf_linker__free()
189 if (linker->elf) in bpf_linker__free()
190 elf_end(linker->elf); in bpf_linker__free()
192 if (linker->fd >= 0) in bpf_linker__free()
193 close(linker->fd); in bpf_linker__free()
195 strset__free(linker->strtab_strs); in bpf_linker__free()
197 btf__free(linker->btf); in bpf_linker__free()
198 btf_ext__free(linker->btf_ext); in bpf_linker__free()
200 for (i = 1; i < linker->sec_cnt; i++) { in bpf_linker__free()
201 struct dst_sec *sec = &linker->secs[i]; in bpf_linker__free()
211 free(linker->secs); in bpf_linker__free()
213 free(linker); in bpf_linker__free()
218 struct bpf_linker *linker; in bpf_linker__new() local
229 linker = calloc(1, sizeof(*linker)); in bpf_linker__new()
230 if (!linker) in bpf_linker__new()
233 linker->fd = -1; in bpf_linker__new()
235 err = init_output_elf(linker, filename); in bpf_linker__new()
239 return linker; in bpf_linker__new()
242 bpf_linker__free(linker); in bpf_linker__new()
246 static struct dst_sec *add_dst_sec(struct bpf_linker *linker, const char *sec_name) in add_dst_sec() argument
248 struct dst_sec *secs = linker->secs, *sec; in add_dst_sec()
249 size_t new_cnt = linker->sec_cnt ? linker->sec_cnt + 1 : 2; in add_dst_sec()
256 memset(secs + linker->sec_cnt, 0, (new_cnt - linker->sec_cnt) * sizeof(*secs)); in add_dst_sec()
258 linker->secs = secs; in add_dst_sec()
259 linker->sec_cnt = new_cnt; in add_dst_sec()
261 sec = &linker->secs[new_cnt - 1]; in add_dst_sec()
270 static Elf64_Sym *add_new_sym(struct bpf_linker *linker, size_t *sym_idx) in add_new_sym() argument
272 struct dst_sec *symtab = &linker->secs[linker->symtab_sec_idx]; in add_new_sym()
294 static int init_output_elf(struct bpf_linker *linker, const char *file) in init_output_elf() argument
300 linker->filename = strdup(file); in init_output_elf()
301 if (!linker->filename) in init_output_elf()
304 linker->fd = open(file, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644); in init_output_elf()
305 if (linker->fd < 0) { in init_output_elf()
311 linker->elf = elf_begin(linker->fd, ELF_C_WRITE, NULL); in init_output_elf()
312 if (!linker->elf) { in init_output_elf()
318 linker->elf_hdr = elf64_newehdr(linker->elf); in init_output_elf()
319 if (!linker->elf_hdr) { in init_output_elf()
324 linker->elf_hdr->e_machine = EM_BPF; in init_output_elf()
325 linker->elf_hdr->e_type = ET_REL; in init_output_elf()
327 linker->elf_hdr->e_ident[EI_DATA] = ELFDATA2LSB; in init_output_elf()
329 linker->elf_hdr->e_ident[EI_DATA] = ELFDATA2MSB; in init_output_elf()
336 linker->strtab_strs = strset__new(INT_MAX, "", sizeof("")); in init_output_elf()
337 if (libbpf_get_error(linker->strtab_strs)) in init_output_elf()
338 return libbpf_get_error(linker->strtab_strs); in init_output_elf()
340 sec = add_dst_sec(linker, ".strtab"); in init_output_elf()
344 sec->scn = elf_newscn(linker->elf); in init_output_elf()
360 str_off = strset__add_str(linker->strtab_strs, sec->sec_name); in init_output_elf()
365 linker->elf_hdr->e_shstrndx = sec->sec_idx; in init_output_elf()
366 linker->strtab_sec_idx = sec->sec_idx; in init_output_elf()
379 sec = add_dst_sec(linker, ".symtab"); in init_output_elf()
383 sec->scn = elf_newscn(linker->elf); in init_output_elf()
399 str_off = strset__add_str(linker->strtab_strs, sec->sec_name); in init_output_elf()
404 linker->symtab_sec_idx = sec->sec_idx; in init_output_elf()
410 sec->shdr->sh_link = linker->strtab_sec_idx; in init_output_elf()
419 linker->btf = btf__new_empty(); in init_output_elf()
420 err = libbpf_get_error(linker->btf); in init_output_elf()
425 init_sym = add_new_sym(linker, NULL); in init_output_elf()
439 int bpf_linker__add_file(struct bpf_linker *linker, const char *filename, in bpf_linker__add_file() argument
448 if (!linker->elf) in bpf_linker__add_file()
451 err = err ?: linker_load_obj_file(linker, filename, opts, &obj); in bpf_linker__add_file()
452 err = err ?: linker_append_sec_data(linker, &obj); in bpf_linker__add_file()
453 err = err ?: linker_append_elf_syms(linker, &obj); in bpf_linker__add_file()
454 err = err ?: linker_append_elf_relos(linker, &obj); in bpf_linker__add_file()
455 err = err ?: linker_append_btf(linker, &obj); in bpf_linker__add_file()
456 err = err ?: linker_append_btf_ext(linker, &obj); in bpf_linker__add_file()
537 static int linker_load_obj_file(struct bpf_linker *linker, const char *filename, in linker_load_obj_file() argument
982 static int init_sec(struct bpf_linker *linker, struct dst_sec *dst_sec, struct src_sec *src_sec) in init_sec() argument
997 scn = elf_newscn(linker->elf); in init_sec()
1012 name_off = strset__add_str(linker->strtab_strs, src_sec->sec_name); in init_sec()
1038 static struct dst_sec *find_dst_sec_by_name(struct bpf_linker *linker, const char *sec_name) in find_dst_sec_by_name() argument
1043 for (i = 1; i < linker->sec_cnt; i++) { in find_dst_sec_by_name()
1044 sec = &linker->secs[i]; in find_dst_sec_by_name()
1083 static int extend_sec(struct bpf_linker *linker, struct dst_sec *dst, struct src_sec *src) in extend_sec() argument
1103 err = init_sec(linker, dst, src); in extend_sec()
1161 static int linker_append_sec_data(struct bpf_linker *linker, struct src_obj *obj) in linker_append_sec_data() argument
1173 dst_sec = find_dst_sec_by_name(linker, src_sec->sec_name); in linker_append_sec_data()
1175 dst_sec = add_dst_sec(linker, src_sec->sec_name); in linker_append_sec_data()
1178 err = init_sec(linker, dst_sec, src_sec); in linker_append_sec_data()
1205 err = extend_sec(linker, dst_sec, src_sec); in linker_append_sec_data()
1213 static int linker_append_elf_syms(struct bpf_linker *linker, struct src_obj *obj) in linker_append_elf_syms() argument
1238 err = linker_append_elf_sym(linker, obj, sym, sym_name, i); in linker_append_elf_syms()
1246 static Elf64_Sym *get_sym_by_idx(struct bpf_linker *linker, size_t sym_idx) in get_sym_by_idx() argument
1248 struct dst_sec *symtab = &linker->secs[linker->symtab_sec_idx]; in get_sym_by_idx()
1254 static struct glob_sym *find_glob_sym(struct bpf_linker *linker, const char *sym_name) in find_glob_sym() argument
1260 for (i = 0; i < linker->glob_sym_cnt; i++) { in find_glob_sym()
1261 glob_sym = &linker->glob_syms[i]; in find_glob_sym()
1262 name = strset__data(linker->strtab_strs) + glob_sym->name_off; in find_glob_sym()
1271 static struct glob_sym *add_glob_sym(struct bpf_linker *linker) in add_glob_sym() argument
1275 syms = libbpf_reallocarray(linker->glob_syms, linker->glob_sym_cnt + 1, in add_glob_sym()
1276 sizeof(*linker->glob_syms)); in add_glob_sym()
1280 sym = &syms[linker->glob_sym_cnt]; in add_glob_sym()
1284 linker->glob_syms = syms; in add_glob_sym()
1285 linker->glob_sym_cnt++; in add_glob_sym()
1571 struct bpf_linker *linker, struct glob_sym *glob_sym, in glob_map_defs_match() argument
1593 t = btf__type_by_id(linker->btf, glob_sym->btf_id); in glob_map_defs_match()
1594 t = skip_mods_and_typedefs(linker->btf, t->type, NULL); in glob_map_defs_match()
1595 err = parse_btf_map_def(sym_name, linker->btf, t, true /*strict*/, &dst_def, &dst_inner_def); in glob_map_defs_match()
1606 return map_defs_match(sym_name, linker->btf, &dst_def, &dst_inner_def, in glob_map_defs_match()
1611 struct bpf_linker *linker, struct glob_sym *glob_sym, in glob_syms_match() argument
1632 if (glob_sym->sec_id && strcmp(linker->secs[glob_sym->sec_id].sec_name, MAPS_ELF_SEC) == 0) in glob_syms_match()
1633 return glob_map_defs_match(sym_name, linker, glob_sym, obj, sym, btf_id); in glob_syms_match()
1636 linker->btf, glob_sym->btf_id, obj->btf, btf_id)) in glob_syms_match()
1801 static int linker_append_elf_sym(struct bpf_linker *linker, struct src_obj *obj, in linker_append_elf_sym() argument
1827 dst_sec = &linker->secs[src_sec->dst_id]; in linker_append_elf_sym()
1863 dst_sec = &linker->secs[src_sec->dst_id]; in linker_append_elf_sym()
1867 glob_sym = find_glob_sym(linker, sym_name); in linker_append_elf_sym()
1886 if (!glob_syms_match(sym_name, linker, glob_sym, obj, sym, src_sym_idx, btf_id)) in linker_append_elf_sym()
1889 dst_sym = get_sym_by_idx(linker, glob_sym->sym_idx); in linker_append_elf_sym()
1942 if (complete_extern_btf_info(linker->btf, glob_sym->btf_id, in linker_append_elf_sym()
1954 name_off = strset__add_str(linker->strtab_strs, sym_name); in linker_append_elf_sym()
1958 dst_sym = add_new_sym(linker, &dst_sym_idx); in linker_append_elf_sym()
1977 glob_sym = add_glob_sym(linker); in linker_append_elf_sym()
1999 static int linker_append_elf_relos(struct bpf_linker *linker, struct src_obj *obj) in linker_append_elf_relos() argument
2002 struct dst_sec *dst_symtab = &linker->secs[linker->symtab_sec_idx]; in linker_append_elf_relos()
2020 dst_sec = find_dst_sec_by_name(linker, src_sec->sec_name); in linker_append_elf_relos()
2022 dst_sec = add_dst_sec(linker, src_sec->sec_name); in linker_append_elf_relos()
2025 err = init_sec(linker, dst_sec, src_sec); in linker_append_elf_relos()
2036 dst_sec->shdr->sh_link = linker->symtab_sec_idx; in linker_append_elf_relos()
2039 dst_linked_sec = &linker->secs[src_linked_sec->dst_id]; in linker_append_elf_relos()
2043 err = extend_sec(linker, dst_sec, src_sec); in linker_append_elf_relos()
2228 static int linker_append_btf(struct bpf_linker *linker, struct src_obj *obj) in linker_append_btf() argument
2237 start_id = btf__type_cnt(linker->btf); in linker_append_btf()
2256 glob_sym = find_glob_sym(linker, name); in linker_append_btf()
2283 id = btf__add_type(linker->btf, obj->btf, t); in linker_append_btf()
2299 n = btf__type_cnt(linker->btf); in linker_append_btf()
2301 struct btf_type *dst_t = btf_type_by_id(linker->btf, i); in linker_append_btf()
2310 for (i = 0; i < linker->glob_sym_cnt; i++) { in linker_append_btf()
2311 struct glob_sym *glob_sym = &linker->glob_syms[i]; in linker_append_btf()
2319 glob_t = btf_type_by_id(linker->btf, glob_sym->btf_id); in linker_append_btf()
2333 dst_sec = &linker->secs[src_sec->dst_id]; in linker_append_btf()
2353 t = btf_type_by_id(linker->btf, new_id); in linker_append_btf()
2355 name = btf__str_by_offset(linker->btf, t->name_off); in linker_append_btf()
2356 glob_sym = find_glob_sym(linker, name); in linker_append_btf()
2377 sz = btf__resolve_size(linker->btf, glob_sym->underlying_btf_id); in linker_append_btf()
2426 static int linker_append_btf_ext(struct bpf_linker *linker, struct src_obj *obj) in linker_append_btf_ext() argument
2447 dst_sec = &linker->secs[src_sec->dst_id]; in linker_append_btf_ext()
2476 dst_sec = &linker->secs[src_sec->dst_id]; in linker_append_btf_ext()
2493 str_off = btf__add_str(linker->btf, s); in linker_append_btf_ext()
2499 str_off = btf__add_str(linker->btf, s); in linker_append_btf_ext()
2518 dst_sec = &linker->secs[src_sec->dst_id]; in linker_append_btf_ext()
2536 str_off = btf__add_str(linker->btf, s); in linker_append_btf_ext()
2548 int bpf_linker__finalize(struct bpf_linker *linker) in bpf_linker__finalize() argument
2555 if (!linker->elf) in bpf_linker__finalize()
2558 err = finalize_btf(linker); in bpf_linker__finalize()
2563 strs_sz = strset__data_size(linker->strtab_strs); in bpf_linker__finalize()
2564 strs = strset__data(linker->strtab_strs); in bpf_linker__finalize()
2566 sec = &linker->secs[linker->strtab_sec_idx]; in bpf_linker__finalize()
2574 for (i = 1; i < linker->sec_cnt; i++) { in bpf_linker__finalize()
2575 sec = &linker->secs[i]; in bpf_linker__finalize()
2578 if (sec->sec_idx == linker->strtab_sec_idx) in bpf_linker__finalize()
2589 if (elf_update(linker->elf, ELF_C_NULL) < 0) { in bpf_linker__finalize()
2596 if (elf_update(linker->elf, ELF_C_WRITE) < 0) { in bpf_linker__finalize()
2602 elf_end(linker->elf); in bpf_linker__finalize()
2603 close(linker->fd); in bpf_linker__finalize()
2605 linker->elf = NULL; in bpf_linker__finalize()
2606 linker->fd = -1; in bpf_linker__finalize()
2611 static int emit_elf_data_sec(struct bpf_linker *linker, const char *sec_name, in emit_elf_data_sec() argument
2619 name_off = strset__add_str(linker->strtab_strs, sec_name); in emit_elf_data_sec()
2623 scn = elf_newscn(linker->elf); in emit_elf_data_sec()
2651 static int finalize_btf(struct bpf_linker *linker) in finalize_btf() argument
2653 struct btf *btf = linker->btf; in finalize_btf()
2659 if (btf__type_cnt(linker->btf) == 1) in finalize_btf()
2662 for (i = 1; i < linker->sec_cnt; i++) { in finalize_btf()
2663 struct dst_sec *sec = &linker->secs[i]; in finalize_btf()
2683 err = finalize_btf_ext(linker); in finalize_btf()
2689 err = btf__dedup(linker->btf, linker->btf_ext, NULL); in finalize_btf()
2696 raw_data = btf__raw_data(linker->btf, &raw_sz); in finalize_btf()
2700 err = emit_elf_data_sec(linker, BTF_ELF_SEC, 8, raw_data, raw_sz); in finalize_btf()
2707 if (linker->btf_ext) { in finalize_btf()
2708 raw_data = btf_ext__get_raw_data(linker->btf_ext, &raw_sz); in finalize_btf()
2712 err = emit_elf_data_sec(linker, BTF_EXT_ELF_SEC, 8, raw_data, raw_sz); in finalize_btf()
2722 static int emit_btf_ext_data(struct bpf_linker *linker, void *output, in emit_btf_ext_data() argument
2733 str_off = btf__add_str(linker->btf, sec_name); in emit_btf_ext_data()
2749 static int finalize_btf_ext(struct bpf_linker *linker) in finalize_btf_ext() argument
2761 for (i = 1; i < linker->sec_cnt; i++) { in finalize_btf_ext()
2762 struct dst_sec *sec = &linker->secs[i]; in finalize_btf_ext()
2839 for (i = 1; i < linker->sec_cnt; i++) { in finalize_btf_ext()
2840 struct dst_sec *sec = &linker->secs[i]; in finalize_btf_ext()
2842 sz = emit_btf_ext_data(linker, cur, sec->sec_name, &sec->func_info); in finalize_btf_ext()
2856 for (i = 1; i < linker->sec_cnt; i++) { in finalize_btf_ext()
2857 struct dst_sec *sec = &linker->secs[i]; in finalize_btf_ext()
2859 sz = emit_btf_ext_data(linker, cur, sec->sec_name, &sec->line_info); in finalize_btf_ext()
2873 for (i = 1; i < linker->sec_cnt; i++) { in finalize_btf_ext()
2874 struct dst_sec *sec = &linker->secs[i]; in finalize_btf_ext()
2876 sz = emit_btf_ext_data(linker, cur, sec->sec_name, &sec->core_relo_info); in finalize_btf_ext()
2886 linker->btf_ext = btf_ext__new(data, total_sz); in finalize_btf_ext()
2887 err = libbpf_get_error(linker->btf_ext); in finalize_btf_ext()
2889 linker->btf_ext = NULL; in finalize_btf_ext()