+2000-09-16 Ralf Baechle <ralf@gnu.org>
+
+ * sysdeps/mips/dl-machine.h (_RTLD_PROLOGUE): Reformat. Declare
+ as function.
+ (_RTLD_EPILOGUE): Reformat. Declare size of entry function.
+ (ELF_MACHINE_BEFORE_RTLD_RELOC): Relocate the dynamic linker itself so
+ it will even work when not loaded to the standard address.
+ (RTLD_START): Reformat. Call _dl_start in a way that is safe even
+ before the dynamic linker itself is relocated.
+
+2000-09-18 Andreas Jaeger <aj@suse.de>
+
+ * sysdeps/unix/sysv/linux/kernel-features.h: Always define
+ __ASSUME_32BITUIDS for MIPS.
+ * sysdeps/unix/sysv/linux/mips/ipc_priv.h: New file.
+ * sysdeps/unix/sysv/linux/mips/Dist: Add ipc_priv.h.
+
2000-09-17 H.J. Lu <hjl@gnu.org>
* catgets/Makefile ($(objpfx)de/libc.cat): Use
#define OFFSET_GP_GOT 0x7ff0
#ifndef _RTLD_PROLOGUE
-# define _RTLD_PROLOGUE(entry) "\n\t.globl " __STRING(entry) \
- "\n\t.ent " __STRING(entry) \
- "\n\t" __STRING(entry) ":\n\t"
+# define _RTLD_PROLOGUE(entry) \
+ ".globl\t" __STRING(entry) "\n\t" \
+ ".ent\t" __STRING(entry) "\n\t" \
+ ".type\t" __STRING(entry) ", @function\n" \
+ __STRING(entry) ":\n\t"
#endif
#ifndef _RTLD_EPILOGUE
-# define _RTLD_EPILOGUE(entry) "\t.end " __STRING(entry) "\n"
+# define _RTLD_EPILOGUE(entry) \
+ ".end\t" __STRING(entry) "\n\t" \
+ ".size\t" __STRING(entry) ", . - " __STRING(entry) "\n\t"
#endif
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries.
/* The MSB of got[1] of a gnu object is set to identify gnu objects. */
#define ELF_MIPS_GNU_GOT1_MASK 0x80000000
+/* We can't rely on elf_machine_got_rel because _dl_object_relocation_scope
+ fiddles with global data. */
+#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) \
+do { \
+ struct link_map *map = &bootstrap_map; \
+ ElfW(Sym) *sym; \
+ ElfW(Addr) *got; \
+ int i, n; \
+ \
+ got = (ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]); \
+ \
+ \
+ if (__builtin_expect (map->l_addr == 0, 1)) \
+ goto done; \
+ \
+ /* got[0] is reserved. got[1] is also reserved for the dynamic object \
+ generated by gnu ld. Skip these reserved entries from \
+ relocation. */ \
+ i = (got[1] & ELF_MIPS_GNU_GOT1_MASK)? 2 : 1; \
+ n = map->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val; \
+ \
+ /* Add the run-time display to all local got entries. */ \
+ while (i < n) \
+ got[i++] += map->l_addr; \
+ \
+ /* Handle global got entries. */ \
+ got += n; \
+ sym = (ElfW(Sym) *) D_PTR(map, l_info[DT_SYMTAB]) \
+ + map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val; \
+ i = (map->l_info[DT_MIPS (SYMTABNO)]->d_un.d_val \
+ - map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val); \
+ \
+ while (i--) \
+ { \
+ if (sym->st_shndx == SHN_UNDEF || sym->st_shndx == SHN_COMMON) \
+ *got = map->l_addr + sym->st_value; \
+ else if (ELFW(ST_TYPE) (sym->st_info) == STT_FUNC \
+ && *got != sym->st_value) \
+ *got += map->l_addr; \
+ else if (ELFW(ST_TYPE) (sym->st_info) == STT_SECTION) \
+ { \
+ if (sym->st_other == 0) \
+ *got += map->l_addr; \
+ } \
+ else \
+ *got = map->l_addr + sym->st_value; \
+ \
+ got++; \
+ sym++; \
+ } \
+done: \
+} while(0)
+
+
/* Get link map for callers object containing STUB_PC. */
static inline struct link_map *
elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc)
2) That under Linux the entry is named __start
and not just plain _start. */
-#define RTLD_START asm ("\
- .text\n"\
-_RTLD_PROLOGUE(ENTRY_POINT)\
-" .globl _dl_start_user\n\
+#define RTLD_START asm (\
+ ".text\n"\
+ _RTLD_PROLOGUE(ENTRY_POINT)\
+ ".set noreorder\n\
.set noreorder\n\
bltzal $0, 0f\n\
nop\n\
sw $4, -0x7ff0($28)\n\
move $4, $29\n\
subu $29, 16\n\
- jal _dl_start\n\
+ \n\
+ la $8, coff\n\
+ bltzal $8, coff\n\
+coff: subu $8, $31, $8\n\
+ \n\
+ la $25, _dl_start\n\
+ addu $25, $8\n\
+ jalr $25\n\
+ \n\
addiu $29, 16\n\
# Get the value of label '_dl_start_user' in t9 ($25).\n\
la $25, _dl_start_user\n\
+ .globl _dl_start_user\n\
_dl_start_user:\n\
.set noreorder\n\
.cpload $25\n\
la $2, _dl_fini\n\
# Jump to the user entry point.\n\
move $25, $17\n\
- jr $25\n"\
-_RTLD_EPILOGUE(ENTRY_POINT)\
- "\n.previous"\
+ jr $25\n\t"\
+ _RTLD_EPILOGUE(ENTRY_POINT)\
+ ".previous"\
);
/* The MIPS never uses Elfxx_Rela relocations. */
/* got[0] is reserved. got[1] is also reserved for the dynamic object
generated by gnu ld. Skip these reserved entries from relocation. */
- i = (got[1] & ELF_MIPS_GNU_GOT1_MASK)? 2: 1;
+ i = (got[1] & ELF_MIPS_GNU_GOT1_MASK)? 2 : 1;
n = map->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val;
/* Add the run-time display to all local got entries if needed. */
if (__builtin_expect (map->l_addr != 0, 0))