This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

mips64 elf64 reloc data structures


Even though the standard elf64 relocation data structures work for
big-endian, they don't for little endian, since MIPS ELF64 uses a
mixed-endian format for relocation types, that enables it to pack 3
relocations into a single relocation record.  This patch introduces
support for such relocation data structures, with accessor macros that
replace the standard ones when compiling glibc for mips, so that we
can process n64 LE relocations correctly.  Ok?

Index: ChangeLog
2003-03-14  Alexandre Oliva  <aoliva at redhat dot com>

	* include/elf.h (ELF64_R_SYM, ELF64_R_TYPE, ELF64_R_INFO): Use the
	ELF64_MIPS_ macros for mips.
	* elf/elf.h: Define structures and macros to support MIPS ELF64
	relocations.

Index: include/elf.h
===================================================================
RCS file: /cvs/glibc/libc/include/elf.h,v
retrieving revision 1.2
diff -u -p -r1.2 elf.h
--- include/elf.h 8 Jun 2000 04:45:24 -0000 1.2
+++ include/elf.h 14 Mar 2003 05:15:56 -0000
@@ -3,4 +3,15 @@
 /* Some information which is not meant for the public and therefore not
    in <elf.h>.  */
 # include <dl-dtprocnum.h>
+
+/* MIPS ELF64 uses a non-standard relocation format.  */
+#ifdef __mips
+# 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
+
 #endif
Index: elf/elf.h
===================================================================
RCS file: /cvs/glibc/libc/elf/elf.h,v
retrieving revision 1.130
diff -u -p -r1.130 elf.h
--- elf/elf.h 2 Mar 2003 11:41:51 -0000 1.130
+++ elf/elf.h 14 Mar 2003 05:15:57 -0000
@@ -519,6 +519,70 @@ typedef struct
 #define ELF64_R_TYPE(i)			((i) & 0xffffffff)
 #define ELF64_R_INFO(sym,type)		((((Elf64_Xword) (sym)) << 32) + (type))
 
+/* 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.  */
+
+/* An entry in a 64 bit SHT_REL section.  */
+
+struct Elf64_Mips_R_Info {
+  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 */
+};
+
+union Elf64_Mips_R_Info_union {
+  Elf64_Xword	r_info_number;
+  struct Elf64_Mips_R_Info r_info_fields;
+};
+
+typedef struct
+{
+  Elf64_Addr	r_offset;		/* Address */
+  union Elf64_Mips_R_Info_union r_info; /* Relocation ytpe and symbol index */
+} Elf64_Mips_Rel;
+
+typedef struct
+{
+  Elf64_Addr	r_offset;		/* Address */
+  union Elf64_Mips_R_Info_union r_info; /* Relocation ytpe and symbol index */
+  Elf64_Sxword	r_addend;		/* Addend */
+} Elf64_Mips_Rela;
+
+#define ELF64_MIPS_R_SYM(i) \
+  (((union Elf64_Mips_R_Info_union)(i)).r_info_fields.r_sym)
+#define ELF64_MIPS_R_TYPE(i) \
+  (((union Elf64_Mips_R_Info_union)(i)).r_info_fields.r_type1 \
+   | ((Elf32_Word)((union Elf64_Mips_R_Info_union)(i)).r_info_fields.r_type2 << 8) \
+   | ((Elf32_Word)((union Elf64_Mips_R_Info_union)(i)).r_info_fields.r_type3 << 16) \
+   | ((Elf32_Word)((union Elf64_Mips_R_Info_union)(i)).r_info_fields.r_ssym << 24))
+#define ELF64_MIPS_R_INFO(sym,type) \
+  ((union Elf64_Mips_R_Info_union) \
+   ((struct 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))
+
 /* Program segment header.  */
 
 typedef struct
-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                 aoliva at {redhat dot com, gcc.gnu.org}
CS PhD student at IC-Unicamp        oliva at {lsd dot ic dot unicamp dot br, gnu.org}
Free Software Evangelist                Professional serial bug killer

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]