diff options
author | Mike Frysinger <vapier@gentoo.org> | 2006-06-06 06:30:32 +0000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2006-06-06 06:30:32 +0000 |
commit | 280dae74b052c6b75c48de5a0d883cb7a07a2e3a (patch) | |
tree | 8904ca7777cda5fa6450d130c939050a907fce5a | |
parent | 2a13175440420169e575c433de6c35e1399290e9 (diff) | |
download | busybox-280dae74b052c6b75c48de5a0d883cb7a07a2e3a.tar.gz |
import support for microblaze relocations from uClinux-dist
-rw-r--r-- | modutils/insmod.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/modutils/insmod.c b/modutils/insmod.c index f6943291e..7ed4cdb30 100644 --- a/modutils/insmod.c +++ b/modutils/insmod.c @@ -988,6 +988,65 @@ arch_apply_relocation(struct obj_file *f, *loc += v - got; break; +#elif defined (__microblaze__) + case R_MICROBLAZE_NONE: + case R_MICROBLAZE_64_NONE: + case R_MICROBLAZE_32_SYM_OP_SYM: + case R_MICROBLAZE_32_PCREL: + break; + + case R_MICROBLAZE_64_PCREL: { + /* dot is the address of the current instruction. + * v is the target symbol address. + * So we need to extract the offset in the code, + * adding v, then subtrating the current address + * of this instruction. + * Ex: "IMM 0xFFFE bralid 0x0000" = "bralid 0xFFFE0000" + */ + + /* Get split offset stored in code */ + unsigned int temp = (loc[0] & 0xFFFF) << 16 | + (loc[1] & 0xFFFF); + + /* Adjust relative offset. -4 adjustment required + * because dot points to the IMM insn, but branch + * is computed relative to the branch instruction itself. + */ + temp += v - dot - 4; + + /* Store back into code */ + loc[0] = (loc[0] & 0xFFFF0000) | temp >> 16; + loc[1] = (loc[1] & 0xFFFF0000) | (temp & 0xFFFF); + + break; + } + + case R_MICROBLAZE_32: + *loc += v; + break; + + case R_MICROBLAZE_64: { + /* Get split pointer stored in code */ + unsigned int temp1 = (loc[0] & 0xFFFF) << 16 | + (loc[1] & 0xFFFF); + + /* Add reloc offset */ + temp1+=v; + + /* Store back into code */ + loc[0] = (loc[0] & 0xFFFF0000) | temp1 >> 16; + loc[1] = (loc[1] & 0xFFFF0000) | (temp1 & 0xFFFF); + + break; + } + + case R_MICROBLAZE_32_PCREL_LO: + case R_MICROBLAZE_32_LO: + case R_MICROBLAZE_SRO32: + case R_MICROBLAZE_SRW32: + ret = obj_reloc_unhandled; + break; + #elif defined(__mc68000__) case R_68K_NONE: |