Lines Matching +full:- +full:section
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * elf.c - ELF access library
6 * Copyright (C) 2013-2015 Josh Poimboeuf <[email protected]>
30 #define __elf_table(name) (elf->name##_hash)
31 #define __elf_bits(name) (elf->name##_bits)
39 __node->next = __elf_table_entry(name, key); \
49 *head = node->next; in __elf_hash_del()
53 for (prev = NULL, cur = *head; cur; prev = cur, cur = cur->next) { in __elf_hash_del()
55 prev->next = cur->next; in __elf_hash_del()
73 obj = elf_list_entry(obj->member.next, typeof(*(obj)), member))
80 MAP_PRIVATE|MAP_ANON, -1, 0); \
81 if (__elf_table(name) == (void *)-1L) { \
90 return s->offset; in __sym_start()
95 return s->offset + s->len - 1; in __sym_last()
111 * Find !section symbol where @offset is after it.
118 if (sh->key < s->offset) in symbol_hole_by_offset()
119 return -1; in symbol_hole_by_offset()
121 if (sh->key >= s->offset + s->len) { in symbol_hole_by_offset()
122 if (s->type != STT_SECTION) in symbol_hole_by_offset()
123 sh->sym = s; in symbol_hole_by_offset()
130 struct section *find_section_by_name(const struct elf *elf, const char *name) in find_section_by_name()
132 struct section *sec; in find_section_by_name()
135 if (!strcmp(sec->name, name)) in find_section_by_name()
142 static struct section *find_section_by_index(struct elf *elf, in find_section_by_index()
145 struct section *sec; in find_section_by_index()
147 elf_hash_for_each_possible(section, sec, hash, idx) { in find_section_by_index()
148 if (sec->idx == idx) in find_section_by_index()
160 if (sym->idx == idx) in find_symbol_by_index()
167 struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset) in find_symbol_by_offset()
169 struct rb_root_cached *tree = (struct rb_root_cached *)&sec->symbol_tree; in find_symbol_by_offset()
173 if (iter->offset == offset && iter->type != STT_SECTION) in find_symbol_by_offset()
180 struct symbol *find_func_by_offset(struct section *sec, unsigned long offset) in find_func_by_offset()
182 struct rb_root_cached *tree = (struct rb_root_cached *)&sec->symbol_tree; in find_func_by_offset()
186 if (iter->offset == offset && iter->type == STT_FUNC) in find_func_by_offset()
193 struct symbol *find_symbol_containing(const struct section *sec, unsigned long offset) in find_symbol_containing()
195 struct rb_root_cached *tree = (struct rb_root_cached *)&sec->symbol_tree; in find_symbol_containing()
199 if (iter->type != STT_SECTION) in find_symbol_containing()
209 int find_symbol_hole_containing(const struct section *sec, unsigned long offset) in find_symbol_hole_containing()
221 n = rb_find(&hole, &sec->symbol_tree.rb_root, symbol_hole_by_offset); in find_symbol_hole_containing()
228 * @offset >= sym->offset + sym->len, find symbol after it. in find_symbol_hole_containing()
230 * If there is no symbol in the section, the first node will be NULL, in find_symbol_hole_containing()
231 * in which case, -1 is returned to skip the whole section. in find_symbol_hole_containing()
234 n = rb_next(&hole.sym->node); in find_symbol_hole_containing()
236 n = rb_first_cached(&sec->symbol_tree); in find_symbol_hole_containing()
239 return -1; /* until end of address space */ in find_symbol_hole_containing()
243 return s->offset - offset; in find_symbol_hole_containing()
246 struct symbol *find_func_containing(struct section *sec, unsigned long offset) in find_func_containing()
248 struct rb_root_cached *tree = (struct rb_root_cached *)&sec->symbol_tree; in find_func_containing()
252 if (iter->type == STT_FUNC) in find_func_containing()
264 if (!strcmp(sym->name, name)) in find_symbol_by_name()
271 struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec, in find_reloc_by_dest_range()
275 struct section *rsec; in find_reloc_by_dest_range()
278 rsec = sec->rsec; in find_reloc_by_dest_range()
285 if (reloc->sec != rsec) in find_reloc_by_dest_range()
301 struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset) in find_reloc_by_dest()
306 static bool is_dwarf_section(struct section *sec) in is_dwarf_section()
308 return !strncmp(sec->name, ".debug_", 7); in is_dwarf_section()
314 struct section *sec; in read_sections()
318 if (elf_getshdrnum(elf->elf, §ions_nr)) { in read_sections()
320 return -1; in read_sections()
323 if (elf_getshdrstrndx(elf->elf, &shstrndx)) { in read_sections()
325 return -1; in read_sections()
328 if (!elf_alloc_hash(section, sections_nr) || in read_sections()
330 return -1; in read_sections()
332 elf->section_data = calloc(sections_nr, sizeof(*sec)); in read_sections()
333 if (!elf->section_data) { in read_sections()
335 return -1; in read_sections()
338 sec = &elf->section_data[i]; in read_sections()
340 INIT_LIST_HEAD(&sec->symbol_list); in read_sections()
342 s = elf_getscn(elf->elf, i); in read_sections()
345 return -1; in read_sections()
348 sec->idx = elf_ndxscn(s); in read_sections()
350 if (!gelf_getshdr(s, &sec->sh)) { in read_sections()
352 return -1; in read_sections()
355 sec->name = elf_strptr(elf->elf, shstrndx, sec->sh.sh_name); in read_sections()
356 if (!sec->name) { in read_sections()
358 return -1; in read_sections()
361 if (sec->sh.sh_size != 0 && !is_dwarf_section(sec)) { in read_sections()
362 sec->data = elf_getdata(s, NULL); in read_sections()
363 if (!sec->data) { in read_sections()
365 return -1; in read_sections()
367 if (sec->data->d_off != 0 || in read_sections()
368 sec->data->d_size != sec->sh.sh_size) { in read_sections()
370 sec->name); in read_sections()
371 return -1; in read_sections()
375 list_add_tail(&sec->list, &elf->sections); in read_sections()
376 elf_hash_add(section, &sec->hash, sec->idx); in read_sections()
377 elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name)); in read_sections()
380 elf->num_relocs += sec_num_entries(sec); in read_sections()
385 printf("section_bits: %d\n", elf->section_bits); in read_sections()
389 if (elf_nextscn(elf->elf, s)) { in read_sections()
390 WARN("section entry mismatch"); in read_sections()
391 return -1; in read_sections()
403 INIT_LIST_HEAD(&sym->pv_target); in elf_add_symbol()
404 sym->alias = sym; in elf_add_symbol()
406 sym->type = GELF_ST_TYPE(sym->sym.st_info); in elf_add_symbol()
407 sym->bind = GELF_ST_BIND(sym->sym.st_info); in elf_add_symbol()
409 if (sym->type == STT_FILE) in elf_add_symbol()
410 elf->num_files++; in elf_add_symbol()
412 sym->offset = sym->sym.st_value; in elf_add_symbol()
413 sym->len = sym->sym.st_size; in elf_add_symbol()
415 __sym_for_each(iter, &sym->sec->symbol_tree, sym->offset, sym->offset) { in elf_add_symbol()
416 if (iter->offset == sym->offset && iter->type == sym->type) in elf_add_symbol()
417 iter->alias = sym; in elf_add_symbol()
420 __sym_insert(sym, &sym->sec->symbol_tree); in elf_add_symbol()
421 pnode = rb_prev(&sym->node); in elf_add_symbol()
423 entry = &rb_entry(pnode, struct symbol, node)->list; in elf_add_symbol()
425 entry = &sym->sec->symbol_list; in elf_add_symbol()
426 list_add(&sym->list, entry); in elf_add_symbol()
427 elf_hash_add(symbol, &sym->hash, sym->idx); in elf_add_symbol()
428 elf_hash_add(symbol_name, &sym->name_hash, str_hash(sym->name)); in elf_add_symbol()
434 if (!sym->len) in elf_add_symbol()
435 __sym_remove(sym, &sym->sec->symbol_tree); in elf_add_symbol()
440 struct section *symtab, *symtab_shndx, *sec; in read_symbols()
451 shndx_data = symtab_shndx->data; in read_symbols()
466 return -1; in read_symbols()
468 elf->symbol_data = calloc(symbols_nr, sizeof(*sym)); in read_symbols()
469 if (!elf->symbol_data) { in read_symbols()
471 return -1; in read_symbols()
474 sym = &elf->symbol_data[i]; in read_symbols()
476 sym->idx = i; in read_symbols()
478 if (!gelf_getsymshndx(symtab->data, shndx_data, i, &sym->sym, in read_symbols()
484 sym->name = elf_strptr(elf->elf, symtab->sh.sh_link, in read_symbols()
485 sym->sym.st_name); in read_symbols()
486 if (!sym->name) { in read_symbols()
491 if ((sym->sym.st_shndx > SHN_UNDEF && in read_symbols()
492 sym->sym.st_shndx < SHN_LORESERVE) || in read_symbols()
493 (shndx_data && sym->sym.st_shndx == SHN_XINDEX)) { in read_symbols()
494 if (sym->sym.st_shndx != SHN_XINDEX) in read_symbols()
495 shndx = sym->sym.st_shndx; in read_symbols()
497 sym->sec = find_section_by_index(elf, shndx); in read_symbols()
498 if (!sym->sec) { in read_symbols()
499 WARN("couldn't find section for symbol %s", in read_symbols()
500 sym->name); in read_symbols()
503 if (GELF_ST_TYPE(sym->sym.st_info) == STT_SECTION) { in read_symbols()
504 sym->name = sym->sec->name; in read_symbols()
505 sym->sec->sym = sym; in read_symbols()
508 sym->sec = find_section_by_index(elf, 0); in read_symbols()
515 printf("symbol_bits: %d\n", elf->symbol_bits); in read_symbols()
519 list_for_each_entry(sec, &elf->sections, list) { in read_symbols()
523 if (sym->type != STT_FUNC) in read_symbols()
526 if (sym->pfunc == NULL) in read_symbols()
527 sym->pfunc = sym; in read_symbols()
529 if (sym->cfunc == NULL) in read_symbols()
530 sym->cfunc = sym; in read_symbols()
532 coldstr = strstr(sym->name, ".cold"); in read_symbols()
536 pnamelen = coldstr - sym->name; in read_symbols()
537 pname = strndup(sym->name, pnamelen); in read_symbols()
540 sym->name); in read_symbols()
541 return -1; in read_symbols()
549 sym->name); in read_symbols()
550 return -1; in read_symbols()
553 sym->pfunc = pfunc; in read_symbols()
554 pfunc->cfunc = sym; in read_symbols()
557 * Unfortunately, -fnoreorder-functions puts the child in read_symbols()
561 * Note that pfunc->len now no longer matches in read_symbols()
562 * pfunc->sym.st_size. in read_symbols()
564 if (sym->sec == pfunc->sec && in read_symbols()
565 sym->offset >= pfunc->offset && in read_symbols()
566 sym->offset + sym->len == pfunc->offset + pfunc->len) { in read_symbols()
567 pfunc->len -= sym->len; in read_symbols()
576 return -1; in read_symbols()
586 for (reloc = sym->relocs; reloc; reloc = sym_next_reloc(reloc)) in elf_update_sym_relocs()
587 set_reloc_sym(elf, reloc, reloc->sym->idx); in elf_update_sym_relocs()
600 static int elf_update_symbol(struct elf *elf, struct section *symtab, in elf_update_symbol()
601 struct section *symtab_shndx, struct symbol *sym) in elf_update_symbol()
603 Elf32_Word shndx = sym->sec ? sym->sec->idx : SHN_UNDEF; in elf_update_symbol()
605 Elf64_Xword entsize = symtab->sh.sh_entsize; in elf_update_symbol()
606 int max_idx, idx = sym->idx; in elf_update_symbol()
608 bool is_special_shndx = sym->sym.st_shndx >= SHN_LORESERVE && in elf_update_symbol()
609 sym->sym.st_shndx != SHN_XINDEX; in elf_update_symbol()
612 shndx = sym->sym.st_shndx; in elf_update_symbol()
614 s = elf_getscn(elf->elf, symtab->idx); in elf_update_symbol()
617 return -1; in elf_update_symbol()
621 t = elf_getscn(elf->elf, symtab_shndx->idx); in elf_update_symbol()
624 return -1; in elf_update_symbol()
634 /* end-of-list */ in elf_update_symbol()
637 * Over-allocate to avoid O(n^2) symbol creation in elf_update_symbol()
641 int num = max(1U, sym->idx/3); in elf_update_symbol()
647 return -1; in elf_update_symbol()
658 return -1; in elf_update_symbol()
661 symtab_data->d_buf = buf; in elf_update_symbol()
662 symtab_data->d_size = num * entsize; in elf_update_symbol()
663 symtab_data->d_align = 1; in elf_update_symbol()
664 symtab_data->d_type = ELF_T_SYM; in elf_update_symbol()
667 symtab->truncate = true; in elf_update_symbol()
673 return -1; in elf_update_symbol()
676 shndx_data->d_buf = buf; in elf_update_symbol()
677 shndx_data->d_size = num * sizeof(Elf32_Word); in elf_update_symbol()
678 shndx_data->d_align = sizeof(Elf32_Word); in elf_update_symbol()
679 shndx_data->d_type = ELF_T_WORD; in elf_update_symbol()
682 symtab_shndx->truncate = true; in elf_update_symbol()
689 if (!symtab_data->d_size) { in elf_update_symbol()
691 return -1; in elf_update_symbol()
695 max_idx = symtab_data->d_size / entsize; in elf_update_symbol()
700 idx -= max_idx; in elf_update_symbol()
703 /* something went side-ways */ in elf_update_symbol()
706 return -1; in elf_update_symbol()
709 /* setup extended section index magic and write the symbol */ in elf_update_symbol()
711 sym->sym.st_shndx = shndx; in elf_update_symbol()
715 sym->sym.st_shndx = SHN_XINDEX; in elf_update_symbol()
718 return -1; in elf_update_symbol()
722 if (!gelf_update_symshndx(symtab_data, shndx_data, idx, &sym->sym, shndx)) { in elf_update_symbol()
724 return -1; in elf_update_symbol()
733 struct section *symtab, *symtab_shndx; in __elf_create_symbol()
747 if (GELF_ST_BIND(sym->sym.st_info) != STB_LOCAL) in __elf_create_symbol()
754 first_non_local = symtab->sh.sh_info; in __elf_create_symbol()
758 elf_hash_del(symbol, &old->hash, old->idx); in __elf_create_symbol()
759 elf_hash_add(symbol, &old->hash, new_idx); in __elf_create_symbol()
760 old->idx = new_idx; in __elf_create_symbol()
776 symtab->sh.sh_info += 1; in __elf_create_symbol()
779 sym->idx = new_idx; in __elf_create_symbol()
785 symtab->sh.sh_size += symtab->sh.sh_entsize; in __elf_create_symbol()
789 symtab_shndx->sh.sh_size += sizeof(Elf32_Word); in __elf_create_symbol()
797 elf_create_section_symbol(struct elf *elf, struct section *sec) in elf_create_section_symbol()
806 sym->name = sec->name; in elf_create_section_symbol()
807 sym->sec = sec; in elf_create_section_symbol()
810 sym->sym.st_info = GELF_ST_INFO(STB_LOCAL, STT_SECTION); in elf_create_section_symbol()
822 static int elf_add_string(struct elf *elf, struct section *strtab, char *str);
828 size_t namelen = strlen(orig->name) + sizeof("__pfx_"); in elf_create_prefix_symbol()
836 snprintf(name, namelen, "__pfx_%s", orig->name); in elf_create_prefix_symbol()
838 sym->name = name; in elf_create_prefix_symbol()
839 sym->sec = orig->sec; in elf_create_prefix_symbol()
841 sym->sym.st_name = elf_add_string(elf, NULL, name); in elf_create_prefix_symbol()
842 sym->sym.st_info = orig->sym.st_info; in elf_create_prefix_symbol()
843 sym->sym.st_value = orig->sym.st_value - size; in elf_create_prefix_symbol()
844 sym->sym.st_size = size; in elf_create_prefix_symbol()
853 static struct reloc *elf_init_reloc(struct elf *elf, struct section *rsec, in elf_init_reloc()
862 __func__, reloc_idx, rsec->name, sec_num_entries(rsec)); in elf_init_reloc()
866 reloc = &rsec->relocs[reloc_idx]; in elf_init_reloc()
870 __func__, rsec->name, reloc_idx); in elf_init_reloc()
874 reloc->sec = rsec; in elf_init_reloc()
875 reloc->sym = sym; in elf_init_reloc()
878 set_reloc_sym(elf, reloc, sym->idx); in elf_init_reloc()
882 elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc)); in elf_init_reloc()
883 set_sym_next_reloc(reloc, sym->relocs); in elf_init_reloc()
884 sym->relocs = reloc; in elf_init_reloc()
889 struct reloc *elf_init_reloc_text_sym(struct elf *elf, struct section *sec, in elf_init_reloc_text_sym()
892 struct section *insn_sec, in elf_init_reloc_text_sym()
895 struct symbol *sym = insn_sec->sym; in elf_init_reloc_text_sym()
898 if (!(insn_sec->sh.sh_flags & SHF_EXECINSTR)) { in elf_init_reloc_text_sym()
900 __func__, sym->name); in elf_init_reloc_text_sym()
906 * Due to how weak functions work, we must use section based in elf_init_reloc_text_sym()
908 * weak and non-weak function annotations being overlaid on the in elf_init_reloc_text_sym()
909 * non-weak function after linking. in elf_init_reloc_text_sym()
915 insn_sec->sym = sym; in elf_init_reloc_text_sym()
918 return elf_init_reloc(elf, sec->rsec, reloc_idx, offset, sym, addend, in elf_init_reloc_text_sym()
922 struct reloc *elf_init_reloc_data_sym(struct elf *elf, struct section *sec, in elf_init_reloc_data_sym()
928 if (sym->sec && (sec->sh.sh_flags & SHF_EXECINSTR)) { in elf_init_reloc_data_sym()
930 __func__, sym->name); in elf_init_reloc_data_sym()
934 return elf_init_reloc(elf, sec->rsec, reloc_idx, offset, sym, addend, in elf_init_reloc_data_sym()
941 struct section *rsec; in read_relocs()
947 if (!elf_alloc_hash(reloc, elf->num_relocs)) in read_relocs()
948 return -1; in read_relocs()
950 list_for_each_entry(rsec, &elf->sections, list) { in read_relocs()
954 rsec->base = find_section_by_index(elf, rsec->sh.sh_info); in read_relocs()
955 if (!rsec->base) { in read_relocs()
956 WARN("can't find base section for reloc section %s", in read_relocs()
957 rsec->name); in read_relocs()
958 return -1; in read_relocs()
961 rsec->base->rsec = rsec; in read_relocs()
964 rsec->relocs = calloc(sec_num_entries(rsec), sizeof(*reloc)); in read_relocs()
965 if (!rsec->relocs) { in read_relocs()
967 return -1; in read_relocs()
970 reloc = &rsec->relocs[i]; in read_relocs()
972 reloc->sec = rsec; in read_relocs()
974 reloc->sym = sym = find_symbol_by_index(elf, symndx); in read_relocs()
975 if (!reloc->sym) { in read_relocs()
977 symndx, rsec->name); in read_relocs()
978 return -1; in read_relocs()
981 elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc)); in read_relocs()
982 set_sym_next_reloc(reloc, sym->relocs); in read_relocs()
983 sym->relocs = reloc; in read_relocs()
992 printf("num_relocs: %lu\n", elf->num_relocs); in read_relocs()
993 printf("reloc_bits: %d\n", elf->reloc_bits); in read_relocs()
1013 INIT_LIST_HEAD(&elf->sections); in elf_open_read()
1015 elf->fd = open(name, flags); in elf_open_read()
1016 if (elf->fd == -1) { in elf_open_read()
1029 elf->elf = elf_begin(elf->fd, cmd, NULL); in elf_open_read()
1030 if (!elf->elf) { in elf_open_read()
1035 if (!gelf_getehdr(elf->elf, &elf->ehdr)) { in elf_open_read()
1056 static int elf_add_string(struct elf *elf, struct section *strtab, char *str) in elf_add_string()
1065 WARN("can't find .strtab section"); in elf_add_string()
1066 return -1; in elf_add_string()
1069 s = elf_getscn(elf->elf, strtab->idx); in elf_add_string()
1072 return -1; in elf_add_string()
1078 return -1; in elf_add_string()
1081 data->d_buf = str; in elf_add_string()
1082 data->d_size = strlen(str) + 1; in elf_add_string()
1083 data->d_align = 1; in elf_add_string()
1085 len = strtab->sh.sh_size; in elf_add_string()
1086 strtab->sh.sh_size += data->d_size; in elf_add_string()
1093 struct section *elf_create_section(struct elf *elf, const char *name, in elf_create_section()
1096 struct section *sec, *shstrtab; in elf_create_section()
1107 INIT_LIST_HEAD(&sec->symbol_list); in elf_create_section()
1109 s = elf_newscn(elf->elf); in elf_create_section()
1115 sec->name = strdup(name); in elf_create_section()
1116 if (!sec->name) { in elf_create_section()
1121 sec->idx = elf_ndxscn(s); in elf_create_section()
1123 sec->data = elf_newdata(s); in elf_create_section()
1124 if (!sec->data) { in elf_create_section()
1129 sec->data->d_size = size; in elf_create_section()
1130 sec->data->d_align = 1; in elf_create_section()
1133 sec->data->d_buf = malloc(size); in elf_create_section()
1134 if (!sec->data->d_buf) { in elf_create_section()
1138 memset(sec->data->d_buf, 0, size); in elf_create_section()
1141 if (!gelf_getshdr(s, &sec->sh)) { in elf_create_section()
1146 sec->sh.sh_size = size; in elf_create_section()
1147 sec->sh.sh_entsize = entsize; in elf_create_section()
1148 sec->sh.sh_type = SHT_PROGBITS; in elf_create_section()
1149 sec->sh.sh_addralign = 1; in elf_create_section()
1150 sec->sh.sh_flags = SHF_ALLOC; in elf_create_section()
1152 /* Add section name to .shstrtab (or .strtab for Clang) */ in elf_create_section()
1157 WARN("can't find .shstrtab or .strtab section"); in elf_create_section()
1160 sec->sh.sh_name = elf_add_string(elf, shstrtab, sec->name); in elf_create_section()
1161 if (sec->sh.sh_name == -1) in elf_create_section()
1164 list_add_tail(&sec->list, &elf->sections); in elf_create_section()
1165 elf_hash_add(section, &sec->hash, sec->idx); in elf_create_section()
1166 elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name)); in elf_create_section()
1173 static struct section *elf_create_rela_section(struct elf *elf, in elf_create_rela_section()
1174 struct section *sec, in elf_create_rela_section()
1177 struct section *rsec; in elf_create_rela_section()
1180 rsec_name = malloc(strlen(sec->name) + strlen(".rela") + 1); in elf_create_rela_section()
1186 strcat(rsec_name, sec->name); in elf_create_rela_section()
1193 rsec->data->d_type = ELF_T_RELA; in elf_create_rela_section()
1194 rsec->sh.sh_type = SHT_RELA; in elf_create_rela_section()
1195 rsec->sh.sh_addralign = elf_addr_size(elf); in elf_create_rela_section()
1196 rsec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx; in elf_create_rela_section()
1197 rsec->sh.sh_info = sec->idx; in elf_create_rela_section()
1198 rsec->sh.sh_flags = SHF_INFO_LINK; in elf_create_rela_section()
1200 rsec->relocs = calloc(sec_num_entries(rsec), sizeof(struct reloc)); in elf_create_rela_section()
1201 if (!rsec->relocs) { in elf_create_rela_section()
1206 sec->rsec = rsec; in elf_create_rela_section()
1207 rsec->base = sec; in elf_create_rela_section()
1212 struct section *elf_create_section_pair(struct elf *elf, const char *name, in elf_create_section_pair()
1216 struct section *sec; in elf_create_section_pair()
1228 int elf_write_insn(struct elf *elf, struct section *sec, in elf_write_insn()
1232 Elf_Data *data = sec->data; in elf_write_insn()
1234 if (data->d_type != ELF_T_BYTE || data->d_off) { in elf_write_insn()
1235 WARN("write to unexpected data for section: %s", sec->name); in elf_write_insn()
1236 return -1; in elf_write_insn()
1239 memcpy(data->d_buf + offset, insn, len); in elf_write_insn()
1250 * A) adhere to the section header and truncate the data, or
1251 * B) ignore the section header and write out all the data you've got?
1253 * Yes, libelf sucks and we need to manually truncate if we over-allocate data.
1255 static int elf_truncate_section(struct elf *elf, struct section *sec) in elf_truncate_section()
1257 u64 size = sec->sh.sh_size; in elf_truncate_section()
1262 s = elf_getscn(elf->elf, sec->idx); in elf_truncate_section()
1265 return -1; in elf_truncate_section()
1269 /* get next data descriptor for the relevant section */ in elf_truncate_section()
1274 WARN("end of section data but non-zero size left\n"); in elf_truncate_section()
1275 return -1; in elf_truncate_section()
1283 return -1; in elf_truncate_section()
1286 if (!data->d_size) { in elf_truncate_section()
1288 return -1; in elf_truncate_section()
1291 if (data->d_size > size) { in elf_truncate_section()
1293 data->d_size = size; in elf_truncate_section()
1296 size -= data->d_size; in elf_truncate_section()
1302 struct section *sec; in elf_write()
1308 /* Update changed relocation sections and section headers: */ in elf_write()
1309 list_for_each_entry(sec, &elf->sections, list) { in elf_write()
1310 if (sec->truncate) in elf_write()
1314 s = elf_getscn(elf->elf, sec->idx); in elf_write()
1317 return -1; in elf_write()
1320 /* Note this also flags the section dirty */ in elf_write()
1321 if (!gelf_update_shdr(s, &sec->sh)) { in elf_write()
1323 return -1; in elf_write()
1330 /* Make sure the new section header entries get updated properly. */ in elf_write()
1331 elf_flagelf(elf->elf, ELF_C_SET, ELF_F_DIRTY); in elf_write()
1334 if (elf_update(elf->elf, ELF_C_WRITE) < 0) { in elf_write()
1336 return -1; in elf_write()
1339 elf->changed = false; in elf_write()
1346 if (elf->elf) in elf_close()
1347 elf_end(elf->elf); in elf_close()
1349 if (elf->fd > 0) in elf_close()
1350 close(elf->fd); in elf_close()