Lines Matching full:elf

3  * elf.c - ELF access library
26 #include <objtool/elf.h>
34 #define __elf_table(name) (elf->name##_hash)
35 #define __elf_bits(name) (elf->name##_bits)
134 struct section *find_section_by_name(const struct elf *elf, const char *name) in find_section_by_name() argument
146 static struct section *find_section_by_index(struct elf *elf, in find_section_by_index() argument
159 static struct symbol *find_symbol_by_index(struct elf *elf, unsigned int idx) in find_symbol_by_index() argument
278 struct symbol *find_symbol_by_name(const struct elf *elf, const char *name) in find_symbol_by_name() argument
291 static struct symbol *find_local_symbol_by_file_and_name(const struct elf *elf, in find_local_symbol_by_file_and_name() argument
307 struct symbol *find_global_symbol_by_name(const struct elf *elf, const char *name) in find_global_symbol_by_name() argument
319 struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec, in find_reloc_by_dest_range() argument
349 struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset) in find_reloc_by_dest() argument
351 return find_reloc_by_dest_range(elf, sec, offset, 1); in find_reloc_by_dest()
359 static int read_sections(struct elf *elf) in read_sections() argument
366 if (elf_getshdrnum(elf->elf, &sections_nr)) { in read_sections()
371 if (elf_getshdrstrndx(elf->elf, &shstrndx)) { in read_sections()
380 elf->section_data = calloc(sections_nr, sizeof(*sec)); in read_sections()
381 if (!elf->section_data) { in read_sections()
386 sec = &elf->section_data[i]; in read_sections()
390 s = elf_getscn(elf->elf, i); in read_sections()
403 sec->name = elf_strptr(elf->elf, shstrndx, sec->sh.sh_name); in read_sections()
422 list_add_tail(&sec->list, &elf->sections); in read_sections()
427 elf->num_relocs += sec_num_entries(sec); in read_sections()
432 printf("section_bits: %d\n", elf->section_bits); in read_sections()
436 if (elf_nextscn(elf->elf, s)) { in read_sections()
475 static int elf_add_symbol(struct elf *elf, struct symbol *sym) in elf_add_symbol() argument
488 elf->num_files++; in elf_add_symbol()
507 list_add_tail(&sym->global_list, &elf->symbols); in elf_add_symbol()
540 static int read_symbols(struct elf *elf) in read_symbols() argument
549 symtab = find_section_by_name(elf, ".symtab"); in read_symbols()
551 symtab_shndx = find_section_by_name(elf, ".symtab_shndx"); in read_symbols()
570 elf->symbol_data = calloc(symbols_nr, sizeof(*sym)); in read_symbols()
571 if (!elf->symbol_data) { in read_symbols()
576 INIT_LIST_HEAD(&elf->symbols); in read_symbols()
579 sym = &elf->symbol_data[i]; in read_symbols()
589 sym->name = elf_strptr(elf->elf, symtab->sh.sh_link, in read_symbols()
602 sym->sec = find_section_by_index(elf, shndx); in read_symbols()
612 sym->sec = find_section_by_index(elf, 0); in read_symbols()
614 if (elf_add_symbol(elf, sym)) in read_symbols()
625 printf("symbol_bits: %d\n", elf->symbol_bits); in read_symbols()
629 list_for_each_entry(sec, &elf->sections, list) { in read_symbols()
650 pfunc = find_local_symbol_by_file_and_name(elf, sym->file, pname); in read_symbols()
652 pfunc = find_global_symbol_by_name(elf, pname); in read_symbols()
683 static int mark_group_syms(struct elf *elf) in mark_group_syms() argument
688 symtab = find_section_by_name(elf, ".symtab"); in mark_group_syms()
694 for_each_sec(elf, sec) { in mark_group_syms()
697 sym = find_symbol_by_index(elf, sec->sh.sh_info); in mark_group_syms()
714 static int elf_update_sym_relocs(struct elf *elf, struct symbol *sym) in elf_update_sym_relocs() argument
719 set_reloc_sym(elf, reloc, reloc->sym->idx); in elf_update_sym_relocs()
732 static int elf_update_symbol(struct elf *elf, struct section *symtab, in elf_update_symbol() argument
745 s = elf_getscn(elf->elf, symtab->idx); in elf_update_symbol()
752 t = elf_getscn(elf->elf, symtab_shndx->idx); in elf_update_symbol()
797 mark_sec_changed(elf, symtab, true); in elf_update_symbol()
812 mark_sec_changed(elf, symtab_shndx, true); in elf_update_symbol()
861 struct symbol *elf_create_symbol(struct elf *elf, const char *name, in elf_create_symbol() argument
883 sym->sym.st_name = elf_add_string(elf, NULL, sym->name); in elf_create_symbol()
891 sym->sec = find_section_by_index(elf, 0); in elf_create_symbol()
902 symtab = find_section_by_name(elf, ".symtab"); in elf_create_symbol()
908 symtab_shndx = find_section_by_name(elf, ".symtab_shndx"); in elf_create_symbol()
920 old = find_symbol_by_index(elf, first_non_local); in elf_create_symbol()
927 if (elf_update_symbol(elf, symtab, symtab_shndx, old)) { in elf_create_symbol()
932 if (elf_update_sym_relocs(elf, old)) in elf_create_symbol()
937 mark_sec_changed(elf, old->group_sec, true); in elf_create_symbol()
950 if (sym->idx && elf_update_symbol(elf, symtab, symtab_shndx, sym)) in elf_create_symbol()
954 mark_sec_changed(elf, symtab, true); in elf_create_symbol()
958 mark_sec_changed(elf, symtab_shndx, true); in elf_create_symbol()
961 if (elf_add_symbol(elf, sym)) in elf_create_symbol()
967 struct symbol *elf_create_section_symbol(struct elf *elf, struct section *sec) in elf_create_section_symbol() argument
971 sym = elf_create_symbol(elf, sec->name, sec, STB_LOCAL, STT_SECTION, 0, 0); in elf_create_section_symbol()
980 struct reloc *elf_init_reloc(struct elf *elf, struct section *rsec, in elf_init_reloc() argument
1003 set_reloc_offset(elf, reloc, offset); in elf_init_reloc()
1004 set_reloc_sym(elf, reloc, sym->idx); in elf_init_reloc()
1005 set_reloc_type(elf, reloc, type); in elf_init_reloc()
1006 set_reloc_addend(elf, reloc, addend); in elf_init_reloc()
1015 struct reloc *elf_init_reloc_text_sym(struct elf *elf, struct section *sec, in elf_init_reloc_text_sym() argument
1036 sym = elf_create_section_symbol(elf, insn_sec); in elf_init_reloc_text_sym()
1041 return elf_init_reloc(elf, sec->rsec, reloc_idx, offset, sym, addend, in elf_init_reloc_text_sym()
1042 elf_text_rela_type(elf)); in elf_init_reloc_text_sym()
1045 struct reloc *elf_init_reloc_data_sym(struct elf *elf, struct section *sec, in elf_init_reloc_data_sym() argument
1056 return elf_init_reloc(elf, sec->rsec, reloc_idx, offset, sym, addend, in elf_init_reloc_data_sym()
1057 elf_data_rela_type(elf)); in elf_init_reloc_data_sym()
1060 static int read_relocs(struct elf *elf) in read_relocs() argument
1069 if (!elf_alloc_hash(reloc, elf->num_relocs)) in read_relocs()
1072 list_for_each_entry(rsec, &elf->sections, list) { in read_relocs()
1076 rsec->base = find_section_by_index(elf, rsec->sh.sh_info); in read_relocs()
1099 reloc->sym = sym = find_symbol_by_index(elf, symndx); in read_relocs()
1116 printf("num_relocs: %lu\n", elf->num_relocs); in read_relocs()
1117 printf("reloc_bits: %d\n", elf->reloc_bits); in read_relocs()
1123 struct elf *elf_open_read(const char *name, int flags) in elf_open_read()
1125 struct elf *elf; in elf_open_read() local
1130 elf = malloc(sizeof(*elf)); in elf_open_read()
1131 if (!elf) { in elf_open_read()
1135 memset(elf, 0, sizeof(*elf)); in elf_open_read()
1137 INIT_LIST_HEAD(&elf->sections); in elf_open_read()
1139 elf->fd = open(name, flags); in elf_open_read()
1140 if (elf->fd == -1) { in elf_open_read()
1146 elf->name = strdup(name); in elf_open_read()
1147 if (!elf->name) { in elf_open_read()
1159 elf->elf = elf_begin(elf->fd, cmd, NULL); in elf_open_read()
1160 if (!elf->elf) { in elf_open_read()
1165 if (!gelf_getehdr(elf->elf, &elf->ehdr)) { in elf_open_read()
1170 if (read_sections(elf)) in elf_open_read()
1173 if (read_symbols(elf)) in elf_open_read()
1176 if (mark_group_syms(elf)) in elf_open_read()
1179 if (read_relocs(elf)) in elf_open_read()
1182 return elf; in elf_open_read()
1185 elf_close(elf); in elf_open_read()
1189 struct elf *elf_create_file(GElf_Ehdr *ehdr, const char *name) in elf_create_file()
1194 struct elf *elf; in elf_create_file() local
1198 elf = calloc(1, sizeof(*elf)); in elf_create_file()
1199 if (!elf) { in elf_create_file()
1204 INIT_LIST_HEAD(&elf->sections); in elf_create_file()
1230 elf->fd = mkstemp(tmp_name); in elf_create_file()
1231 if (elf->fd == -1) { in elf_create_file()
1236 elf->tmp_name = tmp_name; in elf_create_file()
1238 elf->name = strdup(name); in elf_create_file()
1239 if (!elf->name) { in elf_create_file()
1244 elf->elf = elf_begin(elf->fd, ELF_C_WRITE, NULL); in elf_create_file()
1245 if (!elf->elf) { in elf_create_file()
1250 if (!gelf_newehdr(elf->elf, ELFCLASS64)) { in elf_create_file()
1255 memcpy(&elf->ehdr, ehdr, sizeof(elf->ehdr)); in elf_create_file()
1257 if (!gelf_update_ehdr(elf->elf, &elf->ehdr)) { in elf_create_file()
1262 INIT_LIST_HEAD(&elf->symbols); in elf_create_file()
1271 null = elf_create_section(elf, NULL, 0, 0, SHT_NULL, 0, 0); in elf_create_file()
1272 shstrtab = elf_create_section(elf, NULL, 0, 0, SHT_STRTAB, 1, 0); in elf_create_file()
1273 strtab = elf_create_section(elf, NULL, 0, 0, SHT_STRTAB, 1, 0); in elf_create_file()
1282 null->sh.sh_name = elf_add_string(elf, shstrtab, null->name); in elf_create_file()
1283 shstrtab->sh.sh_name = elf_add_string(elf, shstrtab, shstrtab->name); in elf_create_file()
1284 strtab->sh.sh_name = elf_add_string(elf, shstrtab, strtab->name); in elf_create_file()
1293 if (elf_add_string(elf, strtab, "") == -1) in elf_create_file()
1296 symtab = elf_create_section(elf, ".symtab", 0x18, 0x18, SHT_SYMTAB, 0x8, 0); in elf_create_file()
1303 elf->ehdr.e_shstrndx = shstrtab->idx; in elf_create_file()
1304 if (!gelf_update_ehdr(elf->elf, &elf->ehdr)) { in elf_create_file()
1317 elf_add_symbol(elf, sym); in elf_create_file()
1319 return elf; in elf_create_file()
1322 unsigned int elf_add_string(struct elf *elf, struct section *strtab, const char *str) in elf_add_string() argument
1327 strtab = find_section_by_name(elf, ".strtab"); in elf_add_string()
1340 if (!elf_add_data(elf, strtab, str, strlen(str) + 1)) in elf_add_string()
1346 void *elf_add_data(struct elf *elf, struct section *sec, const void *data, size_t size) in elf_add_data() argument
1356 s = elf_getscn(elf->elf, sec->idx); in elf_add_data()
1383 mark_sec_changed(elf, sec, true); in elf_add_data()
1388 struct section *elf_create_section(struct elf *elf, const char *name, in elf_create_section() argument
1396 if (name && find_section_by_name(elf, name)) { in elf_create_section()
1413 s = elf_newscn(elf->elf); in elf_create_section()
1457 shstrtab = find_section_by_name(elf, ".shstrtab"); in elf_create_section()
1459 shstrtab = find_section_by_name(elf, ".strtab"); in elf_create_section()
1465 sec->sh.sh_name = elf_add_string(elf, shstrtab, sec->name); in elf_create_section()
1473 list_add_tail(&sec->list, &elf->sections); in elf_create_section()
1476 mark_sec_changed(elf, sec, true); in elf_create_section()
1481 static int elf_alloc_reloc(struct elf *elf, struct section *rsec) in elf_alloc_reloc() argument
1490 rsec->data = elf_newdata(elf_getscn(elf->elf, rsec->idx)); in elf_alloc_reloc()
1501 rsec->data->d_size = nr_relocs_new * elf_rela_size(elf); in elf_alloc_reloc()
1515 rsec->data->d_buf = malloc(nr_alloc * elf_rela_size(elf)); in elf_alloc_reloc()
1521 nr_relocs_old * elf_rela_size(elf)); in elf_alloc_reloc()
1524 nr_alloc * elf_rela_size(elf)); in elf_alloc_reloc()
1549 for_each_sym(elf, sym) { in elf_alloc_reloc()
1589 struct section *elf_create_rela_section(struct elf *elf, struct section *sec, in elf_create_rela_section() argument
1603 rsec = elf_create_section(elf, rsec_name, nr_relocs * elf_rela_size(elf), in elf_create_rela_section()
1604 elf_rela_size(elf), SHT_RELA, elf_addr_size(elf), in elf_create_rela_section()
1621 rsec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx; in elf_create_rela_section()
1630 struct reloc *elf_create_reloc(struct elf *elf, struct section *sec, in elf_create_reloc() argument
1638 rsec = elf_create_rela_section(elf, sec, 0); in elf_create_reloc()
1643 if (find_reloc_by_dest(elf, sec, offset)) { in elf_create_reloc()
1648 if (elf_alloc_reloc(elf, rsec)) in elf_create_reloc()
1651 mark_sec_changed(elf, rsec, true); in elf_create_reloc()
1653 return elf_init_reloc(elf, rsec, sec_num_entries(rsec) - 1, offset, sym, in elf_create_reloc()
1657 struct section *elf_create_section_pair(struct elf *elf, const char *name, in elf_create_section_pair() argument
1663 sec = elf_create_section(elf, name, nr * entsize, entsize, in elf_create_section_pair()
1668 if (!elf_create_rela_section(elf, sec, nr_relocs)) in elf_create_section_pair()
1674 int elf_write_insn(struct elf *elf, struct section *sec, in elf_write_insn() argument
1687 mark_sec_changed(elf, sec, true); in elf_write_insn()
1701 static int elf_truncate_section(struct elf *elf, struct section *sec) in elf_truncate_section() argument
1708 s = elf_getscn(elf->elf, sec->idx); in elf_truncate_section()
1745 int elf_write(struct elf *elf) in elf_write() argument
1751 list_for_each_entry(sec, &elf->sections, list) { in elf_write()
1752 if (sec->truncate && elf_truncate_section(elf, sec)) in elf_write()
1756 s = elf_getscn(elf->elf, sec->idx); in elf_write()
1768 mark_sec_changed(elf, sec, false); in elf_write()
1773 elf_flagelf(elf->elf, ELF_C_SET, ELF_F_DIRTY); in elf_write()
1776 if (elf_update(elf->elf, ELF_C_WRITE) < 0) { in elf_write()
1781 elf->changed = false; in elf_write()
1786 int elf_close(struct elf *elf) in elf_close() argument
1788 if (elf->elf) in elf_close()
1789 elf_end(elf->elf); in elf_close()
1791 if (elf->fd > 0) in elf_close()
1792 close(elf->fd); in elf_close()
1794 if (elf->tmp_name && rename(elf->tmp_name, elf->name)) in elf_close()