Fix relocations related to dpcpu and vnet sets. The address is

rebased to point to the allocated memory, but for architectures
that have non-zero relocation addends, the address comparison
happens on the "unfinalized" address.
After the addend is taken into account, call elf_relocaddr() to
make sure we rebase properly.
This commit is contained in:
Marcel Moolenaar 2014-07-26 17:07:32 +00:00
parent 31d743df76
commit 8b4f33c5f6

View file

@ -190,8 +190,7 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
addr = lookup(lf, symidx, 1);
if (addr == 0)
return -1;
addr += addend;
*where = addr;
*where = elf_relocaddr(lf, addr + addend);
break;
case R_PPC_ADDR16_LO: /* #lo(S) */
@ -204,9 +203,8 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
* are relative to relocbase. Detect this condition.
*/
if (addr > relocbase && addr <= (relocbase + addend))
addr = relocbase + addend;
else
addr += addend;
addr = relocbase;
addr = elf_relocaddr(lf, addr + addend);
*hwhere = addr & 0xffff;
break;
@ -220,9 +218,8 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
* are relative to relocbase. Detect this condition.
*/
if (addr > relocbase && addr <= (relocbase + addend))
addr = relocbase + addend;
else
addr += addend;
addr = relocbase;
addr = elf_relocaddr(lf, addr + addend);
*hwhere = ((addr >> 16) + ((addr & 0x8000) ? 1 : 0))
& 0xffff;
break;