status_t arch_relocate_image(image_t* rootImage, image_t* image, SymbolLookupCache* cache) { status_t status; // deal with the rels first if (image->rel) { status = relocate_rel(rootImage, image, image->rel, image->rel_len, cache); if (status < B_OK) return status; } if (image->pltrel) { status = relocate_rel(rootImage, image, image->pltrel, image->pltrel_len, cache); if (status < B_OK) return status; } if (image->rela) { //int i; TRACE(("RELA relocations not supported\n")); return EOPNOTSUPP; //for (i = 1; i * (int)sizeof(struct Elf32_Rela) < image->rela_len; i++) { // printf("rela: type %d\n", ELF32_R_TYPE(image->rela[i].r_info)); //} } return B_OK; }
static int relocate_section_rel(Elf32_Sym *sym_table, Elf32_Rel *rel, char *target_sect, int nr_reloc, char *strtab) { Elf32_Sym *sym; Elf32_Addr sym_val; int i; for (i = 0; i < nr_reloc; i++) { sym = &sym_table[ELF32_R_SYM(rel->r_info)]; ELFDBG(("%s\n", strtab + sym->st_name)); if (sym->st_shndx != STN_UNDEF) { sym_val = (Elf32_Addr)sect_addr[sym->st_shndx] + sym->st_value; if (relocate_rel(rel, sym_val, target_sect) != 0) return -1; } else if (ELF32_ST_BIND(sym->st_info) != STB_WEAK) { DPRINTF(("Undefined symbol for rel[%x] sym=%lx\n", i, (long)sym)); return -1; } else { DPRINTF(("Undefined weak symbol for rel[%x]\n", i)); } rel++; } return 0; }
static int relocate_rel_array(unsigned char *data, address_t offset, const Elf32_Rel *rel, unsigned rel_count, const Elf32_Shdr *rel_progbits, const Elf32_Sym *sym, unsigned sym_count, const char *strtab) { int ret; for (; rel_count > 0; rel_count--, rel++) { Elf32_Word sym_index = ELF32_R_SYM(rel->r_info); if (sym_index >= sym_count) { fputs("sym_index out of bounds\n", stderr); return -1; } ret = relocate_rel(data, offset, rel, rel_progbits, sym + sym_index, strtab); if (ret < 0) return -1; } return 0; }