[prev in list] [next in list] [prev in thread] [next in thread]
List: busybox
Subject: [BusyBox] patch to add v850 support to busybox insmod
From: Miles Bader <miles () lsi ! nec ! co ! jp>
Date: 2002-03-25 23:07:03
[Download RAW message or body]
Hi,
This patch adds support for the v850e processor to busybox's insmod
program. The patch is against busybox 0.60.0 from uClinux-dist-20020214.
Could you apply it?
Thanks,
-Miles
Patch:
["busybox-insmod-v850.patch" (text/x-patch)]
diff -ruP -X../diff.xcl ../orig/uClinux-dist/user/busybox/insmod.c user/busybox/insmod.c
--- ../orig/uClinux-dist/user/busybox/insmod.c Thu Feb 14 11:42:15 2002
+++ user/busybox/insmod.c Tue Mar 26 14:58:37 2002
@@ -6,7 +6,7 @@
* and MIPS.
*
*
- * Copyright (C) 1999,2000,2001 by Lineo, inc.
+ * Copyright (C) 1999,2000,2001, 2002 by Lineo, inc.
* Written by Erik Andersen <andersen@lineo.com>
* and Ron Alder <alder@lineo.com>
*
@@ -106,6 +106,11 @@
// neither used
#endif
+#if defined (__v850e__)
+#define BB_USE_PLT_ENTRIES
+#define BB_PLT_ENTRY_SIZE 8
+#endif
+
#ifndef FILENAME_MAX
#include <limits.h>
#define FILENAME_MAX NAME_MAX
@@ -451,6 +456,19 @@
#define SHT_RELM SHT_RELA
#define Elf32_RelM Elf32_Rela
+#elif defined (__v850e__)
+
+#ifndef EM_CYGNUS_V850 /* grumble */
+#define EM_CYGNUS_V850 0x9080
+#endif
+
+#define MATCH_MACHINE(x) ((x) == EM_V850 || (x) == EM_CYGNUS_V850)
+#define SHT_RELM SHT_RELA
+#define Elf32_RelM Elf32_Rela
+#define ELFDATAM ELFDATA2LSB
+
+#define SYMBOL_PREFIX "_"
+
#else
#error Sorry, but insmod.c does not yet support this architecture...
#endif
@@ -628,6 +646,12 @@
+/* SPFX is always a string, so it can be concatenated to string constants. */
+#ifdef SYMBOL_PREFIX
+#define SPFX SYMBOL_PREFIX
+#else
+#define SPFX ""
+#endif
#define _PATH_MODULES "/lib/modules"
@@ -832,9 +856,22 @@
case R_PPC_NONE:
#elif defined(__mips__)
case R_MIPS_NONE:
+#elif defined (__v850e__)
+ case R_V850_NONE:
#endif
break;
+#if defined (__v850e__)
+ case R_V850_32:
+ /* We write two shorts instead of a long because even
+ 32-bit insns only need half-word alignment, but
+ 32-bit data needs to be long-word aligned. */
+ v += ((unsigned short *)loc)[0];
+ v += ((unsigned short *)loc)[1] << 16;
+ ((unsigned short *)loc)[0] = v & 0xffff;
+ ((unsigned short *)loc)[1] = (v >> 16) & 0xffff;
+ break;
+#else /* !__v850e__ */
#if defined(__sh__)
case R_SH_DIR32:
#elif defined(__arm__)
@@ -850,6 +887,8 @@
#endif
*loc += v;
break;
+#endif /* __v850e__ */
+
#if defined(__mc68000__)
case R_68K_8:
if (v > 0xff)
@@ -1005,6 +1044,9 @@
#if defined(__powerpc__)
case R_PPC_REL24:
#endif
+#if defined (__v850e__)
+ case R_V850_22_PCREL:
+#endif
/* find the plt entry and initialize it if necessary */
assert(isym != NULL);
@@ -1025,18 +1067,33 @@
ip[2] = 0x7d6903a6; /* mtctr r11 */
ip[3] = 0x4e800420; /* bctr */
#endif
+#if defined (__v850e__)
+ /* We have to trash a register, so we assume that any control
+ transfer more than 21-bits away must be a function call
+ (so we can use a call-clobbered register). */
+ ip[0] = 0x0621 + ((v & 0xffff) << 16); /* mov sym, r1 ... */
+ ip[1] = ((v >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
+#endif
pe->inited = 1;
}
/* relative distance to target */
v -= dot;
/* if the target is too far away.... */
- if ((int)v < -0x02000000 || (int)v >= 0x02000000) {
- /* go via the plt */
- v = plt + pe->offset - dot;
- }
+#if defined (__arm__) || defined (__powerpc__)
+ if ((int)v < -0x02000000 || (int)v >= 0x02000000)
+#elif defined (__v850e__)
+ if ((Elf32_Sword)v > 0x1fffff || (Elf32_Sword)v < (Elf32_Sword)-0x200000)
+#endif
+ /* go via the plt */
+ v = plt + pe->offset - dot;
+
+#if defined (__v850e__)
+ if (v & 1)
+#else
if (v & 3)
- ret = obj_reloc_dangerous;
+#endif
+ ret = obj_reloc_dangerous;
/* merge the offset into the instruction. */
#if defined(__arm__)
@@ -1048,6 +1105,17 @@
#if defined(__powerpc__)
*loc = (*loc & ~0x03fffffc) | (v & 0x03fffffc);
#endif
+#if defined (__v850e__)
+ /* We write two shorts instead of a long because even 32-bit insns
+ only need half-word alignment, but the 32-bit data write needs
+ to be long-word aligned. */
+ ((unsigned short *)loc)[0] =
+ (*(unsigned short *)loc & 0xffc0) /* opcode + reg */
+ | ((v >> 16) & 0x3f); /* offs high part */
+ ((unsigned short *)loc)[1] =
+ (v & 0xffff); /* offs low part */
+#endif
+
break;
#endif /* BB_USE_PLT_ENTRIES */
@@ -1207,6 +1275,12 @@
break;
#endif
+#if defined (__v850e__)
+ case R_V850_22_PCREL:
+ pltneeded = 1;
+ break;
+#endif
+
#if defined(__arm__)
case R_ARM_PC24:
case R_ARM_PLT32:
@@ -1254,8 +1328,8 @@
pltneeded = 0;
}
#endif
- }
}
+ }
#if defined(BB_USE_GOT_ENTRIES)
if (got_offset) {
@@ -1631,19 +1705,45 @@
struct new_module_symbol *s;
size_t i;
int used = 0;
+#ifdef SYMBOL_PREFIX
+ char *name_buf = 0;
+ size_t name_alloced_size = 0;
+#endif
for (i = 0, s = syms; i < nsyms; ++i, ++s) {
-
- /* Only add symbols that are already marked external. If we
- override locals we may cause problems for argument initialization.
- We will also create a false dependency on the module. */
+ /* Only add symbols that are already marked external.
+ If we override locals we may cause problems for
+ argument initialization. We will also create a false
+ dependency on the module. */
struct obj_symbol *sym;
+ char *name = (char *)s->name;
- sym = obj_find_symbol(f, (char *) s->name);
- if (sym && !ELFW(ST_BIND) (sym->info) == STB_LOCAL) {
- sym = obj_add_symbol(f, (char *) s->name, -1,
- ELFW(ST_INFO) (STB_GLOBAL, STT_NOTYPE),
- idx, s->value, 0);
+#ifdef SYMBOL_PREFIX
+ /* Prepend SYMBOL_PREFIX to the symbol's name (the
+ kernel exports `C names', but module object files
+ reference `linker names'). */
+ size_t extra = sizeof SYMBOL_PREFIX;
+ size_t name_size = strlen (name) + extra;
+ if (name_size > name_alloced_size) {
+ name_alloced_size = name_size * 2;
+ name_buf = alloca (name_alloced_size);
+ }
+ strcpy (name_buf, SYMBOL_PREFIX);
+ strcpy (name_buf + extra - 1, name);
+ name = name_buf;
+#endif /* SYMBOL_PREFIX */
+
+ sym = obj_find_symbol(f, name);
+ if (sym && !(ELFW(ST_BIND) (sym->info) == STB_LOCAL)) {
+#ifdef SYMBOL_PREFIX
+ /* Put NAME_BUF into more permanent storage. */
+ name = xmalloc (name_size);
+ strcpy (name, name_buf);
+#endif
+ sym = obj_add_symbol(f, name, -1,
+ ELFW(ST_INFO) (STB_GLOBAL,
+ STT_NOTYPE),
+ idx, s->value, 0);
/* Did our symbol just get installed? If so, mark the
module as "used". */
if (sym->secidx == idx)
@@ -2033,9 +2133,9 @@
/* Fill in routines. */
routines.init =
- obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
+ obj_symbol_final_value(f, obj_find_symbol(f, SPFX "init_module"));
routines.cleanup =
- obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
+ obj_symbol_final_value(f, obj_find_symbol(f, SPFX "cleanup_module"));
/* Whew! All of the initialization is complete. Collect the final
module image and give it to the kernel. */
@@ -2461,9 +2561,9 @@
sizeof(struct new_module));
memset(sec->contents, 0, sizeof(struct new_module));
- obj_add_symbol(f, "__this_module", -1,
- ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
- sizeof(struct new_module));
+ obj_add_symbol(f, SPFX "__this_module", -1,
+ ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,
+ sizeof(struct new_module));
obj_string_patch(f, sec->idx, offsetof(struct new_module, name),
m_name);
@@ -2489,7 +2589,7 @@
if (!sec)
return 0;
- tm = obj_find_symbol(f, "__this_module");
+ tm = obj_find_symbol(f, SPFX "__this_module");
dep = (struct new_module_ref *) sec->contents;
for (i = 0; i < n_ext_modules; ++i)
if (ext_modules[i].used) {
@@ -2575,9 +2675,9 @@
}
module->init =
- obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));
+ obj_symbol_final_value(f, obj_find_symbol(f, SPFX "init_module"));
module->cleanup =
- obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));
+ obj_symbol_final_value(f, obj_find_symbol(f, SPFX "cleanup_module"));
sec = obj_find_section(f, "__ex_table");
if (sec) {
@@ -3223,9 +3323,9 @@
static void hide_special_symbols(struct obj_file *f)
{
static const char *const specials[] = {
- "cleanup_module",
- "init_module",
- "kernel_version",
+ SPFX "cleanup_module",
+ SPFX "init_module",
+ SPFX "kernel_version",
NULL
};
--
I'm beginning to think that life is just one long Yoko Ono album; no rhyme
or reason, just a lot of incoherent shrieks and then it's over. --Ian Wolff
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic