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 <jpoimboe@redhat.com>
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()
231 /* @offset >= sym->offset + sym->len, find symbol after it */ in find_symbol_hole_containing()
232 n = rb_next(&hole.sym->node); in find_symbol_hole_containing()
234 return -1; /* until end of address space */ in find_symbol_hole_containing()
238 return s->offset - offset; in find_symbol_hole_containing()
241 struct symbol *find_func_containing(struct section *sec, unsigned long offset) in find_func_containing()
243 struct rb_root_cached *tree = (struct rb_root_cached *)&sec->symbol_tree; in find_func_containing()
247 if (iter->type == STT_FUNC) in find_func_containing()
259 if (!strcmp(sym->name, name)) in find_symbol_by_name()
266 struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec, in find_reloc_by_dest_range()
270 struct section *rsec; in find_reloc_by_dest_range()
273 rsec = sec->rsec; in find_reloc_by_dest_range()
280 if (reloc->sec != rsec) in find_reloc_by_dest_range()
296 struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset) in find_reloc_by_dest()
301 static bool is_dwarf_section(struct section *sec) in is_dwarf_section()
303 return !strncmp(sec->name, ".debug_", 7); in is_dwarf_section()
309 struct section *sec; in read_sections()
313 if (elf_getshdrnum(elf->elf, &sections_nr)) { in read_sections()
315 return -1; in read_sections()
318 if (elf_getshdrstrndx(elf->elf, &shstrndx)) { in read_sections()
320 return -1; in read_sections()
323 if (!elf_alloc_hash(section, sections_nr) || in read_sections()
325 return -1; in read_sections()
327 elf->section_data = calloc(sections_nr, sizeof(*sec)); in read_sections()
328 if (!elf->section_data) { in read_sections()
330 return -1; in read_sections()
333 sec = &elf->section_data[i]; in read_sections()
335 INIT_LIST_HEAD(&sec->symbol_list); in read_sections()
337 s = elf_getscn(elf->elf, i); in read_sections()
340 return -1; in read_sections()
343 sec->idx = elf_ndxscn(s); in read_sections()
345 if (!gelf_getshdr(s, &sec->sh)) { in read_sections()
347 return -1; in read_sections()
350 sec->name = elf_strptr(elf->elf, shstrndx, sec->sh.sh_name); in read_sections()
351 if (!sec->name) { in read_sections()
353 return -1; in read_sections()
356 if (sec->sh.sh_size != 0 && !is_dwarf_section(sec)) { in read_sections()
357 sec->data = elf_getdata(s, NULL); in read_sections()
358 if (!sec->data) { in read_sections()
360 return -1; in read_sections()
362 if (sec->data->d_off != 0 || in read_sections()
363 sec->data->d_size != sec->sh.sh_size) { in read_sections()
365 sec->name); in read_sections()
366 return -1; in read_sections()
370 list_add_tail(&sec->list, &elf->sections); in read_sections()
371 elf_hash_add(section, &sec->hash, sec->idx); in read_sections()
372 elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name)); in read_sections()
375 elf->num_relocs += sec_num_entries(sec); in read_sections()
380 printf("section_bits: %d\n", elf->section_bits); in read_sections()
384 if (elf_nextscn(elf->elf, s)) { in read_sections()
385 WARN("section entry mismatch"); in read_sections()
386 return -1; in read_sections()
398 INIT_LIST_HEAD(&sym->pv_target); in elf_add_symbol()
399 sym->alias = sym; in elf_add_symbol()
401 sym->type = GELF_ST_TYPE(sym->sym.st_info); in elf_add_symbol()
402 sym->bind = GELF_ST_BIND(sym->sym.st_info); in elf_add_symbol()
404 if (sym->type == STT_FILE) in elf_add_symbol()
405 elf->num_files++; in elf_add_symbol()
407 sym->offset = sym->sym.st_value; in elf_add_symbol()
408 sym->len = sym->sym.st_size; in elf_add_symbol()
410 __sym_for_each(iter, &sym->sec->symbol_tree, sym->offset, sym->offset) { in elf_add_symbol()
411 if (iter->offset == sym->offset && iter->type == sym->type) in elf_add_symbol()
412 iter->alias = sym; in elf_add_symbol()
415 __sym_insert(sym, &sym->sec->symbol_tree); in elf_add_symbol()
416 pnode = rb_prev(&sym->node); in elf_add_symbol()
418 entry = &rb_entry(pnode, struct symbol, node)->list; in elf_add_symbol()
420 entry = &sym->sec->symbol_list; in elf_add_symbol()
421 list_add(&sym->list, entry); in elf_add_symbol()
422 elf_hash_add(symbol, &sym->hash, sym->idx); in elf_add_symbol()
423 elf_hash_add(symbol_name, &sym->name_hash, str_hash(sym->name)); in elf_add_symbol()
429 if (!sym->len) in elf_add_symbol()
430 __sym_remove(sym, &sym->sec->symbol_tree); in elf_add_symbol()
435 struct section *symtab, *symtab_shndx, *sec; in read_symbols()
446 shndx_data = symtab_shndx->data; in read_symbols()
461 return -1; in read_symbols()
463 elf->symbol_data = calloc(symbols_nr, sizeof(*sym)); in read_symbols()
464 if (!elf->symbol_data) { in read_symbols()
466 return -1; in read_symbols()
469 sym = &elf->symbol_data[i]; in read_symbols()
471 sym->idx = i; in read_symbols()
473 if (!gelf_getsymshndx(symtab->data, shndx_data, i, &sym->sym, in read_symbols()
479 sym->name = elf_strptr(elf->elf, symtab->sh.sh_link, in read_symbols()
480 sym->sym.st_name); in read_symbols()
481 if (!sym->name) { in read_symbols()
486 if ((sym->sym.st_shndx > SHN_UNDEF && in read_symbols()
487 sym->sym.st_shndx < SHN_LORESERVE) || in read_symbols()
488 (shndx_data && sym->sym.st_shndx == SHN_XINDEX)) { in read_symbols()
489 if (sym->sym.st_shndx != SHN_XINDEX) in read_symbols()
490 shndx = sym->sym.st_shndx; in read_symbols()
492 sym->sec = find_section_by_index(elf, shndx); in read_symbols()
493 if (!sym->sec) { in read_symbols()
494 WARN("couldn't find section for symbol %s", in read_symbols()
495 sym->name); in read_symbols()
498 if (GELF_ST_TYPE(sym->sym.st_info) == STT_SECTION) { in read_symbols()
499 sym->name = sym->sec->name; in read_symbols()
500 sym->sec->sym = sym; in read_symbols()
503 sym->sec = find_section_by_index(elf, 0); in read_symbols()
510 printf("symbol_bits: %d\n", elf->symbol_bits); in read_symbols()
514 list_for_each_entry(sec, &elf->sections, list) { in read_symbols()
518 if (sym->type != STT_FUNC) in read_symbols()
521 if (sym->pfunc == NULL) in read_symbols()
522 sym->pfunc = sym; in read_symbols()
524 if (sym->cfunc == NULL) in read_symbols()
525 sym->cfunc = sym; in read_symbols()
527 coldstr = strstr(sym->name, ".cold"); in read_symbols()
531 pnamelen = coldstr - sym->name; in read_symbols()
532 pname = strndup(sym->name, pnamelen); in read_symbols()
535 sym->name); in read_symbols()
536 return -1; in read_symbols()
544 sym->name); in read_symbols()
545 return -1; in read_symbols()
548 sym->pfunc = pfunc; in read_symbols()
549 pfunc->cfunc = sym; in read_symbols()
552 * Unfortunately, -fnoreorder-functions puts the child in read_symbols()
556 * Note that pfunc->len now no longer matches in read_symbols()
557 * pfunc->sym.st_size. in read_symbols()
559 if (sym->sec == pfunc->sec && in read_symbols()
560 sym->offset >= pfunc->offset && in read_symbols()
561 sym->offset + sym->len == pfunc->offset + pfunc->len) { in read_symbols()
562 pfunc->len -= sym->len; in read_symbols()
571 return -1; in read_symbols()
581 for (reloc = sym->relocs; reloc; reloc = reloc->sym_next_reloc) in elf_update_sym_relocs()
582 set_reloc_sym(elf, reloc, reloc->sym->idx); in elf_update_sym_relocs()
595 static int elf_update_symbol(struct elf *elf, struct section *symtab, in elf_update_symbol()
596 struct section *symtab_shndx, struct symbol *sym) in elf_update_symbol()
598 Elf32_Word shndx = sym->sec ? sym->sec->idx : SHN_UNDEF; in elf_update_symbol()
600 Elf64_Xword entsize = symtab->sh.sh_entsize; in elf_update_symbol()
601 int max_idx, idx = sym->idx; in elf_update_symbol()
603 bool is_special_shndx = sym->sym.st_shndx >= SHN_LORESERVE && in elf_update_symbol()
604 sym->sym.st_shndx != SHN_XINDEX; in elf_update_symbol()
607 shndx = sym->sym.st_shndx; in elf_update_symbol()
609 s = elf_getscn(elf->elf, symtab->idx); in elf_update_symbol()
612 return -1; in elf_update_symbol()
616 t = elf_getscn(elf->elf, symtab_shndx->idx); in elf_update_symbol()
619 return -1; in elf_update_symbol()
629 /* end-of-list */ in elf_update_symbol()
632 * Over-allocate to avoid O(n^2) symbol creation in elf_update_symbol()
636 int num = max(1U, sym->idx/3); in elf_update_symbol()
642 return -1; in elf_update_symbol()
653 return -1; in elf_update_symbol()
656 symtab_data->d_buf = buf; in elf_update_symbol()
657 symtab_data->d_size = num * entsize; in elf_update_symbol()
658 symtab_data->d_align = 1; in elf_update_symbol()
659 symtab_data->d_type = ELF_T_SYM; in elf_update_symbol()
662 symtab->truncate = true; in elf_update_symbol()
668 return -1; in elf_update_symbol()
671 shndx_data->d_buf = buf; in elf_update_symbol()
672 shndx_data->d_size = num * sizeof(Elf32_Word); in elf_update_symbol()
673 shndx_data->d_align = sizeof(Elf32_Word); in elf_update_symbol()
674 shndx_data->d_type = ELF_T_WORD; in elf_update_symbol()
677 symtab_shndx->truncate = true; in elf_update_symbol()
684 if (!symtab_data->d_size) { in elf_update_symbol()
686 return -1; in elf_update_symbol()
690 max_idx = symtab_data->d_size / entsize; in elf_update_symbol()
695 idx -= max_idx; in elf_update_symbol()
698 /* something went side-ways */ in elf_update_symbol()
701 return -1; in elf_update_symbol()
704 /* setup extended section index magic and write the symbol */ in elf_update_symbol()
706 sym->sym.st_shndx = shndx; in elf_update_symbol()
710 sym->sym.st_shndx = SHN_XINDEX; in elf_update_symbol()
713 return -1; in elf_update_symbol()
717 if (!gelf_update_symshndx(symtab_data, shndx_data, idx, &sym->sym, shndx)) { in elf_update_symbol()
719 return -1; in elf_update_symbol()
728 struct section *symtab, *symtab_shndx; in __elf_create_symbol()
742 if (GELF_ST_BIND(sym->sym.st_info) != STB_LOCAL) in __elf_create_symbol()
749 first_non_local = symtab->sh.sh_info; in __elf_create_symbol()
753 elf_hash_del(symbol, &old->hash, old->idx); in __elf_create_symbol()
754 elf_hash_add(symbol, &old->hash, new_idx); in __elf_create_symbol()
755 old->idx = new_idx; in __elf_create_symbol()
771 symtab->sh.sh_info += 1; in __elf_create_symbol()
774 sym->idx = new_idx; in __elf_create_symbol()
780 symtab->sh.sh_size += symtab->sh.sh_entsize; in __elf_create_symbol()
784 symtab_shndx->sh.sh_size += sizeof(Elf32_Word); in __elf_create_symbol()
792 elf_create_section_symbol(struct elf *elf, struct section *sec) in elf_create_section_symbol()
801 sym->name = sec->name; in elf_create_section_symbol()
802 sym->sec = sec; in elf_create_section_symbol()
805 sym->sym.st_info = GELF_ST_INFO(STB_LOCAL, STT_SECTION); in elf_create_section_symbol()
817 static int elf_add_string(struct elf *elf, struct section *strtab, char *str);
823 size_t namelen = strlen(orig->name) + sizeof("__pfx_"); in elf_create_prefix_symbol()
831 snprintf(name, namelen, "__pfx_%s", orig->name); in elf_create_prefix_symbol()
833 sym->name = name; in elf_create_prefix_symbol()
834 sym->sec = orig->sec; in elf_create_prefix_symbol()
836 sym->sym.st_name = elf_add_string(elf, NULL, name); in elf_create_prefix_symbol()
837 sym->sym.st_info = orig->sym.st_info; in elf_create_prefix_symbol()
838 sym->sym.st_value = orig->sym.st_value - size; in elf_create_prefix_symbol()
839 sym->sym.st_size = size; in elf_create_prefix_symbol()
848 static struct reloc *elf_init_reloc(struct elf *elf, struct section *rsec, in elf_init_reloc()
857 __func__, reloc_idx, rsec->name, sec_num_entries(rsec)); in elf_init_reloc()
861 reloc = &rsec->relocs[reloc_idx]; in elf_init_reloc()
865 __func__, rsec->name, reloc_idx); in elf_init_reloc()
869 reloc->sec = rsec; in elf_init_reloc()
870 reloc->sym = sym; in elf_init_reloc()
873 set_reloc_sym(elf, reloc, sym->idx); in elf_init_reloc()
877 elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc)); in elf_init_reloc()
878 reloc->sym_next_reloc = sym->relocs; in elf_init_reloc()
879 sym->relocs = reloc; in elf_init_reloc()
884 struct reloc *elf_init_reloc_text_sym(struct elf *elf, struct section *sec, in elf_init_reloc_text_sym()
887 struct section *insn_sec, in elf_init_reloc_text_sym()
890 struct symbol *sym = insn_sec->sym; in elf_init_reloc_text_sym()
893 if (!(insn_sec->sh.sh_flags & SHF_EXECINSTR)) { in elf_init_reloc_text_sym()
895 __func__, sym->name); in elf_init_reloc_text_sym()
901 * Due to how weak functions work, we must use section based in elf_init_reloc_text_sym()
903 * weak and non-weak function annotations being overlaid on the in elf_init_reloc_text_sym()
904 * non-weak function after linking. in elf_init_reloc_text_sym()
910 insn_sec->sym = sym; in elf_init_reloc_text_sym()
913 return elf_init_reloc(elf, sec->rsec, reloc_idx, offset, sym, addend, in elf_init_reloc_text_sym()
917 struct reloc *elf_init_reloc_data_sym(struct elf *elf, struct section *sec, in elf_init_reloc_data_sym()
923 if (sym->sec && (sec->sh.sh_flags & SHF_EXECINSTR)) { in elf_init_reloc_data_sym()
925 __func__, sym->name); in elf_init_reloc_data_sym()
929 return elf_init_reloc(elf, sec->rsec, reloc_idx, offset, sym, addend, in elf_init_reloc_data_sym()
936 struct section *rsec; in read_relocs()
942 if (!elf_alloc_hash(reloc, elf->num_relocs)) in read_relocs()
943 return -1; in read_relocs()
945 list_for_each_entry(rsec, &elf->sections, list) { in read_relocs()
949 rsec->base = find_section_by_index(elf, rsec->sh.sh_info); in read_relocs()
950 if (!rsec->base) { in read_relocs()
951 WARN("can't find base section for reloc section %s", in read_relocs()
952 rsec->name); in read_relocs()
953 return -1; in read_relocs()
956 rsec->base->rsec = rsec; in read_relocs()
959 rsec->relocs = calloc(sec_num_entries(rsec), sizeof(*reloc)); in read_relocs()
960 if (!rsec->relocs) { in read_relocs()
962 return -1; in read_relocs()
965 reloc = &rsec->relocs[i]; in read_relocs()
967 reloc->sec = rsec; in read_relocs()
969 reloc->sym = sym = find_symbol_by_index(elf, symndx); in read_relocs()
970 if (!reloc->sym) { in read_relocs()
972 symndx, rsec->name); in read_relocs()
973 return -1; in read_relocs()
976 elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc)); in read_relocs()
977 reloc->sym_next_reloc = sym->relocs; in read_relocs()
978 sym->relocs = reloc; in read_relocs()
987 printf("num_relocs: %lu\n", elf->num_relocs); in read_relocs()
988 printf("reloc_bits: %d\n", elf->reloc_bits); in read_relocs()
1008 INIT_LIST_HEAD(&elf->sections); in elf_open_read()
1010 elf->fd = open(name, flags); in elf_open_read()
1011 if (elf->fd == -1) { in elf_open_read()
1024 elf->elf = elf_begin(elf->fd, cmd, NULL); in elf_open_read()
1025 if (!elf->elf) { in elf_open_read()
1030 if (!gelf_getehdr(elf->elf, &elf->ehdr)) { in elf_open_read()
1051 static int elf_add_string(struct elf *elf, struct section *strtab, char *str) in elf_add_string()
1060 WARN("can't find .strtab section"); in elf_add_string()
1061 return -1; in elf_add_string()
1064 s = elf_getscn(elf->elf, strtab->idx); in elf_add_string()
1067 return -1; in elf_add_string()
1073 return -1; in elf_add_string()
1076 data->d_buf = str; in elf_add_string()
1077 data->d_size = strlen(str) + 1; in elf_add_string()
1078 data->d_align = 1; in elf_add_string()
1080 len = strtab->sh.sh_size; in elf_add_string()
1081 strtab->sh.sh_size += data->d_size; in elf_add_string()
1088 struct section *elf_create_section(struct elf *elf, const char *name, in elf_create_section()
1091 struct section *sec, *shstrtab; in elf_create_section()
1102 INIT_LIST_HEAD(&sec->symbol_list); in elf_create_section()
1104 s = elf_newscn(elf->elf); in elf_create_section()
1110 sec->name = strdup(name); in elf_create_section()
1111 if (!sec->name) { in elf_create_section()
1116 sec->idx = elf_ndxscn(s); in elf_create_section()
1118 sec->data = elf_newdata(s); in elf_create_section()
1119 if (!sec->data) { in elf_create_section()
1124 sec->data->d_size = size; in elf_create_section()
1125 sec->data->d_align = 1; in elf_create_section()
1128 sec->data->d_buf = malloc(size); in elf_create_section()
1129 if (!sec->data->d_buf) { in elf_create_section()
1133 memset(sec->data->d_buf, 0, size); in elf_create_section()
1136 if (!gelf_getshdr(s, &sec->sh)) { in elf_create_section()
1141 sec->sh.sh_size = size; in elf_create_section()
1142 sec->sh.sh_entsize = entsize; in elf_create_section()
1143 sec->sh.sh_type = SHT_PROGBITS; in elf_create_section()
1144 sec->sh.sh_addralign = 1; in elf_create_section()
1145 sec->sh.sh_flags = SHF_ALLOC; in elf_create_section()
1147 /* Add section name to .shstrtab (or .strtab for Clang) */ in elf_create_section()
1152 WARN("can't find .shstrtab or .strtab section"); in elf_create_section()
1155 sec->sh.sh_name = elf_add_string(elf, shstrtab, sec->name); in elf_create_section()
1156 if (sec->sh.sh_name == -1) in elf_create_section()
1159 list_add_tail(&sec->list, &elf->sections); in elf_create_section()
1160 elf_hash_add(section, &sec->hash, sec->idx); in elf_create_section()
1161 elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name)); in elf_create_section()
1168 static struct section *elf_create_rela_section(struct elf *elf, in elf_create_rela_section()
1169 struct section *sec, in elf_create_rela_section()
1172 struct section *rsec; in elf_create_rela_section()
1175 rsec_name = malloc(strlen(sec->name) + strlen(".rela") + 1); in elf_create_rela_section()
1181 strcat(rsec_name, sec->name); in elf_create_rela_section()
1188 rsec->data->d_type = ELF_T_RELA; in elf_create_rela_section()
1189 rsec->sh.sh_type = SHT_RELA; in elf_create_rela_section()
1190 rsec->sh.sh_addralign = elf_addr_size(elf); in elf_create_rela_section()
1191 rsec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx; in elf_create_rela_section()
1192 rsec->sh.sh_info = sec->idx; in elf_create_rela_section()
1193 rsec->sh.sh_flags = SHF_INFO_LINK; in elf_create_rela_section()
1195 rsec->relocs = calloc(sec_num_entries(rsec), sizeof(struct reloc)); in elf_create_rela_section()
1196 if (!rsec->relocs) { in elf_create_rela_section()
1201 sec->rsec = rsec; in elf_create_rela_section()
1202 rsec->base = sec; in elf_create_rela_section()
1207 struct section *elf_create_section_pair(struct elf *elf, const char *name, in elf_create_section_pair()
1211 struct section *sec; in elf_create_section_pair()
1223 int elf_write_insn(struct elf *elf, struct section *sec, in elf_write_insn()
1227 Elf_Data *data = sec->data; in elf_write_insn()
1229 if (data->d_type != ELF_T_BYTE || data->d_off) { in elf_write_insn()
1230 WARN("write to unexpected data for section: %s", sec->name); in elf_write_insn()
1231 return -1; in elf_write_insn()
1234 memcpy(data->d_buf + offset, insn, len); in elf_write_insn()
1245 * A) adhere to the section header and truncate the data, or
1246 * B) ignore the section header and write out all the data you've got?
1248 * Yes, libelf sucks and we need to manually truncate if we over-allocate data.
1250 static int elf_truncate_section(struct elf *elf, struct section *sec) in elf_truncate_section()
1252 u64 size = sec->sh.sh_size; in elf_truncate_section()
1257 s = elf_getscn(elf->elf, sec->idx); in elf_truncate_section()
1260 return -1; in elf_truncate_section()
1264 /* get next data descriptor for the relevant section */ in elf_truncate_section()
1269 WARN("end of section data but non-zero size left\n"); in elf_truncate_section()
1270 return -1; in elf_truncate_section()
1278 return -1; in elf_truncate_section()
1281 if (!data->d_size) { in elf_truncate_section()
1283 return -1; in elf_truncate_section()
1286 if (data->d_size > size) { in elf_truncate_section()
1288 data->d_size = size; in elf_truncate_section()
1291 size -= data->d_size; in elf_truncate_section()
1297 struct section *sec; in elf_write()
1303 /* Update changed relocation sections and section headers: */ in elf_write()
1304 list_for_each_entry(sec, &elf->sections, list) { in elf_write()
1305 if (sec->truncate) in elf_write()
1309 s = elf_getscn(elf->elf, sec->idx); in elf_write()
1312 return -1; in elf_write()
1315 /* Note this also flags the section dirty */ in elf_write()
1316 if (!gelf_update_shdr(s, &sec->sh)) { in elf_write()
1318 return -1; in elf_write()
1325 /* Make sure the new section header entries get updated properly. */ in elf_write()
1326 elf_flagelf(elf->elf, ELF_C_SET, ELF_F_DIRTY); in elf_write()
1329 if (elf_update(elf->elf, ELF_C_WRITE) < 0) { in elf_write()
1331 return -1; in elf_write()
1334 elf->changed = false; in elf_write()
1341 if (elf->elf) in elf_close()
1342 elf_end(elf->elf); in elf_close()
1344 if (elf->fd > 0) in elf_close()
1345 close(elf->fd); in elf_close()