Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 162688
b: refs/heads/master
c: a769094
h: refs/heads/master
v: v3
  • Loading branch information
Mike Frysinger committed Sep 17, 2009
1 parent 1958357 commit a05411c
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 29 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 459fec9073bca854badc1a719f7c12f5162d0edd
refs/heads/master: a769094061289453e8c331d7746e0e26f5d1e38b
62 changes: 34 additions & 28 deletions trunk/arch/blackfin/kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <linux/kernel.h>
#include <asm/dma.h>
#include <asm/cacheflush.h>
#include <asm/uaccess.h>

void *module_alloc(unsigned long size)
{
Expand Down Expand Up @@ -199,26 +200,23 @@ apply_relocate(Elf_Shdr * sechdrs, const char *strtab,
/* gas does not generate it. */
/*************************************************************************/
int
apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab,
apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
unsigned int symindex, unsigned int relsec,
struct module *mod)
{
unsigned int i;
unsigned short tmp;
Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
Elf32_Sym *sym;
uint32_t *location32;
uint16_t *location16;
uint32_t value;
unsigned long location, value, size;

pr_debug("applying relocate section %u to %u\n", mod->name,
relsec, sechdrs[relsec].sh_info);

for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
/* This is where to make the change */
location16 =
(uint16_t *) (sechdrs[sechdrs[relsec].sh_info].sh_addr +
rel[i].r_offset);
location32 = (uint32_t *) location16;
location = sechdrs[sechdrs[relsec].sh_info].sh_addr +
rel[i].r_offset;

/* This is the symbol it is referring to. Note that all
undefined symbols have been resolved. */
sym = (Elf32_Sym *) sechdrs[symindex].sh_addr
Expand All @@ -227,39 +225,28 @@ apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab,
value += rel[i].r_addend;

#ifdef CONFIG_SMP
if ((unsigned long)location16 >= COREB_L1_DATA_A_START) {
if (location >= COREB_L1_DATA_A_START) {
pr_err("cannot relocate in L1: %u (SMP kernel)",
mod->name, ELF32_R_TYPE(rel[i].r_info));
return -ENOEXEC;
}
#endif

pr_debug("location is %lx, value is %x type is %d\n",
mod->name, (unsigned long)location32, value,
ELF32_R_TYPE(rel[i].r_info));
pr_debug("location is %lx, value is %lx type is %d\n",
mod->name, location, value, ELF32_R_TYPE(rel[i].r_info));

switch (ELF32_R_TYPE(rel[i].r_info)) {

case R_BFIN_LUIMM16:
tmp = (value & 0xffff);
if ((unsigned long)location16 >= L1_CODE_START) {
dma_memcpy(location16, &tmp, 2);
} else
*location16 = tmp;
break;
case R_BFIN_HUIMM16:
tmp = ((value >> 16) & 0xffff);
if ((unsigned long)location16 >= L1_CODE_START) {
dma_memcpy(location16, &tmp, 2);
} else
*location16 = tmp;
break;
value >>= 16;
case R_BFIN_LUIMM16:
case R_BFIN_RIMM16:
*location16 = (value & 0xffff);
size = 2;
break;
case R_BFIN_BYTE4_DATA:
*location32 = value;
size = 4;
break;

case R_BFIN_PCREL24:
case R_BFIN_PCREL24_JUMP_L:
case R_BFIN_PCREL12_JUMP:
Expand All @@ -268,12 +255,31 @@ apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab,
pr_err("unsupported relocation: %u (no -mlong-calls?)\n",
mod->name, ELF32_R_TYPE(rel[i].r_info));
return -ENOEXEC;

default:
pr_err("unknown relocation: %u\n", mod->name,
ELF32_R_TYPE(rel[i].r_info));
return -ENOEXEC;
}

switch (bfin_mem_access_type(location, size)) {
case BFIN_MEM_ACCESS_CORE:
case BFIN_MEM_ACCESS_CORE_ONLY:
memcpy((void *)location, &value, size);
break;
case BFIN_MEM_ACCESS_DMA:
dma_memcpy((void *)location, &value, size);
break;
case BFIN_MEM_ACCESS_ITEST:
isram_memcpy((void *)location, &value, size);
break;
default:
pr_err("invalid relocation for %#lx\n",
mod->name, location);
return -ENOEXEC;
}
}

return 0;
}

Expand Down

0 comments on commit a05411c

Please sign in to comment.