Page MenuHomeFreeBSD

D16794.id.diff
No OneTemporary

D16794.id.diff

Index: stand/common/reloc_elf.c
===================================================================
--- stand/common/reloc_elf.c
+++ stand/common/reloc_elf.c
@@ -201,27 +201,81 @@
return (0);
#elif defined(__powerpc__)
- Elf_Size w;
+ Elf_Addr *where;
+ Elf_Half *hwhere;
+ Elf_Addr addr;
+ Elf_Addr addend;
+ Elf_Word rtype, symidx;
const Elf_Rela *rela;
switch (reltype) {
case ELF_RELOC_RELA:
rela = reldata;
- if (relbase + rela->r_offset >= dataaddr &&
- relbase + rela->r_offset < dataaddr + len) {
- switch (ELF_R_TYPE(rela->r_info)) {
- case R_PPC_RELATIVE:
- w = relbase + rela->r_addend;
- bcopy(&w, (u_char *)data + (relbase +
- rela->r_offset - dataaddr), sizeof(w));
- break;
- default:
- printf("\nunhandled relocation type %u\n",
- (u_int)ELF_R_TYPE(rela->r_info));
- return (EFTYPE);
- }
- }
+ where = (Elf_Addr *)((char *)data + relbase + rela->r_offset -
+ dataaddr);
+ hwhere = (Elf_Half *)where;
+ addend = rela->r_addend;
+ rtype = ELF_R_TYPE(rela->r_info);
+ symidx = ELF_R_SYM(rela->r_info);
+ break;
+ default:
+ printf("\nPPC only supports RELA relocations\n");
+ return (EFTYPE);
+ }
+
+ if ((char *)where < (char *)data || (char *)where >= (char *)data + len)
+ printf("\nReloc %d outside of data, offset %lu",
+ rtype, (long)rela->r_offset);
+
+ switch (rtype) {
+ case R_PPC_NONE:
break;
+
+ case R_PPC_ADDR32: /* word32 S + A */
+ addr = symaddr(ef, symidx);
+ if (addr == 0)
+ return (ESRCH);
+ *where = addr + addend;
+ break;
+
+ case R_PPC_ADDR16_LO: /* #lo(S) */
+ addr = symaddr(ef, symidx);
+ if (addr == 0)
+ return (ESRCH);
+ /*
+ * addend values are sometimes relative to sections
+ * (i.e. .rodata) in rela, where in reality they
+ * are relative to relbase. Detect this condition.
+ */
+ if (addr > relbase && addr <= (relbase + addend))
+ addr = relbase;
+ addr = addr + addend;
+ *hwhere = addr & 0xffff;
+ break;
+
+ case R_PPC_ADDR16_HA: /* #ha(S) */
+ addr = symaddr(ef, symidx);
+ if (addr == 0)
+ return (ESRCH);
+ /*
+ * addend values are sometimes relative to sections
+ * (i.e. .rodata) in rela, where in reality they
+ * are relative to relbase. Detect this condition.
+ */
+ if (addr > relbase && addr <= (relbase + addend))
+ addr = relbase;
+ addr = addr + addend;
+ *hwhere = ((addr >> 16) + ((addr & 0x8000) ? 1 : 0))
+ & 0xffff;
+ break;
+
+ case R_PPC_RELATIVE: /* word32 B + A */
+ *where = relbase + addend;
+ break;
+
+ default:
+ printf("\nunhandled relocation type %u\n", rtype);
+ return (EFTYPE);
}
return (0);

File Metadata

Mime Type
text/plain
Expires
Sat, Apr 11, 10:59 AM (14 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31222935
Default Alt Text
D16794.id.diff (2 KB)

Event Timeline