.. | .. |
---|
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: |
---|