summaryrefslogtreecommitdiff
path: root/ldso/ldso/mips/dl-sysdep.h
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2002-04-02 21:12:37 +0000
committerEric Andersen <andersen@codepoet.org>2002-04-02 21:12:37 +0000
commit96749a768287761528a05670560402a16f6839ac (patch)
treec53550a3ec7458f02da07d465c74bae3f752f499 /ldso/ldso/mips/dl-sysdep.h
parentabdb41c778c5892d51fe92879d383eb8ba000028 (diff)
Steven J. Hill's latest mips dynamic loader updates
Diffstat (limited to 'ldso/ldso/mips/dl-sysdep.h')
-rw-r--r--ldso/ldso/mips/dl-sysdep.h92
1 files changed, 70 insertions, 22 deletions
diff --git a/ldso/ldso/mips/dl-sysdep.h b/ldso/ldso/mips/dl-sysdep.h
index 24cbc3d04..8bc6aaccd 100644
--- a/ldso/ldso/mips/dl-sysdep.h
+++ b/ldso/ldso/mips/dl-sysdep.h
@@ -8,36 +8,82 @@
*/
#undef ELF_USES_RELOCA
+
/*
* Get a pointer to the argv array. On many platforms this can be just
* the address if the first argument, on other platforms we need to
* do something a little more subtle here.
*/
-#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long*) ARGS)
+#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long *) ARGS)
+
/*
- * Initialization sequence for a GOT.
+ * Initialization sequence for the application GOT.
*/
-#define INIT_GOT(GOT_BASE,MODULE) \
-{ \
- GOT_BASE[0] = (unsigned long) _dl_linux_resolve; \
- GOT_BASE[1] = (unsigned long) MODULE; \
-}
+#define INIT_GOT(GOT_BASE,MODULE) _dl_init_got(GOT_BASE,MODULE)
+
+
+/*
+ * Here is a macro to perform the GOT relocation. This is only
+ * used when bootstrapping the dynamic loader.
+ */
+#define PERFORM_BOOTSTRAP_GOT(got) \
+do { \
+ Elf32_Sym *sym; \
+ unsigned long i; \
+ \
+ /* Add load address displacement to all local GOT entries */ \
+ i = 2; \
+ while (i < mips_local_gotno) \
+ got[i++] += load_addr; \
+ \
+ /* Handle global GOT entries */ \
+ got += mips_local_gotno; \
+ sym = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + \
+ load_addr) + mips_gotsym; \
+ i = mips_symtabno - mips_gotsym; \
+ \
+ while (i--) { \
+ if (sym->st_shndx == SHN_UNDEF || \
+ sym->st_shndx == SHN_COMMON) \
+ *got = load_addr + sym->st_value; \
+ else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && \
+ *got != sym->st_value) \
+ *got += load_addr; \
+ else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) { \
+ if (sym->st_other == 0) \
+ *got += load_addr; \
+ } \
+ else \
+ *got = load_addr + sym->st_value; \
+ \
+ got++; \
+ sym++; \
+ } \
+} while (0)
+
/*
* Here is a macro to perform a relocation. This is only used when
- * bootstrapping the dynamic loader. RELP is the relocation that we
- * are performing, REL is the pointer to the address we are relocating.
- * SYMBOL is the symbol involved in the relocation, and LOAD is the
- * load address.
- *
- * !!!NOTE!!!
- *
- * For MIPS, we don't have any DT_JMPREL or DT_PLTRELSZ dynamic
- * entries, so this macro function is empty. The code contained
- * in elfinterp.c does the real relocation work.
+ * bootstrapping the dynamic loader.
*/
-#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD)
+#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD) \
+ switch(ELF32_R_TYPE((RELP)->r_info)) { \
+ case R_MIPS_REL32: \
+ if (symtab_index) { \
+ if (symtab_index < mips_gotsym) \
+ *REL += SYMBOL + LOAD; \
+ } \
+ else { \
+ *REL += LOAD; \
+ } \
+ break; \
+ case R_MIPS_NONE: \
+ break; \
+ default: \
+ SEND_STDERR("Aiieeee!"); \
+ _dl_exit(1); \
+ }
/*
@@ -45,19 +91,21 @@
* is done. This routine has to exit the current function, then
* call the _dl_elf_main function.
*/
-
#define START() return (void) _dl_elf_main;
-
/* Here we define the magic numbers that this dynamic loader should accept */
-
#define MAGIC1 EM_MIPS
#define MAGIC2 EM_MIPS_RS3_LE
+
+
/* Used for error messages */
#define ELF_TARGET "MIPS"
+
struct elf_resolve;
-unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
+extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt,
+ int reloc_entry);
+void _dl_init_got(unsigned long *got, struct elf_resolve *tpnt);
#define do_rem(result, n, base) result = (n % base)