summaryrefslogtreecommitdiff
path: root/ldso/ldso/mips/dl-sysdep.h
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2006-11-04 20:14:10 +0000
committerEric Andersen <andersen@codepoet.org>2006-11-04 20:14:10 +0000
commitbcd949c7f80ccf66c8ef869367a9b33dbb51a261 (patch)
tree981e52a9924916366df69688e042f3ad427a22c4 /ldso/ldso/mips/dl-sysdep.h
parent980871f06dc4b2359b589fd9d720ed3fc8c3a925 (diff)
mips64 patch from Atsushi Nemoto:
64bit MIPS ELF format tweaks. (from glibc) Elf32/ElfW convertions. asm code adjustments.
Diffstat (limited to 'ldso/ldso/mips/dl-sysdep.h')
-rw-r--r--ldso/ldso/mips/dl-sysdep.h102
1 files changed, 98 insertions, 4 deletions
diff --git a/ldso/ldso/mips/dl-sysdep.h b/ldso/ldso/mips/dl-sysdep.h
index 5f4dfadc3..19f6812a1 100644
--- a/ldso/ldso/mips/dl-sysdep.h
+++ b/ldso/ldso/mips/dl-sysdep.h
@@ -8,6 +8,89 @@
/* Define this if the system uses RELOCA. */
#undef ELF_USES_RELOCA
#include <elf.h>
+
+#ifdef __mips64 /* from glibc sysdeps/mips/elf/ldsodefs.h 1.4 */
+/* The 64-bit MIPS ELF ABI uses an unusual reloc format. Each
+ relocation entry specifies up to three actual relocations, all at
+ the same address. The first relocation which required a symbol
+ uses the symbol in the r_sym field. The second relocation which
+ requires a symbol uses the symbol in the r_ssym field. If all
+ three relocations require a symbol, the third one uses a zero
+ value.
+
+ We define these structures in internal headers because we're not
+ sure we want to make them part of the ABI yet. Eventually, some of
+ this may move into elf/elf.h. */
+
+/* An entry in a 64 bit SHT_REL section. */
+
+typedef struct
+{
+ Elf32_Word r_sym; /* Symbol index */
+ unsigned char r_ssym; /* Special symbol for 2nd relocation */
+ unsigned char r_type3; /* 3rd relocation type */
+ unsigned char r_type2; /* 2nd relocation type */
+ unsigned char r_type1; /* 1st relocation type */
+} _Elf64_Mips_R_Info;
+
+typedef union
+{
+ Elf64_Xword r_info_number;
+ _Elf64_Mips_R_Info r_info_fields;
+} _Elf64_Mips_R_Info_union;
+
+typedef struct
+{
+ Elf64_Addr r_offset; /* Address */
+ _Elf64_Mips_R_Info_union r_info; /* Relocation type and symbol index */
+} Elf64_Mips_Rel;
+
+typedef struct
+{
+ Elf64_Addr r_offset; /* Address */
+ _Elf64_Mips_R_Info_union r_info; /* Relocation type and symbol index */
+ Elf64_Sxword r_addend; /* Addend */
+} Elf64_Mips_Rela;
+
+#define ELF64_MIPS_R_SYM(i) \
+ ((__extension__ (_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_sym)
+#define ELF64_MIPS_R_TYPE(i) \
+ (((_Elf64_Mips_R_Info_union)(i)).r_info_fields.r_type1 \
+ | ((Elf32_Word)(__extension__ (_Elf64_Mips_R_Info_union)(i) \
+ ).r_info_fields.r_type2 << 8) \
+ | ((Elf32_Word)(__extension__ (_Elf64_Mips_R_Info_union)(i) \
+ ).r_info_fields.r_type3 << 16) \
+ | ((Elf32_Word)(__extension__ (_Elf64_Mips_R_Info_union)(i) \
+ ).r_info_fields.r_ssym << 24))
+#define ELF64_MIPS_R_INFO(sym, type) \
+ (__extension__ (_Elf64_Mips_R_Info_union) \
+ (__extension__ (_Elf64_Mips_R_Info) \
+ { (sym), ELF64_MIPS_R_SSYM (type), \
+ ELF64_MIPS_R_TYPE3 (type), \
+ ELF64_MIPS_R_TYPE2 (type), \
+ ELF64_MIPS_R_TYPE1 (type) \
+ }).r_info_number)
+/* These macros decompose the value returned by ELF64_MIPS_R_TYPE, and
+ compose it back into a value that it can be used as an argument to
+ ELF64_MIPS_R_INFO. */
+#define ELF64_MIPS_R_SSYM(i) (((i) >> 24) & 0xff)
+#define ELF64_MIPS_R_TYPE3(i) (((i) >> 16) & 0xff)
+#define ELF64_MIPS_R_TYPE2(i) (((i) >> 8) & 0xff)
+#define ELF64_MIPS_R_TYPE1(i) ((i) & 0xff)
+#define ELF64_MIPS_R_TYPEENC(type1, type2, type3, ssym) \
+ ((type1) \
+ | ((Elf32_Word)(type2) << 8) \
+ | ((Elf32_Word)(type3) << 16) \
+ | ((Elf32_Word)(ssym) << 24))
+
+#undef ELF64_R_SYM
+#define ELF64_R_SYM(i) ELF64_MIPS_R_SYM (i)
+#undef ELF64_R_TYPE
+#define ELF64_R_TYPE(i) ELF64_MIPS_R_TYPE (i)
+#undef ELF64_R_INFO
+#define ELF64_R_INFO(sym, type) ELF64_MIPS_R_INFO ((sym), (type))
+#endif /* __mips64 */
+
#include <link.h>
#define ARCH_NUM 3
@@ -24,7 +107,7 @@ else if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO) \
else if (dpnt->d_tag == DT_MIPS_SYMTABNO) \
dynamic[DT_MIPS_SYMTABNO_IDX] = dpnt->d_un.d_val; \
else if (dpnt->d_tag == DT_MIPS_RLD_MAP) \
- *(Elf32_Addr *)(dpnt->d_un.d_ptr) = (Elf32_Addr) debug_addr; \
+ *(ElfW(Addr) *)(dpnt->d_un.d_ptr) = (ElfW(Addr)) debug_addr; \
} while (0)
/* Initialization sequence for the application/library GOT. */
@@ -64,9 +147,15 @@ struct elf_resolve;
void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt, int lazy);
/* 4096 bytes alignment */
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+#define PAGE_ALIGN (~0xfffUL)
+#define ADDR_ALIGN 0xfffUL
+#define OFFS_ALIGN (0x10000000000UL-0x1000)
+#else /* O32 || N32 */
#define PAGE_ALIGN 0xfffff000
#define ADDR_ALIGN 0xfff
#define OFFS_ALIGN 0x7ffff000
+#endif /* O32 || N32 */
#define elf_machine_type_class(type) ELF_RTYPE_CLASS_PLT
/* MIPS does not have COPY relocs */
@@ -94,8 +183,13 @@ elf_machine_dynamic (void)
#define STRINGXP(X) __STRING(X)
#define STRINGXV(X) STRINGV_(X)
#define STRINGV_(...) # __VA_ARGS__
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+#define PTR_LA dla
+#define PTR_SUBU dsubu
+#else
#define PTR_LA la
#define PTR_SUBU subu
+#endif
/* Return the run-time load address of the shared object. */
static inline ElfW(Addr)
@@ -115,8 +209,8 @@ elf_machine_load_address (void)
}
static inline void
-elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
- Elf32_Word relative_count)
+elf_machine_relative (ElfW(Addr) load_off, const ElfW(Addr) rel_addr,
+ ElfW(Word) relative_count)
{
- /* No REALTIVE relocs in MIPS? */
+ /* No RELATIVE relocs in MIPS? */
}