提交 f9720205 编写于 作者: B Bernd Schmidt 提交者: Bryan Wu

Binfmt_flat: Add minimum support for the Blackfin relocations

Add minimum support for the Blackfin relocations, since we don't have
enough space in each reloc.  The idea is to store a value with one
relocation so that subsequent ones can access it.

Actually, this patch is required for Blackfin.  Currently if BINFMT_FLAT is
enabled, git-tree kernel will fail to compile.
Signed-off-by: NBernd Schmidt <bernd.schmidt@analog.com>
Signed-off-by: NBryan Wu <bryan.wu@analog.com>
Cc: David McCullough <davidm@snapgear.com>
Cc: Greg Ungerer <gerg@snapgear.com>
Cc: Miles Bader <miles.bader@necel.com>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
上级 f778089c
...@@ -742,6 +742,7 @@ static int load_flat_file(struct linux_binprm * bprm, ...@@ -742,6 +742,7 @@ static int load_flat_file(struct linux_binprm * bprm,
* __start to address 4 so that is okay). * __start to address 4 so that is okay).
*/ */
if (rev > OLD_FLAT_VERSION) { if (rev > OLD_FLAT_VERSION) {
unsigned long persistent = 0;
for (i=0; i < relocs; i++) { for (i=0; i < relocs; i++) {
unsigned long addr, relval; unsigned long addr, relval;
...@@ -749,6 +750,8 @@ static int load_flat_file(struct linux_binprm * bprm, ...@@ -749,6 +750,8 @@ static int load_flat_file(struct linux_binprm * bprm,
relocated (of course, the address has to be relocated (of course, the address has to be
relocated first). */ relocated first). */
relval = ntohl(reloc[i]); relval = ntohl(reloc[i]);
if (flat_set_persistent (relval, &persistent))
continue;
addr = flat_get_relocate_addr(relval); addr = flat_get_relocate_addr(relval);
rp = (unsigned long *) calc_reloc(addr, libinfo, id, 1); rp = (unsigned long *) calc_reloc(addr, libinfo, id, 1);
if (rp == (unsigned long *)RELOC_FAILED) { if (rp == (unsigned long *)RELOC_FAILED) {
...@@ -757,7 +760,7 @@ static int load_flat_file(struct linux_binprm * bprm, ...@@ -757,7 +760,7 @@ static int load_flat_file(struct linux_binprm * bprm,
} }
/* Get the pointer's value. */ /* Get the pointer's value. */
addr = flat_get_addr_from_rp(rp, relval, flags); addr = flat_get_addr_from_rp(rp, relval, flags, &persistent);
if (addr != 0) { if (addr != 0) {
/* /*
* Do the relocation. PIC relocs in the data section are * Do the relocation. PIC relocs in the data section are
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#define flat_argvp_envp_on_stack() 1 #define flat_argvp_envp_on_stack() 1
#define flat_old_ram_flag(flags) 1 #define flat_old_ram_flag(flags) 1
#define flat_reloc_valid(reloc, size) ((reloc) <= (size)) #define flat_reloc_valid(reloc, size) ((reloc) <= (size))
#define flat_set_persistent(relval, p) 0
/* /*
* on the H8 a couple of the relocations have an instruction in the * on the H8 a couple of the relocations have an instruction in the
...@@ -18,7 +19,7 @@ ...@@ -18,7 +19,7 @@
*/ */
#define flat_get_relocate_addr(rel) (rel) #define flat_get_relocate_addr(rel) (rel)
#define flat_get_addr_from_rp(rp, relval, flags) \ #define flat_get_addr_from_rp(rp, relval, flags, persistent) \
(get_unaligned(rp) & ((flags & FLAT_FLAG_GOTPIC) ? 0xffffffff: 0x00ffffff)) (get_unaligned(rp) & ((flags & FLAT_FLAG_GOTPIC) ? 0xffffffff: 0x00ffffff))
#define flat_put_addr_at_rp(rp, addr, rel) \ #define flat_put_addr_at_rp(rp, addr, rel) \
put_unaligned (((*(char *)(rp)) << 24) | ((addr) & 0x00ffffff), rp) put_unaligned (((*(char *)(rp)) << 24) | ((addr) & 0x00ffffff), rp)
......
...@@ -15,9 +15,10 @@ ...@@ -15,9 +15,10 @@
#define flat_stack_align(sp) (*sp += (*sp & 3 ? (4 - (*sp & 3)): 0)) #define flat_stack_align(sp) (*sp += (*sp & 3 ? (4 - (*sp & 3)): 0))
#define flat_argvp_envp_on_stack() 0 #define flat_argvp_envp_on_stack() 0
#define flat_old_ram_flag(flags) (flags) #define flat_old_ram_flag(flags) (flags)
#define flat_set_persistent(relval, p) 0
#define flat_reloc_valid(reloc, size) \ #define flat_reloc_valid(reloc, size) \
(((reloc) - textlen_for_m32r_lo16_data) <= (size)) (((reloc) - textlen_for_m32r_lo16_data) <= (size))
#define flat_get_addr_from_rp(rp, relval, flags) \ #define flat_get_addr_from_rp(rp, relval, flags, persistent) \
m32r_flat_get_addr_from_rp(rp, relval, (text_len) ) m32r_flat_get_addr_from_rp(rp, relval, (text_len) )
#define flat_put_addr_at_rp(rp, addr, relval) \ #define flat_put_addr_at_rp(rp, addr, relval) \
......
...@@ -9,8 +9,9 @@ ...@@ -9,8 +9,9 @@
#define flat_argvp_envp_on_stack() 1 #define flat_argvp_envp_on_stack() 1
#define flat_old_ram_flag(flags) (flags) #define flat_old_ram_flag(flags) (flags)
#define flat_reloc_valid(reloc, size) ((reloc) <= (size)) #define flat_reloc_valid(reloc, size) ((reloc) <= (size))
#define flat_get_addr_from_rp(rp, relval, flags) get_unaligned(rp) #define flat_get_addr_from_rp(rp, relval, flags, p) get_unaligned(rp)
#define flat_put_addr_at_rp(rp, val, relval) put_unaligned(val,rp) #define flat_put_addr_at_rp(rp, val, relval) put_unaligned(val,rp)
#define flat_get_relocate_addr(rel) (rel) #define flat_get_relocate_addr(rel) (rel)
#define flat_set_persistent(relval, p) 0
#endif /* __M68KNOMMU_FLAT_H__ */ #endif /* __M68KNOMMU_FLAT_H__ */
...@@ -16,8 +16,9 @@ ...@@ -16,8 +16,9 @@
#define flat_argvp_envp_on_stack() 0 #define flat_argvp_envp_on_stack() 0
#define flat_old_ram_flag(flags) (flags) #define flat_old_ram_flag(flags) (flags)
#define flat_reloc_valid(reloc, size) ((reloc) <= (size)) #define flat_reloc_valid(reloc, size) ((reloc) <= (size))
#define flat_get_addr_from_rp(rp, relval, flags) get_unaligned(rp) #define flat_get_addr_from_rp(rp, relval, flags, p) get_unaligned(rp)
#define flat_put_addr_at_rp(rp, val, relval) put_unaligned(val,rp) #define flat_put_addr_at_rp(rp, val, relval) put_unaligned(val,rp)
#define flat_get_relocate_addr(rel) (rel) #define flat_get_relocate_addr(rel) (rel)
#define flat_set_persistent(relval, p) 0
#endif /* __ASM_SH_FLAT_H */ #endif /* __ASM_SH_FLAT_H */
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#define flat_stack_align(sp) /* nothing needed */ #define flat_stack_align(sp) /* nothing needed */
#define flat_argvp_envp_on_stack() 0 #define flat_argvp_envp_on_stack() 0
#define flat_old_ram_flag(flags) (flags) #define flat_old_ram_flag(flags) (flags)
#define flat_set_persistent(relval, p) 0
/* We store the type of relocation in the top 4 bits of the `relval.' */ /* We store the type of relocation in the top 4 bits of the `relval.' */
...@@ -46,7 +47,8 @@ flat_get_relocate_addr (unsigned long relval) ...@@ -46,7 +47,8 @@ flat_get_relocate_addr (unsigned long relval)
For the v850, RP should always be half-word aligned. */ For the v850, RP should always be half-word aligned. */
static inline unsigned long flat_get_addr_from_rp (unsigned long *rp, static inline unsigned long flat_get_addr_from_rp (unsigned long *rp,
unsigned long relval, unsigned long relval,
unsigned long flags) unsigned long flags,
unsigned long *persistent)
{ {
short *srp = (short *)rp; short *srp = (short *)rp;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册