Lines Matching full:elf

3  * elf.c - ELF access library
25 #include <objtool/elf.h>
39 __node->next = __elf_table_entry(elf, name, key); \
40 __elf_table_entry(elf, name, key) = __node; \
62 __elf_hash_del(node, &__elf_table_entry(elf, name, key))
66 __elf_bits(elf, name) = max(10, ilog2(size)); \
67 __elf_table(elf, name) = mmap(NULL, \
68 sizeof(struct elf_hash_node *) << __elf_bits(elf, name), \
71 if (__elf_table(elf, name) == (void *)-1L) { \
73 __elf_table(elf, name) = NULL; \
75 __elf_table(elf, name); \
120 struct section *find_section_by_name(const struct elf *elf, const char *name)
124 elf_hash_for_each_possible(elf, section_name, sec, name_hash, str_hash(name)) {
132 static struct section *find_section_by_index(struct elf *elf,
137 elf_hash_for_each_possible(elf, section, sec, hash, idx) {
145 static struct symbol *find_symbol_by_index(struct elf *elf, unsigned int idx)
149 elf_hash_for_each_possible(elf, symbol, sym, hash, idx) {
278 struct symbol *find_symbol_by_name(const struct elf *elf, const char *name)
282 elf_hash_for_each_possible(elf, symbol_name, sym, name_hash, str_hash(name)) {
291 static struct symbol *find_local_symbol_by_file_and_name(const struct elf *elf,
297 elf_hash_for_each_possible(elf, symbol_name, sym, name_hash, str_hash_demangled(name)) {
307 struct symbol *find_global_symbol_by_name(const struct elf *elf, const char *name)
311 elf_hash_for_each_possible(elf, symbol_name, sym, name_hash, str_hash_demangled(name)) {
320 struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec,
332 elf_hash_for_each_possible(elf, reloc, reloc, hash,
350 struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset)
352 return find_reloc_by_dest_range(elf, sec, offset, 1);
360 static int read_sections(struct elf *elf)
367 if (elf_getshdrnum(elf->elf, &sections_nr)) {
372 if (elf_getshdrstrndx(elf->elf, &shstrndx)) {
381 elf->section_data = calloc(sections_nr, sizeof(*sec));
382 if (!elf->section_data) {
387 sec = &elf->section_data[i];
391 s = elf_getscn(elf->elf, i);
404 sec->name = elf_strptr(elf->elf, shstrndx, sec->sh.sh_name);
423 list_add_tail(&sec->list, &elf->sections);
428 elf->num_relocs += sec_num_entries(sec);
433 printf("section_bits: %d\n", elf->section_bits);
437 if (elf_nextscn(elf->elf, s)) {
509 static int elf_add_symbol(struct elf *elf, struct symbol *sym)
522 elf->num_files++;
545 list_add_tail(&sym->global_list, &elf->symbols);
574 static int read_symbols(struct elf *elf)
583 symtab = find_section_by_name(elf, ".symtab");
585 symtab_shndx = find_section_by_name(elf, ".symtab_shndx");
604 elf->symbol_data = calloc(symbols_nr, sizeof(*sym));
605 if (!elf->symbol_data) {
610 INIT_LIST_HEAD(&elf->symbols);
613 sym = &elf->symbol_data[i];
623 sym->name = elf_strptr(elf->elf, symtab->sh.sh_link,
648 sym->sec = find_section_by_index(elf, shndx);
658 sym->sec = find_section_by_index(elf, 0);
660 if (elf_add_symbol(elf, sym))
671 printf("symbol_bits: %d\n", elf->symbol_bits);
675 list_for_each_entry(sec, &elf->sections, list) {
696 pfunc = find_local_symbol_by_file_and_name(elf, sym->file, pname);
698 pfunc = find_global_symbol_by_name(elf, pname);
729 static int mark_group_syms(struct elf *elf)
734 symtab = find_section_by_name(elf, ".symtab");
740 for_each_sec(elf, sec) {
743 sym = find_symbol_by_index(elf, sec->sh.sh_info);
760 static int elf_update_sym_relocs(struct elf *elf, struct symbol *sym)
765 set_reloc_sym(elf, reloc, reloc->sym->idx);
778 static int elf_update_symbol(struct elf *elf, struct section *symtab,
791 s = elf_getscn(elf->elf, symtab->idx);
798 t = elf_getscn(elf->elf, symtab_shndx->idx);
843 mark_sec_changed(elf, symtab, true);
858 mark_sec_changed(elf, symtab_shndx, true);
907 struct symbol *elf_create_symbol(struct elf *elf, const char *name,
929 sym->sym.st_name = elf_add_string(elf, NULL, sym->name);
937 sym->sec = find_section_by_index(elf, 0);
948 symtab = find_section_by_name(elf, ".symtab");
954 symtab_shndx = find_section_by_name(elf, ".symtab_shndx");
966 old = find_symbol_by_index(elf, first_non_local);
973 if (elf_update_symbol(elf, symtab, symtab_shndx, old)) {
978 if (elf_update_sym_relocs(elf, old))
983 mark_sec_changed(elf, old->group_sec, true);
996 if (sym->idx && elf_update_symbol(elf, symtab, symtab_shndx, sym))
1000 mark_sec_changed(elf, symtab, true);
1004 mark_sec_changed(elf, symtab_shndx, true);
1007 if (elf_add_symbol(elf, sym))
1013 int elf_write_symbol(struct elf *elf, struct symbol *sym)
1017 symtab = find_section_by_name(elf, ".symtab");
1023 symtab_shndx = find_section_by_name(elf, ".symtab_shndx");
1025 if (elf_update_symbol(elf, symtab, symtab_shndx, sym))
1028 mark_sec_changed(elf, symtab, true);
1033 struct symbol *elf_create_section_symbol(struct elf *elf, struct section *sec)
1037 sym = elf_create_symbol(elf, sec->name, sec, STB_LOCAL, STT_SECTION, 0, 0);
1046 struct reloc *elf_init_reloc(struct elf *elf, struct section *rsec,
1069 set_reloc_offset(elf, reloc, offset);
1070 set_reloc_sym(elf, reloc, sym->idx);
1071 set_reloc_type(elf, reloc, type);
1072 set_reloc_addend(elf, reloc, addend);
1081 struct reloc *elf_init_reloc_text_sym(struct elf *elf, struct section *sec,
1102 sym = elf_create_section_symbol(elf, insn_sec);
1107 return elf_init_reloc(elf, sec->rsec, reloc_idx, offset, sym, addend,
1108 elf_text_rela_type(elf));
1111 struct reloc *elf_init_reloc_data_sym(struct elf *elf, struct section *sec,
1122 return elf_init_reloc(elf, sec->rsec, reloc_idx, offset, sym, addend,
1123 elf_data_rela_type(elf));
1126 static int read_relocs(struct elf *elf)
1135 if (!elf_alloc_hash(reloc, elf->num_relocs))
1138 list_for_each_entry(rsec, &elf->sections, list) {
1142 rsec->base = find_section_by_index(elf, rsec->sh.sh_info);
1165 reloc->sym = sym = find_symbol_by_index(elf, symndx);
1182 printf("num_relocs: %lu\n", elf->num_relocs);
1183 printf("reloc_bits: %d\n", elf->reloc_bits);
1189 static void mark_rodata(struct elf *elf)
1193 for_each_sec(elf, sec) {
1200 struct elf *elf_open_read(const char *name, int flags)
1202 struct elf *elf;
1207 elf = malloc(sizeof(*elf));
1208 if (!elf) {
1212 memset(elf, 0, sizeof(*elf));
1214 INIT_LIST_HEAD(&elf->sections);
1216 elf->fd = open(name, flags);
1217 if (elf->fd == -1) {
1223 elf->name = strdup(name);
1224 if (!elf->name) {
1236 elf->elf = elf_begin(elf->fd, cmd, NULL);
1237 if (!elf->elf) {
1242 if (!gelf_getehdr(elf->elf, &elf->ehdr)) {
1247 if (read_sections(elf))
1250 mark_rodata(elf);
1252 if (read_symbols(elf))
1255 if (mark_group_syms(elf))
1258 if (read_relocs(elf))
1261 return elf;
1264 elf_close(elf);
1268 struct elf *elf_create_file(GElf_Ehdr *ehdr, const char *name)
1273 struct elf *elf;
1277 elf = calloc(1, sizeof(*elf));
1278 if (!elf) {
1283 INIT_LIST_HEAD(&elf->sections);
1293 elf->fd = mkstemp(tmp_name);
1294 if (elf->fd == -1) {
1299 elf->tmp_name = tmp_name;
1301 elf->name = strdup(name);
1302 if (!elf->name) {
1307 elf->elf = elf_begin(elf->fd, ELF_C_WRITE, NULL);
1308 if (!elf->elf) {
1313 if (!gelf_newehdr(elf->elf, ELFCLASS64)) {
1318 memcpy(&elf->ehdr, ehdr, sizeof(elf->ehdr));
1320 if (!gelf_update_ehdr(elf->elf, &elf->ehdr)) {
1325 INIT_LIST_HEAD(&elf->symbols);
1334 null = elf_create_section(elf, NULL, 0, 0, SHT_NULL, 0, 0);
1335 shstrtab = elf_create_section(elf, NULL, 0, 0, SHT_STRTAB, 1, 0);
1336 strtab = elf_create_section(elf, NULL, 0, 0, SHT_STRTAB, 1, 0);
1345 null->sh.sh_name = elf_add_string(elf, shstrtab, null->name);
1346 shstrtab->sh.sh_name = elf_add_string(elf, shstrtab, shstrtab->name);
1347 strtab->sh.sh_name = elf_add_string(elf, shstrtab, strtab->name);
1356 if (elf_add_string(elf, strtab, "") == -1)
1359 symtab = elf_create_section(elf, ".symtab", 0x18, 0x18, SHT_SYMTAB, 0x8, 0);
1366 elf->ehdr.e_shstrndx = shstrtab->idx;
1367 if (!gelf_update_ehdr(elf->elf, &elf->ehdr)) {
1380 elf_add_symbol(elf, sym);
1382 return elf;
1385 unsigned int elf_add_string(struct elf *elf, struct section *strtab, const char *str)
1390 strtab = find_section_by_name(elf, ".strtab");
1403 if (!elf_add_data(elf, strtab, str, strlen(str) + 1))
1409 void *elf_add_data(struct elf *elf, struct section *sec, const void *data, size_t size)
1419 s = elf_getscn(elf->elf, sec->idx);
1446 mark_sec_changed(elf, sec, true);
1451 struct section *elf_create_section(struct elf *elf, const char *name,
1459 if (name && find_section_by_name(elf, name)) {
1476 s = elf_newscn(elf->elf);
1520 shstrtab = find_section_by_name(elf, ".shstrtab");
1522 shstrtab = find_section_by_name(elf, ".strtab");
1528 sec->sh.sh_name = elf_add_string(elf, shstrtab, sec->name);
1536 list_add_tail(&sec->list, &elf->sections);
1539 mark_sec_changed(elf, sec, true);
1544 static int elf_alloc_reloc(struct elf *elf, struct section *rsec)
1553 rsec->data = elf_newdata(elf_getscn(elf->elf, rsec->idx));
1564 rsec->data->d_size = nr_relocs_new * elf_rela_size(elf);
1578 rsec->data->d_buf = malloc(nr_alloc * elf_rela_size(elf));
1584 nr_relocs_old * elf_rela_size(elf));
1587 nr_alloc * elf_rela_size(elf));
1612 for_each_sym(elf, sym) {
1652 struct section *elf_create_rela_section(struct elf *elf, struct section *sec,
1666 rsec = elf_create_section(elf, rsec_name, nr_relocs * elf_rela_size(elf),
1667 elf_rela_size(elf), SHT_RELA, elf_addr_size(elf),
1684 rsec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx;
1693 struct reloc *elf_create_reloc(struct elf *elf, struct section *sec,
1701 rsec = elf_create_rela_section(elf, sec, 0);
1706 if (find_reloc_by_dest(elf, sec, offset)) {
1711 if (elf_alloc_reloc(elf, rsec))
1714 mark_sec_changed(elf, rsec, true);
1716 return elf_init_reloc(elf, rsec, sec_num_entries(rsec) - 1, offset, sym,
1720 struct section *elf_create_section_pair(struct elf *elf, const char *name,
1726 sec = elf_create_section(elf, name, nr * entsize, entsize,
1731 if (!elf_create_rela_section(elf, sec, nr_relocs))
1737 int elf_write_insn(struct elf *elf, struct section *sec,
1750 mark_sec_changed(elf, sec, true);
1764 static int elf_truncate_section(struct elf *elf, struct section *sec)
1771 s = elf_getscn(elf->elf, sec->idx);
1808 int elf_write(struct elf *elf)
1814 list_for_each_entry(sec, &elf->sections, list) {
1815 if (sec->truncate && elf_truncate_section(elf, sec))
1819 s = elf_getscn(elf->elf, sec->idx);
1831 mark_sec_changed(elf, sec, false);
1836 elf_flagelf(elf->elf, ELF_C_SET, ELF_F_DIRTY);
1839 if (elf_update(elf->elf, ELF_C_WRITE) < 0) {
1844 elf->changed = false;
1849 int elf_close(struct elf *elf)
1851 if (elf->elf)
1852 elf_end(elf->elf);
1854 if (elf->fd > 0)
1855 close(elf->fd);
1857 if (elf->tmp_name && rename(elf->tmp_name, elf->name))