aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2014-03-18 03:05:28 -0400
committerAnton Blanchard <anton@samba.org>2014-04-22 20:05:27 -0400
commit0e60e46e2aa318c92bb224de29b68b6296bb0fde (patch)
tree1926de7c2f97e1ec77b5abefee9a21c1948dcb20 /arch
parent07de8377f7488f262f9694a1567ab93b4dda63bc (diff)
powerpc: make module stub code endian independent
By representing them as words, rather than chars, we can avoid endian ifdefs. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/kernel/module_64.c42
1 files changed, 11 insertions, 31 deletions
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 12664c130d73..7c16b2eefd95 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -47,8 +47,8 @@
47struct ppc64_stub_entry 47struct ppc64_stub_entry
48{ 48{
49 /* 28 byte jump instruction sequence (7 instructions) */ 49 /* 28 byte jump instruction sequence (7 instructions) */
50 unsigned char jump[28]; 50 u32 jump[7];
51 unsigned char unused[4]; 51 u32 unused;
52 /* Data for the above code */ 52 /* Data for the above code */
53 struct ppc64_opd_entry opd; 53 struct ppc64_opd_entry opd;
54}; 54};
@@ -61,25 +61,14 @@ struct ppc64_stub_entry
61 r2) into the stub. */ 61 r2) into the stub. */
62static struct ppc64_stub_entry ppc64_stub = 62static struct ppc64_stub_entry ppc64_stub =
63{ .jump = { 63{ .jump = {
64#ifdef __LITTLE_ENDIAN__ 64 0x3d820000, /* addis r12,r2, <high> */
65 0x00, 0x00, 0x82, 0x3d, /* addis r12,r2, <high> */ 65 0x398c0000, /* addi r12,r12, <low> */
66 0x00, 0x00, 0x8c, 0x39, /* addi r12,r12, <low> */
67 /* Save current r2 value in magic place on the stack. */ 66 /* Save current r2 value in magic place on the stack. */
68 0x28, 0x00, 0x41, 0xf8, /* std r2,40(r1) */ 67 0xf8410028, /* std r2,40(r1) */
69 0x20, 0x00, 0x6c, 0xe9, /* ld r11,32(r12) */ 68 0xe96c0020, /* ld r11,32(r12) */
70 0x28, 0x00, 0x4c, 0xe8, /* ld r2,40(r12) */ 69 0xe84c0028, /* ld r2,40(r12) */
71 0xa6, 0x03, 0x69, 0x7d, /* mtctr r11 */ 70 0x7d6903a6, /* mtctr r11 */
72 0x20, 0x04, 0x80, 0x4e /* bctr */ 71 0x4e800420 /* bctr */
73#else
74 0x3d, 0x82, 0x00, 0x00, /* addis r12,r2, <high> */
75 0x39, 0x8c, 0x00, 0x00, /* addi r12,r12, <low> */
76 /* Save current r2 value in magic place on the stack. */
77 0xf8, 0x41, 0x00, 0x28, /* std r2,40(r1) */
78 0xe9, 0x6c, 0x00, 0x20, /* ld r11,32(r12) */
79 0xe8, 0x4c, 0x00, 0x28, /* ld r2,40(r12) */
80 0x7d, 0x69, 0x03, 0xa6, /* mtctr r11 */
81 0x4e, 0x80, 0x04, 0x20 /* bctr */
82#endif
83} }; 72} };
84 73
85/* Count how many different 24-bit relocations (different symbol, 74/* Count how many different 24-bit relocations (different symbol,
@@ -274,19 +263,10 @@ static inline int create_stub(Elf64_Shdr *sechdrs,
274 struct ppc64_opd_entry *opd, 263 struct ppc64_opd_entry *opd,
275 struct module *me) 264 struct module *me)
276{ 265{
277 Elf64_Half *loc1, *loc2;
278 long reladdr; 266 long reladdr;
279 267
280 *entry = ppc64_stub; 268 *entry = ppc64_stub;
281 269
282#ifdef __LITTLE_ENDIAN__
283 loc1 = (Elf64_Half *)&entry->jump[0];
284 loc2 = (Elf64_Half *)&entry->jump[4];
285#else
286 loc1 = (Elf64_Half *)&entry->jump[2];
287 loc2 = (Elf64_Half *)&entry->jump[6];
288#endif
289
290 /* Stub uses address relative to r2. */ 270 /* Stub uses address relative to r2. */
291 reladdr = (unsigned long)entry - my_r2(sechdrs, me); 271 reladdr = (unsigned long)entry - my_r2(sechdrs, me);
292 if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) { 272 if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) {
@@ -296,8 +276,8 @@ static inline int create_stub(Elf64_Shdr *sechdrs,
296 } 276 }
297 DEBUGP("Stub %p get data from reladdr %li\n", entry, reladdr); 277 DEBUGP("Stub %p get data from reladdr %li\n", entry, reladdr);
298 278
299 *loc1 = PPC_HA(reladdr); 279 entry->jump[0] |= PPC_HA(reladdr);
300 *loc2 = PPC_LO(reladdr); 280 entry->jump[1] |= PPC_LO(reladdr);
301 entry->opd.funcaddr = opd->funcaddr; 281 entry->opd.funcaddr = opd->funcaddr;
302 entry->opd.r2 = opd->r2; 282 entry->opd.r2 = opd->r2;
303 return 1; 283 return 1;