status_t arch_relocate_image(image_t* rootImage, image_t* image, SymbolLookupCache* cache) { status_t status; // No REL on x86_64. // Perform RELA relocations. if (image->rela) { status = relocate_rela(rootImage, image, image->rela, image->rela_len, cache); if (status != B_OK) return status; } // PLT relocations (they are RELA on x86_64). if (image->pltrel) { status = relocate_rela(rootImage, image, (Elf64_Rela*)image->pltrel, image->pltrel_len, cache); if (status != B_OK) return status; } return B_OK; }
status_t arch_relocate_image(image_t *rootImage, image_t *image, SymbolLookupCache* cache) { status_t status; // deal with the rels first if (image->rel) { TRACE(("RELA relocations not supported\n")); return EOPNOTSUPP; } if (image->pltrel) { TRACE(("RELA relocations not supported\n")); return EOPNOTSUPP; #if 0 status = relocate_rel(rootImage, image, image->pltrel, image->pltrel_len); if (status < B_OK) return status; #endif } if (image->rela) { status = relocate_rela(rootImage, image, image->rela, image->rela_len, cache); //int i; if (status < B_OK) return status; //TRACE(("RELA relocations not supported\n")); //return EOPNOTSUPP; //for (i = 1; i * (int)sizeof(Elf32_Rela) < image->rela_len; i++) { // printf("rela: type %d\n", ELF32_R_TYPE(image->rela[i].r_info)); //} } #if 0 if (image->pltrela) { status = relocate_rela(rootImage, image, image->pltrela, image->pltrela_len); if (status < B_OK) return status; } #endif return B_OK; }
static int relocate_section_rela(Elf32_Sym *sym_table, Elf32_Rela *rela, 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(rela->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_rela(rela, sym_val, target_sect) != 0) return -1; } else if (ELF32_ST_BIND(sym->st_info) != STB_WEAK) { DPRINTF(("Undefined symbol for rela[%x] sym=%lx\n", i, (long)sym)); return -1; } else { DPRINTF(("Undefined weak symbol for rela[%x]\n", i)); } rela++; } return 0; }