Lines Matching refs:elf
3 * elf.c - ELF access library
20 #include "elf.h"
130 struct section *find_section_by_name(const struct elf *elf, const char *name)
134 elf_hash_for_each_possible(elf->section_name_hash, sec, name_hash, str_hash(name))
141 static struct section *find_section_by_index(struct elf *elf,
146 elf_hash_for_each_possible(elf->section_hash, sec, hash, idx)
153 static struct symbol *find_symbol_by_index(struct elf *elf, unsigned int idx)
157 elf_hash_for_each_possible(elf->symbol_hash, sym, hash, idx)
220 struct symbol *find_symbol_by_name(const struct elf *elf, const char *name)
224 elf_hash_for_each_possible(elf->symbol_name_hash, sym, name_hash, str_hash(name))
231 struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec,
243 elf_hash_for_each_possible(elf->reloc_hash, reloc, hash,
260 struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset)
262 return find_reloc_by_dest_range(elf, sec, offset, 1);
265 static int read_sections(struct elf *elf)
272 if (elf_getshdrnum(elf->elf, §ions_nr)) {
277 if (elf_getshdrstrndx(elf->elf, &shstrndx)) {
293 s = elf_getscn(elf->elf, i);
306 sec->name = elf_strptr(elf->elf, shstrndx, sec->sh.sh_name);
327 list_add_tail(&sec->list, &elf->sections);
328 elf_hash_add(elf->section_hash, &sec->hash, sec->idx);
329 elf_hash_add(elf->section_name_hash, &sec->name_hash, str_hash(sec->name));
336 if (elf_nextscn(elf->elf, s)) {
344 static void elf_add_symbol(struct elf *elf, struct symbol *sym)
364 elf_hash_add(elf->symbol_hash, &sym->hash, sym->idx);
365 elf_hash_add(elf->symbol_name_hash, &sym->name_hash, str_hash(sym->name));
375 static int read_symbols(struct elf *elf)
384 symtab = find_section_by_name(elf, ".symtab");
393 symtab_shndx = find_section_by_name(elf, ".symtab_shndx");
415 sym->name = elf_strptr(elf->elf, symtab->sh.sh_link,
428 sym->sec = find_section_by_index(elf, shndx);
439 sym->sec = find_section_by_index(elf, 0);
441 elf_add_symbol(elf, sym);
448 list_for_each_entry(sec, &elf->sections, list) {
474 pfunc = find_symbol_by_name(elf, pname);
508 static struct section *elf_create_reloc_section(struct elf *elf,
512 int elf_add_reloc(struct elf *elf, struct section *sec, unsigned long offset,
517 if (!sec->reloc && !elf_create_reloc_section(elf, sec, SHT_RELA))
534 elf_hash_add(elf->reloc_hash, &reloc->hash, reloc_hash(reloc));
546 static void elf_dirty_reloc_sym(struct elf *elf, struct symbol *sym)
550 list_for_each_entry(sec, &elf->sections, list) {
573 static int elf_update_symbol(struct elf *elf, struct section *symtab,
587 s = elf_getscn(elf->elf, symtab->idx);
594 t = elf_getscn(elf->elf, symtab_shndx->idx);
692 elf_create_section_symbol(struct elf *elf, struct section *sec)
698 symtab = find_section_by_name(elf, ".symtab");
700 symtab_shndx = find_section_by_name(elf, ".symtab_shndx");
727 old = find_symbol_by_index(elf, first_non_local);
732 elf_hash_add(elf->symbol_hash, &old->hash, old->idx);
734 elf_dirty_reloc_sym(elf, old);
736 if (elf_update_symbol(elf, symtab, symtab_shndx, old)) {
745 if (elf_update_symbol(elf, symtab, symtab_shndx, sym)) {
755 elf_add_symbol(elf, sym);
760 int elf_add_reloc_to_insn(struct elf *elf, struct section *sec,
774 sym = elf_create_section_symbol(elf, insn_sec);
781 return elf_add_reloc(elf, sec, offset, type, sym, addend);
810 static int read_relocs(struct elf *elf)
818 list_for_each_entry(sec, &elf->sections, list) {
823 sec->base = find_section_by_index(elf, sec->sh.sh_info);
854 reloc->sym = find_symbol_by_index(elf, symndx);
862 elf_hash_add(elf->reloc_hash, &reloc->hash, reloc_hash(reloc));
878 struct elf *elf_open_read(const char *name, int flags)
880 struct elf *elf;
885 elf = malloc(sizeof(*elf));
886 if (!elf) {
890 memset(elf, 0, offsetof(struct elf, sections));
892 INIT_LIST_HEAD(&elf->sections);
894 elf_hash_init(elf->symbol_hash);
895 elf_hash_init(elf->symbol_name_hash);
896 elf_hash_init(elf->section_hash);
897 elf_hash_init(elf->section_name_hash);
898 elf_hash_init(elf->reloc_hash);
900 elf->fd = open(name, flags);
901 if (elf->fd == -1) {
914 elf->elf = elf_begin(elf->fd, cmd, NULL);
915 if (!elf->elf) {
920 if (!gelf_getehdr(elf->elf, &elf->ehdr)) {
925 if (read_sections(elf))
928 if (read_symbols(elf))
931 if (read_relocs(elf))
934 return elf;
937 elf_close(elf);
941 static int elf_add_string(struct elf *elf, struct section *strtab, char *str)
948 strtab = find_section_by_name(elf, ".strtab");
954 s = elf_getscn(elf->elf, strtab->idx);
978 struct section *elf_create_section(struct elf *elf, const char *name,
995 s = elf_newscn(elf->elf);
1041 shstrtab = find_section_by_name(elf, ".shstrtab");
1043 shstrtab = find_section_by_name(elf, ".strtab");
1048 sec->sh.sh_name = elf_add_string(elf, shstrtab, sec->name);
1052 list_add_tail(&sec->list, &elf->sections);
1053 elf_hash_add(elf->section_hash, &sec->hash, sec->idx);
1054 elf_hash_add(elf->section_name_hash, &sec->name_hash, str_hash(sec->name));
1056 elf->changed = true;
1061 static struct section *elf_create_rel_reloc_section(struct elf *elf, struct section *base)
1074 sec = elf_create_section(elf, relocname, 0, sizeof(GElf_Rel), 0);
1084 sec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx;
1091 static struct section *elf_create_rela_reloc_section(struct elf *elf, struct section *base)
1104 sec = elf_create_section(elf, relocname, 0, sizeof(GElf_Rela), 0);
1114 sec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx;
1121 static struct section *elf_create_reloc_section(struct elf *elf,
1126 case SHT_REL: return elf_create_rel_reloc_section(elf, base);
1127 case SHT_RELA: return elf_create_rela_reloc_section(elf, base);
1191 static int elf_rebuild_reloc_section(struct elf *elf, struct section *sec)
1207 int elf_write_insn(struct elf *elf, struct section *sec,
1221 elf->changed = true;
1226 int elf_write_reloc(struct elf *elf, struct reloc *reloc)
1249 elf->changed = true;
1254 int elf_write(struct elf *elf)
1260 list_for_each_entry(sec, &elf->sections, list) {
1263 elf_rebuild_reloc_section(elf, sec)) {
1268 s = elf_getscn(elf->elf, sec->idx);
1279 elf->changed = true;
1284 elf_flagelf(elf->elf, ELF_C_SET, ELF_F_DIRTY);
1287 if (elf_update(elf->elf, ELF_C_WRITE) < 0) {
1292 elf->changed = false;
1297 void elf_close(struct elf *elf)
1303 if (elf->elf)
1304 elf_end(elf->elf);
1306 if (elf->fd > 0)
1307 close(elf->fd);
1309 list_for_each_entry_safe(sec, tmpsec, &elf->sections, list) {
1324 free(elf);