| .. | .. |
|---|
| 1309 | 1309 | if (relsym->st_name != 0) |
|---|
| 1310 | 1310 | return relsym; |
|---|
| 1311 | 1311 | |
|---|
| 1312 | + /* |
|---|
| 1313 | + * Strive to find a better symbol name, but the resulting name may not |
|---|
| 1314 | + * match the symbol referenced in the original code. |
|---|
| 1315 | + */ |
|---|
| 1312 | 1316 | relsym_secindex = get_secindex(elf, relsym); |
|---|
| 1313 | 1317 | for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { |
|---|
| 1314 | 1318 | if (get_secindex(elf, sym) != relsym_secindex) |
|---|
| .. | .. |
|---|
| 1613 | 1617 | |
|---|
| 1614 | 1618 | static int is_executable_section(struct elf_info* elf, unsigned int section_index) |
|---|
| 1615 | 1619 | { |
|---|
| 1616 | | - if (section_index > elf->num_sections) |
|---|
| 1620 | + if (section_index >= elf->num_sections) |
|---|
| 1617 | 1621 | fatal("section_index is outside elf->num_sections!\n"); |
|---|
| 1618 | 1622 | |
|---|
| 1619 | 1623 | return ((elf->sechdrs[section_index].sh_flags & SHF_EXECINSTR) == SHF_EXECINSTR); |
|---|
| .. | .. |
|---|
| 1788 | 1792 | #define R_ARM_THM_JUMP19 51 |
|---|
| 1789 | 1793 | #endif |
|---|
| 1790 | 1794 | |
|---|
| 1795 | +static int32_t sign_extend32(int32_t value, int index) |
|---|
| 1796 | +{ |
|---|
| 1797 | + uint8_t shift = 31 - index; |
|---|
| 1798 | + |
|---|
| 1799 | + return (int32_t)(value << shift) >> shift; |
|---|
| 1800 | +} |
|---|
| 1801 | + |
|---|
| 1791 | 1802 | static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) |
|---|
| 1792 | 1803 | { |
|---|
| 1793 | 1804 | unsigned int r_typ = ELF_R_TYPE(r->r_info); |
|---|
| 1805 | + Elf_Sym *sym = elf->symtab_start + ELF_R_SYM(r->r_info); |
|---|
| 1806 | + void *loc = reloc_location(elf, sechdr, r); |
|---|
| 1807 | + uint32_t inst; |
|---|
| 1808 | + int32_t offset; |
|---|
| 1794 | 1809 | |
|---|
| 1795 | 1810 | switch (r_typ) { |
|---|
| 1796 | 1811 | case R_ARM_ABS32: |
|---|
| 1797 | | - /* From ARM ABI: (S + A) | T */ |
|---|
| 1798 | | - r->r_addend = (int)(long) |
|---|
| 1799 | | - (elf->symtab_start + ELF_R_SYM(r->r_info)); |
|---|
| 1812 | + inst = TO_NATIVE(*(uint32_t *)loc); |
|---|
| 1813 | + r->r_addend = inst + sym->st_value; |
|---|
| 1800 | 1814 | break; |
|---|
| 1801 | 1815 | case R_ARM_PC24: |
|---|
| 1802 | 1816 | case R_ARM_CALL: |
|---|
| 1803 | 1817 | case R_ARM_JUMP24: |
|---|
| 1818 | + inst = TO_NATIVE(*(uint32_t *)loc); |
|---|
| 1819 | + offset = sign_extend32((inst & 0x00ffffff) << 2, 25); |
|---|
| 1820 | + r->r_addend = offset + sym->st_value + 8; |
|---|
| 1821 | + break; |
|---|
| 1804 | 1822 | case R_ARM_THM_CALL: |
|---|
| 1805 | 1823 | case R_ARM_THM_JUMP24: |
|---|
| 1806 | 1824 | case R_ARM_THM_JUMP19: |
|---|