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>
31 #define __elf_table(name) (elf->name##_hash)
32 #define __elf_bits(name) (elf->name##_bits)
45 MAP_PRIVATE|MAP_ANON, -1, 0); \
46 if (__elf_table(name) == (void *)-1L) { \
58 if (sa->offset < sb->offset) in symbol_to_offset()
60 if (sa->offset > sb->offset) in symbol_to_offset()
63 if (sa->len < sb->len) in symbol_to_offset()
65 if (sa->len > sb->len) in symbol_to_offset()
68 sa->alias = sb; in symbol_to_offset()
78 if (*o < s->offset) in symbol_by_offset()
79 return -1; in symbol_by_offset()
80 if (*o >= s->offset + s->len) in symbol_by_offset()
86 struct section *find_section_by_name(const struct elf *elf, const char *name) in find_section_by_name()
88 struct section *sec; in find_section_by_name()
91 if (!strcmp(sec->name, name)) in find_section_by_name()
98 static struct section *find_section_by_index(struct elf *elf, in find_section_by_index()
101 struct section *sec; in find_section_by_index()
103 elf_hash_for_each_possible(section, sec, hash, idx) { in find_section_by_index()
104 if (sec->idx == idx) in find_section_by_index()
116 if (sym->idx == idx) in find_symbol_by_index()
123 struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset) in find_symbol_by_offset()
127 rb_for_each(node, &offset, &sec->symbol_tree, symbol_by_offset) { in find_symbol_by_offset()
130 if (s->offset == offset && s->type != STT_SECTION) in find_symbol_by_offset()
137 struct symbol *find_func_by_offset(struct section *sec, unsigned long offset) in find_func_by_offset()
141 rb_for_each(node, &offset, &sec->symbol_tree, symbol_by_offset) { in find_func_by_offset()
144 if (s->offset == offset && s->type == STT_FUNC) in find_func_by_offset()
151 struct symbol *find_symbol_containing(const struct section *sec, unsigned long offset) in find_symbol_containing()
155 rb_for_each(node, &offset, &sec->symbol_tree, symbol_by_offset) { in find_symbol_containing()
158 if (s->type != STT_SECTION) in find_symbol_containing()
165 struct symbol *find_func_containing(struct section *sec, unsigned long offset) in find_func_containing()
169 rb_for_each(node, &offset, &sec->symbol_tree, symbol_by_offset) { in find_func_containing()
172 if (s->type == STT_FUNC) in find_func_containing()
184 if (!strcmp(sym->name, name)) in find_symbol_by_name()
191 struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec, in find_reloc_by_dest_range()
197 if (!sec->reloc) in find_reloc_by_dest_range()
200 sec = sec->reloc; in find_reloc_by_dest_range()
205 if (reloc->sec != sec) in find_reloc_by_dest_range()
208 if (reloc->offset >= offset && reloc->offset < offset + len) { in find_reloc_by_dest_range()
209 if (!r || reloc->offset < r->offset) in find_reloc_by_dest_range()
220 struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset) in find_reloc_by_dest()
228 struct section *sec; in read_sections()
232 if (elf_getshdrnum(elf->elf, §ions_nr)) { in read_sections()
234 return -1; in read_sections()
237 if (elf_getshdrstrndx(elf->elf, &shstrndx)) { in read_sections()
239 return -1; in read_sections()
242 if (!elf_alloc_hash(section, sections_nr) || in read_sections()
244 return -1; in read_sections()
250 return -1; in read_sections()
254 INIT_LIST_HEAD(&sec->symbol_list); in read_sections()
255 INIT_LIST_HEAD(&sec->reloc_list); in read_sections()
257 s = elf_getscn(elf->elf, i); in read_sections()
260 return -1; in read_sections()
263 sec->idx = elf_ndxscn(s); in read_sections()
265 if (!gelf_getshdr(s, &sec->sh)) { in read_sections()
267 return -1; in read_sections()
270 sec->name = elf_strptr(elf->elf, shstrndx, sec->sh.sh_name); in read_sections()
271 if (!sec->name) { in read_sections()
273 return -1; in read_sections()
276 if (sec->sh.sh_size != 0) { in read_sections()
277 sec->data = elf_getdata(s, NULL); in read_sections()
278 if (!sec->data) { in read_sections()
280 return -1; in read_sections()
282 if (sec->data->d_off != 0 || in read_sections()
283 sec->data->d_size != sec->sh.sh_size) { in read_sections()
285 sec->name); in read_sections()
286 return -1; in read_sections()
290 if (sec->sh.sh_flags & SHF_EXECINSTR) in read_sections()
291 elf->text_size += sec->sh.sh_size; in read_sections()
293 list_add_tail(&sec->list, &elf->sections); in read_sections()
294 elf_hash_add(section, &sec->hash, sec->idx); in read_sections()
295 elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name)); in read_sections()
300 printf("section_bits: %d\n", elf->section_bits); in read_sections()
304 if (elf_nextscn(elf->elf, s)) { in read_sections()
305 WARN("section entry mismatch"); in read_sections()
306 return -1; in read_sections()
317 sym->type = GELF_ST_TYPE(sym->sym.st_info); in elf_add_symbol()
318 sym->bind = GELF_ST_BIND(sym->sym.st_info); in elf_add_symbol()
320 sym->offset = sym->sym.st_value; in elf_add_symbol()
321 sym->len = sym->sym.st_size; in elf_add_symbol()
323 rb_add(&sym->node, &sym->sec->symbol_tree, symbol_to_offset); in elf_add_symbol()
324 pnode = rb_prev(&sym->node); in elf_add_symbol()
326 entry = &rb_entry(pnode, struct symbol, node)->list; in elf_add_symbol()
328 entry = &sym->sec->symbol_list; in elf_add_symbol()
329 list_add(&sym->list, entry); in elf_add_symbol()
330 elf_hash_add(symbol, &sym->hash, sym->idx); in elf_add_symbol()
331 elf_hash_add(symbol_name, &sym->name_hash, str_hash(sym->name)); in elf_add_symbol()
337 if (!sym->len) in elf_add_symbol()
338 rb_erase(&sym->node, &sym->sec->symbol_tree); in elf_add_symbol()
343 struct section *symtab, *symtab_shndx, *sec; in read_symbols()
354 shndx_data = symtab_shndx->data; in read_symbols()
356 symbols_nr = symtab->sh.sh_size / symtab->sh.sh_entsize; in read_symbols()
369 return -1; in read_symbols()
375 return -1; in read_symbols()
378 sym->alias = sym; in read_symbols()
380 sym->idx = i; in read_symbols()
382 if (!gelf_getsymshndx(symtab->data, shndx_data, i, &sym->sym, in read_symbols()
388 sym->name = elf_strptr(elf->elf, symtab->sh.sh_link, in read_symbols()
389 sym->sym.st_name); in read_symbols()
390 if (!sym->name) { in read_symbols()
395 if ((sym->sym.st_shndx > SHN_UNDEF && in read_symbols()
396 sym->sym.st_shndx < SHN_LORESERVE) || in read_symbols()
397 (shndx_data && sym->sym.st_shndx == SHN_XINDEX)) { in read_symbols()
398 if (sym->sym.st_shndx != SHN_XINDEX) in read_symbols()
399 shndx = sym->sym.st_shndx; in read_symbols()
401 sym->sec = find_section_by_index(elf, shndx); in read_symbols()
402 if (!sym->sec) { in read_symbols()
403 WARN("couldn't find section for symbol %s", in read_symbols()
404 sym->name); in read_symbols()
407 if (GELF_ST_TYPE(sym->sym.st_info) == STT_SECTION) { in read_symbols()
408 sym->name = sym->sec->name; in read_symbols()
409 sym->sec->sym = sym; in read_symbols()
412 sym->sec = find_section_by_index(elf, 0); in read_symbols()
419 printf("symbol_bits: %d\n", elf->symbol_bits); in read_symbols()
423 list_for_each_entry(sec, &elf->sections, list) { in read_symbols()
424 list_for_each_entry(sym, &sec->symbol_list, list) { in read_symbols()
427 if (sym->type != STT_FUNC) in read_symbols()
430 if (sym->pfunc == NULL) in read_symbols()
431 sym->pfunc = sym; in read_symbols()
433 if (sym->cfunc == NULL) in read_symbols()
434 sym->cfunc = sym; in read_symbols()
436 coldstr = strstr(sym->name, ".cold"); in read_symbols()
440 pnamelen = coldstr - sym->name; in read_symbols()
443 sym->name, MAX_NAME_LEN); in read_symbols()
444 return -1; in read_symbols()
447 strncpy(pname, sym->name, pnamelen); in read_symbols()
453 sym->name); in read_symbols()
454 return -1; in read_symbols()
457 sym->pfunc = pfunc; in read_symbols()
458 pfunc->cfunc = sym; in read_symbols()
461 * Unfortunately, -fnoreorder-functions puts the child in read_symbols()
465 * Note that pfunc->len now no longer matches in read_symbols()
466 * pfunc->sym.st_size. in read_symbols()
468 if (sym->sec == pfunc->sec && in read_symbols()
469 sym->offset >= pfunc->offset && in read_symbols()
470 sym->offset + sym->len == pfunc->offset + pfunc->len) { in read_symbols()
471 pfunc->len -= sym->len; in read_symbols()
480 return -1; in read_symbols()
483 static struct section *elf_create_reloc_section(struct elf *elf,
484 struct section *base,
487 int elf_add_reloc(struct elf *elf, struct section *sec, unsigned long offset, in elf_add_reloc()
492 if (!sec->reloc && !elf_create_reloc_section(elf, sec, SHT_RELA)) in elf_add_reloc()
493 return -1; in elf_add_reloc()
498 return -1; in elf_add_reloc()
502 reloc->sec = sec->reloc; in elf_add_reloc()
503 reloc->offset = offset; in elf_add_reloc()
504 reloc->type = type; in elf_add_reloc()
505 reloc->sym = sym; in elf_add_reloc()
506 reloc->addend = addend; in elf_add_reloc()
508 list_add_tail(&reloc->list, &sec->reloc->reloc_list); in elf_add_reloc()
509 elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc)); in elf_add_reloc()
511 sec->reloc->sh.sh_size += sec->reloc->sh.sh_entsize; in elf_add_reloc()
512 sec->reloc->changed = true; in elf_add_reloc()
517 int elf_add_reloc_to_insn(struct elf *elf, struct section *sec, in elf_add_reloc_to_insn()
519 struct section *insn_sec, unsigned long insn_off) in elf_add_reloc_to_insn()
524 if (insn_sec->sym) { in elf_add_reloc_to_insn()
525 sym = insn_sec->sym; in elf_add_reloc_to_insn()
530 * The Clang assembler strips section symbols, so we have to in elf_add_reloc_to_insn()
539 sym = find_symbol_containing(insn_sec, insn_off - 1); in elf_add_reloc_to_insn()
543 WARN("can't find symbol containing %s+0x%lx", insn_sec->name, insn_off); in elf_add_reloc_to_insn()
544 return -1; in elf_add_reloc_to_insn()
547 addend = insn_off - sym->offset; in elf_add_reloc_to_insn()
553 static int read_rel_reloc(struct section *sec, int i, struct reloc *reloc, unsigned int *symndx) in read_rel_reloc()
555 if (!gelf_getrel(sec->data, i, &reloc->rel)) { in read_rel_reloc()
557 return -1; in read_rel_reloc()
559 reloc->type = GELF_R_TYPE(reloc->rel.r_info); in read_rel_reloc()
560 reloc->addend = 0; in read_rel_reloc()
561 reloc->offset = reloc->rel.r_offset; in read_rel_reloc()
562 *symndx = GELF_R_SYM(reloc->rel.r_info); in read_rel_reloc()
566 static int read_rela_reloc(struct section *sec, int i, struct reloc *reloc, unsigned int *symndx) in read_rela_reloc()
568 if (!gelf_getrela(sec->data, i, &reloc->rela)) { in read_rela_reloc()
570 return -1; in read_rela_reloc()
572 reloc->type = GELF_R_TYPE(reloc->rela.r_info); in read_rela_reloc()
573 reloc->addend = reloc->rela.r_addend; in read_rela_reloc()
574 reloc->offset = reloc->rela.r_offset; in read_rela_reloc()
575 *symndx = GELF_R_SYM(reloc->rela.r_info); in read_rela_reloc()
581 struct section *sec; in read_relocs()
587 if (!elf_alloc_hash(reloc, elf->text_size / 16)) in read_relocs()
588 return -1; in read_relocs()
590 list_for_each_entry(sec, &elf->sections, list) { in read_relocs()
591 if ((sec->sh.sh_type != SHT_RELA) && in read_relocs()
592 (sec->sh.sh_type != SHT_REL)) in read_relocs()
595 sec->base = find_section_by_index(elf, sec->sh.sh_info); in read_relocs()
596 if (!sec->base) { in read_relocs()
597 WARN("can't find base section for reloc section %s", in read_relocs()
598 sec->name); in read_relocs()
599 return -1; in read_relocs()
602 sec->base->reloc = sec; in read_relocs()
605 for (i = 0; i < sec->sh.sh_size / sec->sh.sh_entsize; i++) { in read_relocs()
609 return -1; in read_relocs()
612 switch (sec->sh.sh_type) { in read_relocs()
615 return -1; in read_relocs()
619 return -1; in read_relocs()
621 default: return -1; in read_relocs()
624 reloc->sec = sec; in read_relocs()
625 reloc->idx = i; in read_relocs()
626 reloc->sym = find_symbol_by_index(elf, symndx); in read_relocs()
627 if (!reloc->sym) { in read_relocs()
629 symndx, sec->name); in read_relocs()
630 return -1; in read_relocs()
633 list_add_tail(&reloc->list, &sec->reloc_list); in read_relocs()
634 elf_hash_add(reloc, &reloc->hash, reloc_hash(reloc)); in read_relocs()
645 printf("reloc_bits: %d\n", elf->reloc_bits); in read_relocs()
665 INIT_LIST_HEAD(&elf->sections); in elf_open_read()
667 elf->fd = open(name, flags); in elf_open_read()
668 if (elf->fd == -1) { in elf_open_read()
681 elf->elf = elf_begin(elf->fd, cmd, NULL); in elf_open_read()
682 if (!elf->elf) { in elf_open_read()
687 if (!gelf_getehdr(elf->elf, &elf->ehdr)) { in elf_open_read()
708 static int elf_add_string(struct elf *elf, struct section *strtab, char *str) in elf_add_string()
717 WARN("can't find .strtab section"); in elf_add_string()
718 return -1; in elf_add_string()
721 s = elf_getscn(elf->elf, strtab->idx); in elf_add_string()
724 return -1; in elf_add_string()
730 return -1; in elf_add_string()
733 data->d_buf = str; in elf_add_string()
734 data->d_size = strlen(str) + 1; in elf_add_string()
735 data->d_align = 1; in elf_add_string()
737 len = strtab->sh.sh_size; in elf_add_string()
738 strtab->sh.sh_size += data->d_size; in elf_add_string()
739 strtab->changed = true; in elf_add_string()
746 struct section *symtab, *symtab_shndx; in elf_create_undef_symbol()
758 sym->name = strdup(name); in elf_create_undef_symbol()
760 sym->sym.st_name = elf_add_string(elf, NULL, sym->name); in elf_create_undef_symbol()
761 if (sym->sym.st_name == -1) in elf_create_undef_symbol()
764 sym->sym.st_info = GELF_ST_INFO(STB_GLOBAL, STT_NOTYPE); in elf_create_undef_symbol()
776 s = elf_getscn(elf->elf, symtab->idx); in elf_create_undef_symbol()
788 data->d_buf = &sym->sym; in elf_create_undef_symbol()
789 data->d_size = sizeof(sym->sym); in elf_create_undef_symbol()
790 data->d_align = 1; in elf_create_undef_symbol()
791 data->d_type = ELF_T_SYM; in elf_create_undef_symbol()
793 sym->idx = symtab->sh.sh_size / sizeof(sym->sym); in elf_create_undef_symbol()
795 symtab->sh.sh_size += data->d_size; in elf_create_undef_symbol()
796 symtab->changed = true; in elf_create_undef_symbol()
800 s = elf_getscn(elf->elf, symtab_shndx->idx); in elf_create_undef_symbol()
812 data->d_buf = &sym->sym.st_size; /* conveniently 0 */ in elf_create_undef_symbol()
813 data->d_size = sizeof(Elf32_Word); in elf_create_undef_symbol()
814 data->d_align = 4; in elf_create_undef_symbol()
815 data->d_type = ELF_T_WORD; in elf_create_undef_symbol()
817 symtab_shndx->sh.sh_size += 4; in elf_create_undef_symbol()
818 symtab_shndx->changed = true; in elf_create_undef_symbol()
821 sym->sec = find_section_by_index(elf, 0); in elf_create_undef_symbol()
828 struct section *elf_create_section(struct elf *elf, const char *name, in elf_create_section()
831 struct section *sec, *shstrtab; in elf_create_section()
842 INIT_LIST_HEAD(&sec->symbol_list); in elf_create_section()
843 INIT_LIST_HEAD(&sec->reloc_list); in elf_create_section()
845 s = elf_newscn(elf->elf); in elf_create_section()
851 sec->name = strdup(name); in elf_create_section()
852 if (!sec->name) { in elf_create_section()
857 sec->idx = elf_ndxscn(s); in elf_create_section()
858 sec->changed = true; in elf_create_section()
860 sec->data = elf_newdata(s); in elf_create_section()
861 if (!sec->data) { in elf_create_section()
866 sec->data->d_size = size; in elf_create_section()
867 sec->data->d_align = 1; in elf_create_section()
870 sec->data->d_buf = malloc(size); in elf_create_section()
871 if (!sec->data->d_buf) { in elf_create_section()
875 memset(sec->data->d_buf, 0, size); in elf_create_section()
878 if (!gelf_getshdr(s, &sec->sh)) { in elf_create_section()
883 sec->sh.sh_size = size; in elf_create_section()
884 sec->sh.sh_entsize = entsize; in elf_create_section()
885 sec->sh.sh_type = SHT_PROGBITS; in elf_create_section()
886 sec->sh.sh_addralign = 1; in elf_create_section()
887 sec->sh.sh_flags = SHF_ALLOC | sh_flags; in elf_create_section()
889 /* Add section name to .shstrtab (or .strtab for Clang) */ in elf_create_section()
894 WARN("can't find .shstrtab or .strtab section"); in elf_create_section()
897 sec->sh.sh_name = elf_add_string(elf, shstrtab, sec->name); in elf_create_section()
898 if (sec->sh.sh_name == -1) in elf_create_section()
901 list_add_tail(&sec->list, &elf->sections); in elf_create_section()
902 elf_hash_add(section, &sec->hash, sec->idx); in elf_create_section()
903 elf_hash_add(section_name, &sec->name_hash, str_hash(sec->name)); in elf_create_section()
905 elf->changed = true; in elf_create_section()
910 static struct section *elf_create_rel_reloc_section(struct elf *elf, struct section *base) in elf_create_rel_reloc_section()
913 struct section *sec; in elf_create_rel_reloc_section()
915 relocname = malloc(strlen(base->name) + strlen(".rel") + 1); in elf_create_rel_reloc_section()
921 strcat(relocname, base->name); in elf_create_rel_reloc_section()
928 base->reloc = sec; in elf_create_rel_reloc_section()
929 sec->base = base; in elf_create_rel_reloc_section()
931 sec->sh.sh_type = SHT_REL; in elf_create_rel_reloc_section()
932 sec->sh.sh_addralign = 8; in elf_create_rel_reloc_section()
933 sec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx; in elf_create_rel_reloc_section()
934 sec->sh.sh_info = base->idx; in elf_create_rel_reloc_section()
935 sec->sh.sh_flags = SHF_INFO_LINK; in elf_create_rel_reloc_section()
940 static struct section *elf_create_rela_reloc_section(struct elf *elf, struct section *base) in elf_create_rela_reloc_section()
943 struct section *sec; in elf_create_rela_reloc_section()
945 relocname = malloc(strlen(base->name) + strlen(".rela") + 1); in elf_create_rela_reloc_section()
951 strcat(relocname, base->name); in elf_create_rela_reloc_section()
958 base->reloc = sec; in elf_create_rela_reloc_section()
959 sec->base = base; in elf_create_rela_reloc_section()
961 sec->sh.sh_type = SHT_RELA; in elf_create_rela_reloc_section()
962 sec->sh.sh_addralign = 8; in elf_create_rela_reloc_section()
963 sec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx; in elf_create_rela_reloc_section()
964 sec->sh.sh_info = base->idx; in elf_create_rela_reloc_section()
965 sec->sh.sh_flags = SHF_INFO_LINK; in elf_create_rela_reloc_section()
970 static struct section *elf_create_reloc_section(struct elf *elf, in elf_create_reloc_section()
971 struct section *base, in elf_create_reloc_section()
981 static int elf_rebuild_rel_reloc_section(struct section *sec) in elf_rebuild_rel_reloc_section()
988 buf = malloc(sec->sh.sh_size); in elf_rebuild_rel_reloc_section()
991 return -1; in elf_rebuild_rel_reloc_section()
994 sec->data->d_buf = buf; in elf_rebuild_rel_reloc_section()
995 sec->data->d_size = sec->sh.sh_size; in elf_rebuild_rel_reloc_section()
996 sec->data->d_type = ELF_T_REL; in elf_rebuild_rel_reloc_section()
999 list_for_each_entry(reloc, &sec->reloc_list, list) { in elf_rebuild_rel_reloc_section()
1000 reloc->rel.r_offset = reloc->offset; in elf_rebuild_rel_reloc_section()
1001 reloc->rel.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type); in elf_rebuild_rel_reloc_section()
1002 if (!gelf_update_rel(sec->data, idx, &reloc->rel)) { in elf_rebuild_rel_reloc_section()
1004 return -1; in elf_rebuild_rel_reloc_section()
1012 static int elf_rebuild_rela_reloc_section(struct section *sec) in elf_rebuild_rela_reloc_section()
1019 buf = malloc(sec->sh.sh_size); in elf_rebuild_rela_reloc_section()
1022 return -1; in elf_rebuild_rela_reloc_section()
1025 sec->data->d_buf = buf; in elf_rebuild_rela_reloc_section()
1026 sec->data->d_size = sec->sh.sh_size; in elf_rebuild_rela_reloc_section()
1027 sec->data->d_type = ELF_T_RELA; in elf_rebuild_rela_reloc_section()
1030 list_for_each_entry(reloc, &sec->reloc_list, list) { in elf_rebuild_rela_reloc_section()
1031 reloc->rela.r_offset = reloc->offset; in elf_rebuild_rela_reloc_section()
1032 reloc->rela.r_addend = reloc->addend; in elf_rebuild_rela_reloc_section()
1033 reloc->rela.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type); in elf_rebuild_rela_reloc_section()
1034 if (!gelf_update_rela(sec->data, idx, &reloc->rela)) { in elf_rebuild_rela_reloc_section()
1036 return -1; in elf_rebuild_rela_reloc_section()
1044 static int elf_rebuild_reloc_section(struct elf *elf, struct section *sec) in elf_rebuild_reloc_section()
1046 switch (sec->sh.sh_type) { in elf_rebuild_reloc_section()
1049 default: return -1; in elf_rebuild_reloc_section()
1053 int elf_write_insn(struct elf *elf, struct section *sec, in elf_write_insn()
1057 Elf_Data *data = sec->data; in elf_write_insn()
1059 if (data->d_type != ELF_T_BYTE || data->d_off) { in elf_write_insn()
1060 WARN("write to unexpected data for section: %s", sec->name); in elf_write_insn()
1061 return -1; in elf_write_insn()
1064 memcpy(data->d_buf + offset, insn, len); in elf_write_insn()
1067 elf->changed = true; in elf_write_insn()
1074 struct section *sec = reloc->sec; in elf_write_reloc()
1076 if (sec->sh.sh_type == SHT_REL) { in elf_write_reloc()
1077 reloc->rel.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type); in elf_write_reloc()
1078 reloc->rel.r_offset = reloc->offset; in elf_write_reloc()
1080 if (!gelf_update_rel(sec->data, reloc->idx, &reloc->rel)) { in elf_write_reloc()
1082 return -1; in elf_write_reloc()
1085 reloc->rela.r_info = GELF_R_INFO(reloc->sym->idx, reloc->type); in elf_write_reloc()
1086 reloc->rela.r_addend = reloc->addend; in elf_write_reloc()
1087 reloc->rela.r_offset = reloc->offset; in elf_write_reloc()
1089 if (!gelf_update_rela(sec->data, reloc->idx, &reloc->rela)) { in elf_write_reloc()
1091 return -1; in elf_write_reloc()
1095 elf->changed = true; in elf_write_reloc()
1102 struct section *sec; in elf_write()
1105 /* Update changed relocation sections and section headers: */ in elf_write()
1106 list_for_each_entry(sec, &elf->sections, list) { in elf_write()
1107 if (sec->changed) { in elf_write()
1108 s = elf_getscn(elf->elf, sec->idx); in elf_write()
1111 return -1; in elf_write()
1113 if (!gelf_update_shdr(s, &sec->sh)) { in elf_write()
1115 return -1; in elf_write()
1118 if (sec->base && in elf_write()
1121 return -1; in elf_write()
1124 sec->changed = false; in elf_write()
1125 elf->changed = true; in elf_write()
1129 /* Make sure the new section header entries get updated properly. */ in elf_write()
1130 elf_flagelf(elf->elf, ELF_C_SET, ELF_F_DIRTY); in elf_write()
1133 if (elf_update(elf->elf, ELF_C_WRITE) < 0) { in elf_write()
1135 return -1; in elf_write()
1138 elf->changed = false; in elf_write()
1145 struct section *sec, *tmpsec; in elf_close()
1149 if (elf->elf) in elf_close()
1150 elf_end(elf->elf); in elf_close()
1152 if (elf->fd > 0) in elf_close()
1153 close(elf->fd); in elf_close()
1155 list_for_each_entry_safe(sec, tmpsec, &elf->sections, list) { in elf_close()
1156 list_for_each_entry_safe(sym, tmpsym, &sec->symbol_list, list) { in elf_close()
1157 list_del(&sym->list); in elf_close()
1158 hash_del(&sym->hash); in elf_close()
1161 list_for_each_entry_safe(reloc, tmpreloc, &sec->reloc_list, list) { in elf_close()
1162 list_del(&reloc->list); in elf_close()
1163 hash_del(&reloc->hash); in elf_close()
1166 list_del(&sec->list); in elf_close()