Lines Matching refs:linker
3 * BPF static 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)
184 if (!linker)
187 free(linker->filename);
189 if (linker->elf)
190 elf_end(linker->elf);
192 if (linker->fd >= 0)
193 close(linker->fd);
195 strset__free(linker->strtab_strs);
197 btf__free(linker->btf);
198 btf_ext__free(linker->btf_ext);
200 for (i = 1; i < linker->sec_cnt; i++) {
201 struct dst_sec *sec = &linker->secs[i];
211 free(linker->secs);
213 free(linker->glob_syms);
214 free(linker);
219 struct bpf_linker *linker;
230 linker = calloc(1, sizeof(*linker));
231 if (!linker)
234 linker->fd = -1;
236 err = init_output_elf(linker, filename);
240 return linker;
243 bpf_linker__free(linker);
247 static struct dst_sec *add_dst_sec(struct bpf_linker *linker, const char *sec_name)
249 struct dst_sec *secs = linker->secs, *sec;
250 size_t new_cnt = linker->sec_cnt ? linker->sec_cnt + 1 : 2;
257 memset(secs + linker->sec_cnt, 0, (new_cnt - linker->sec_cnt) * sizeof(*secs));
259 linker->secs = secs;
260 linker->sec_cnt = new_cnt;
262 sec = &linker->secs[new_cnt - 1];
271 static Elf64_Sym *add_new_sym(struct bpf_linker *linker, size_t *sym_idx)
273 struct dst_sec *symtab = &linker->secs[linker->symtab_sec_idx];
295 static int init_output_elf(struct bpf_linker *linker, const char *file)
301 linker->filename = strdup(file);
302 if (!linker->filename)
305 linker->fd = open(file, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
306 if (linker->fd < 0) {
312 linker->elf = elf_begin(linker->fd, ELF_C_WRITE, NULL);
313 if (!linker->elf) {
319 linker->elf_hdr = elf64_newehdr(linker->elf);
320 if (!linker->elf_hdr) {
325 linker->elf_hdr->e_machine = EM_BPF;
326 linker->elf_hdr->e_type = ET_REL;
328 linker->elf_hdr->e_ident[EI_DATA] = ELFDATA2LSB;
330 linker->elf_hdr->e_ident[EI_DATA] = ELFDATA2MSB;
337 linker->strtab_strs = strset__new(INT_MAX, "", sizeof(""));
338 if (libbpf_get_error(linker->strtab_strs))
339 return libbpf_get_error(linker->strtab_strs);
341 sec = add_dst_sec(linker, ".strtab");
345 sec->scn = elf_newscn(linker->elf);
361 str_off = strset__add_str(linker->strtab_strs, sec->sec_name);
366 linker->elf_hdr->e_shstrndx = sec->sec_idx;
367 linker->strtab_sec_idx = sec->sec_idx;
380 sec = add_dst_sec(linker, ".symtab");
384 sec->scn = elf_newscn(linker->elf);
400 str_off = strset__add_str(linker->strtab_strs, sec->sec_name);
405 linker->symtab_sec_idx = sec->sec_idx;
411 sec->shdr->sh_link = linker->strtab_sec_idx;
420 linker->btf = btf__new_empty();
421 err = libbpf_get_error(linker->btf);
426 init_sym = add_new_sym(linker, NULL);
440 int bpf_linker__add_file(struct bpf_linker *linker, const char *filename,
449 if (!linker->elf)
452 err = err ?: linker_load_obj_file(linker, filename, opts, &obj);
453 err = err ?: linker_append_sec_data(linker, &obj);
454 err = err ?: linker_append_elf_syms(linker, &obj);
455 err = err ?: linker_append_elf_relos(linker, &obj);
456 err = err ?: linker_append_btf(linker, &obj);
457 err = err ?: linker_append_btf_ext(linker, &obj);
538 static int linker_load_obj_file(struct bpf_linker *linker, const char *filename,
556 pr_debug("linker: adding object file '%s'...\n", filename);
978 static int init_sec(struct bpf_linker *linker, struct dst_sec *dst_sec, struct src_sec *src_sec)
993 scn = elf_newscn(linker->elf);
1008 name_off = strset__add_str(linker->strtab_strs, src_sec->sec_name);
1034 static struct dst_sec *find_dst_sec_by_name(struct bpf_linker *linker, const char *sec_name)
1039 for (i = 1; i < linker->sec_cnt; i++) {
1040 sec = &linker->secs[i];
1079 static int extend_sec(struct bpf_linker *linker, struct dst_sec *dst, struct src_sec *src)
1099 err = init_sec(linker, dst, src);
1169 static int linker_append_sec_data(struct bpf_linker *linker, struct src_obj *obj)
1181 dst_sec = find_dst_sec_by_name(linker, src_sec->sec_name);
1183 dst_sec = add_dst_sec(linker, src_sec->sec_name);
1186 err = init_sec(linker, dst_sec, src_sec);
1213 err = extend_sec(linker, dst_sec, src_sec);
1221 static int linker_append_elf_syms(struct bpf_linker *linker, struct src_obj *obj)
1246 err = linker_append_elf_sym(linker, obj, sym, sym_name, i);
1254 static Elf64_Sym *get_sym_by_idx(struct bpf_linker *linker, size_t sym_idx)
1256 struct dst_sec *symtab = &linker->secs[linker->symtab_sec_idx];
1262 static struct glob_sym *find_glob_sym(struct bpf_linker *linker, const char *sym_name)
1268 for (i = 0; i < linker->glob_sym_cnt; i++) {
1269 glob_sym = &linker->glob_syms[i];
1270 name = strset__data(linker->strtab_strs) + glob_sym->name_off;
1279 static struct glob_sym *add_glob_sym(struct bpf_linker *linker)
1283 syms = libbpf_reallocarray(linker->glob_syms, linker->glob_sym_cnt + 1,
1284 sizeof(*linker->glob_syms));
1288 sym = &syms[linker->glob_sym_cnt];
1292 linker->glob_syms = syms;
1293 linker->glob_sym_cnt++;
1581 struct bpf_linker *linker, struct glob_sym *glob_sym,
1603 t = btf__type_by_id(linker->btf, glob_sym->btf_id);
1604 t = skip_mods_and_typedefs(linker->btf, t->type, NULL);
1605 err = parse_btf_map_def(sym_name, linker->btf, t, true /*strict*/, &dst_def, &dst_inner_def);
1616 return map_defs_match(sym_name, linker->btf, &dst_def, &dst_inner_def,
1621 struct bpf_linker *linker, struct glob_sym *glob_sym,
1642 if (glob_sym->sec_id && strcmp(linker->secs[glob_sym->sec_id].sec_name, MAPS_ELF_SEC) == 0)
1643 return glob_map_defs_match(sym_name, linker, glob_sym, obj, sym, btf_id);
1646 linker->btf, glob_sym->btf_id, obj->btf, btf_id))
1811 static int linker_append_elf_sym(struct bpf_linker *linker, struct src_obj *obj,
1837 dst_sec = &linker->secs[src_sec->dst_id];
1873 dst_sec = &linker->secs[src_sec->dst_id];
1877 glob_sym = find_glob_sym(linker, sym_name);
1896 if (!glob_syms_match(sym_name, linker, glob_sym, obj, sym, src_sym_idx, btf_id))
1899 dst_sym = get_sym_by_idx(linker, glob_sym->sym_idx);
1952 if (complete_extern_btf_info(linker->btf, glob_sym->btf_id,
1964 name_off = strset__add_str(linker->strtab_strs, sym_name);
1968 dst_sym = add_new_sym(linker, &dst_sym_idx);
1987 glob_sym = add_glob_sym(linker);
2009 static int linker_append_elf_relos(struct bpf_linker *linker, struct src_obj *obj)
2029 dst_sec = find_dst_sec_by_name(linker, src_sec->sec_name);
2031 dst_sec = add_dst_sec(linker, src_sec->sec_name);
2034 err = init_sec(linker, dst_sec, src_sec);
2045 dst_sec->shdr->sh_link = linker->symtab_sec_idx;
2048 dst_linked_sec = &linker->secs[src_linked_sec->dst_id];
2052 err = extend_sec(linker, dst_sec, src_sec);
2166 * by static linker, not libbpf and kernel. When such
2234 static int linker_append_btf(struct bpf_linker *linker, struct src_obj *obj)
2243 start_id = btf__type_cnt(linker->btf);
2262 glob_sym = find_glob_sym(linker, name);
2289 id = btf__add_type(linker->btf, obj->btf, t);
2305 n = btf__type_cnt(linker->btf);
2307 struct btf_type *dst_t = btf_type_by_id(linker->btf, i);
2316 for (i = 0; i < linker->glob_sym_cnt; i++) {
2317 struct glob_sym *glob_sym = &linker->glob_syms[i];
2325 glob_t = btf_type_by_id(linker->btf, glob_sym->btf_id);
2339 dst_sec = &linker->secs[src_sec->dst_id];
2359 t = btf_type_by_id(linker->btf, new_id);
2361 name = btf__str_by_offset(linker->btf, t->name_off);
2362 glob_sym = find_glob_sym(linker, name);
2383 sz = btf__resolve_size(linker->btf, glob_sym->underlying_btf_id);
2432 static int linker_append_btf_ext(struct bpf_linker *linker, struct src_obj *obj)
2453 dst_sec = &linker->secs[src_sec->dst_id];
2482 dst_sec = &linker->secs[src_sec->dst_id];
2499 str_off = btf__add_str(linker->btf, s);
2505 str_off = btf__add_str(linker->btf, s);
2524 dst_sec = &linker->secs[src_sec->dst_id];
2542 str_off = btf__add_str(linker->btf, s);
2554 int bpf_linker__finalize(struct bpf_linker *linker)
2561 if (!linker->elf)
2564 err = finalize_btf(linker);
2569 strs_sz = strset__data_size(linker->strtab_strs);
2570 strs = strset__data(linker->strtab_strs);
2572 sec = &linker->secs[linker->strtab_sec_idx];
2580 for (i = 1; i < linker->sec_cnt; i++) {
2581 sec = &linker->secs[i];
2584 if (sec->sec_idx == linker->strtab_sec_idx)
2595 if (elf_update(linker->elf, ELF_C_NULL) < 0) {
2602 if (elf_update(linker->elf, ELF_C_WRITE) < 0) {
2608 elf_end(linker->elf);
2609 close(linker->fd);
2611 linker->elf = NULL;
2612 linker->fd = -1;
2617 static int emit_elf_data_sec(struct bpf_linker *linker, const char *sec_name,
2625 name_off = strset__add_str(linker->strtab_strs, sec_name);
2629 scn = elf_newscn(linker->elf);
2657 static int finalize_btf(struct bpf_linker *linker)
2660 struct btf *btf = linker->btf;
2666 if (btf__type_cnt(linker->btf) == 1)
2669 for (i = 1; i < linker->sec_cnt; i++) {
2670 struct dst_sec *sec = &linker->secs[i];
2690 err = finalize_btf_ext(linker);
2696 opts.btf_ext = linker->btf_ext;
2697 err = btf__dedup(linker->btf, &opts);
2704 raw_data = btf__raw_data(linker->btf, &raw_sz);
2708 err = emit_elf_data_sec(linker, BTF_ELF_SEC, 8, raw_data, raw_sz);
2715 if (linker->btf_ext) {
2716 raw_data = btf_ext__get_raw_data(linker->btf_ext, &raw_sz);
2720 err = emit_elf_data_sec(linker, BTF_EXT_ELF_SEC, 8, raw_data, raw_sz);
2730 static int emit_btf_ext_data(struct bpf_linker *linker, void *output,
2741 str_off = btf__add_str(linker->btf, sec_name);
2757 static int finalize_btf_ext(struct bpf_linker *linker)
2769 for (i = 1; i < linker->sec_cnt; i++) {
2770 struct dst_sec *sec = &linker->secs[i];
2847 for (i = 1; i < linker->sec_cnt; i++) {
2848 struct dst_sec *sec = &linker->secs[i];
2850 sz = emit_btf_ext_data(linker, cur, sec->sec_name, &sec->func_info);
2864 for (i = 1; i < linker->sec_cnt; i++) {
2865 struct dst_sec *sec = &linker->secs[i];
2867 sz = emit_btf_ext_data(linker, cur, sec->sec_name, &sec->line_info);
2881 for (i = 1; i < linker->sec_cnt; i++) {
2882 struct dst_sec *sec = &linker->secs[i];
2884 sz = emit_btf_ext_data(linker, cur, sec->sec_name, &sec->core_relo_info);
2894 linker->btf_ext = btf_ext__new(data, total_sz);
2895 err = libbpf_get_error(linker->btf_ext);
2897 linker->btf_ext = NULL;