Non pic support was added earlier this year to gcc and friends. This patch implements nonpic support for uClibc. Does this look okay to apply?

Thanks,
Catherine
*** include/elf.h	(revision 230407)
--- include/elf.h	(local)
*************** typedef struct
*** 1544,1549 ****
--- 1544,1550 ----
  #define STO_MIPS_INTERNAL		0x1
  #define STO_MIPS_HIDDEN			0x2
  #define STO_MIPS_PROTECTED		0x3
+ #define STO_MIPS_PLT			0x8
  #define STO_MIPS_SC_ALIGN_UNUSED	0xff
  
  /* MIPS specific values for `st_info'.  */
*************** typedef struct
*** 1689,1696 ****
  #define R_MIPS_TLS_TPREL64	48	/* TP-relative offset, 64 bit */
  #define R_MIPS_TLS_TPREL_HI16	49	/* TP-relative offset, high 16 bits */
  #define R_MIPS_TLS_TPREL_LO16	50	/* TP-relative offset, low 16 bits */
  /* Keep this the last entry.  */
! #define R_MIPS_NUM		51
  
  /* Legal values for p_type field of Elf32_Phdr.  */
  
--- 1690,1700 ----
  #define R_MIPS_TLS_TPREL64	48	/* TP-relative offset, 64 bit */
  #define R_MIPS_TLS_TPREL_HI16	49	/* TP-relative offset, high 16 bits */
  #define R_MIPS_TLS_TPREL_LO16	50	/* TP-relative offset, low 16 bits */
+ #define R_MIPS_GLOB_DAT		51
+ #define R_MIPS_COPY		126
+ #define R_MIPS_JUMP_SLOT        127
  /* Keep this the last entry.  */
! #define R_MIPS_NUM		128
  
  /* Legal values for p_type field of Elf32_Phdr.  */
  
*************** typedef struct
*** 1756,1762 ****
  #define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
  #define DT_MIPS_GP_VALUE     0x70000030 /* GP value for aux GOTs.  */
  #define DT_MIPS_AUX_DYNAMIC  0x70000031 /* Address of aux .dynamic.  */
! #define DT_MIPS_NUM	     0x32
  
  /* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry.  */
  
--- 1760,1772 ----
  #define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
  #define DT_MIPS_GP_VALUE     0x70000030 /* GP value for aux GOTs.  */
  #define DT_MIPS_AUX_DYNAMIC  0x70000031 /* Address of aux .dynamic.  */
! /* The address of .got.plt in an executable using the new non-PIC ABI.  */
! #define DT_MIPS_PLTGOT	     0x70000032
! /* The base of the PLT in an executable using the new non-PIC ABI if that
!    PLT is writable.  For a non-writable PLT, this is omitted or has a zero
!    value.  */
! #define DT_MIPS_RWPLT        0x70000034
! #define DT_MIPS_NUM	     0x35
  
  /* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry.  */
  
*** ldso/ldso/dl-hash.c	(revision 230407)
--- ldso/ldso/dl-hash.c	(local)
*************** check_match (const ElfW(Sym) *sym, char 
*** 160,165 ****
--- 160,170 ----
  		/* undefined symbol itself */
  		return NULL;
  
+ #ifdef __mips__
+     if (sym->st_shndx == SHN_UNDEF && !(sym->st_other & STO_MIPS_PLT))
+         return NULL;
+ #endif
+ 
  	if (sym->st_value == 0)
  		/* No value */
  		return NULL;
*** ldso/ldso/mips/dl-sysdep.h	(revision 230407)
--- ldso/ldso/mips/dl-sysdep.h	(local)
*************** typedef struct
*** 93,102 ****
  
  #include <link.h>
  
! #define ARCH_NUM 3
  #define DT_MIPS_GOTSYM_IDX	(DT_NUM + OS_NUM)
  #define DT_MIPS_LOCAL_GOTNO_IDX	(DT_NUM + OS_NUM +1)
  #define DT_MIPS_SYMTABNO_IDX	(DT_NUM + OS_NUM +2)
  
  #define ARCH_DYNAMIC_INFO(dpnt,  dynamic, debug_addr) \
  do { \
--- 93,103 ----
  
  #include <link.h>
  
! #define ARCH_NUM 4
  #define DT_MIPS_GOTSYM_IDX	(DT_NUM + OS_NUM)
  #define DT_MIPS_LOCAL_GOTNO_IDX	(DT_NUM + OS_NUM +1)
  #define DT_MIPS_SYMTABNO_IDX	(DT_NUM + OS_NUM +2)
+ #define DT_MIPS_PLTGOT_IDX	(DT_NUM + OS_NUM +3)
  
  #define ARCH_DYNAMIC_INFO(dpnt,  dynamic, debug_addr) \
  do { \
*************** else if (dpnt->d_tag == DT_MIPS_LOCAL_GO
*** 106,111 ****
--- 107,114 ----
       dynamic[DT_MIPS_LOCAL_GOTNO_IDX] = dpnt->d_un.d_val; \
  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_PLTGOT) \
+      dynamic[DT_MIPS_PLTGOT_IDX] = dpnt->d_un.d_val; \
  else if (dpnt->d_tag == DT_MIPS_RLD_MAP) \
       *(ElfW(Addr) *)(dpnt->d_un.d_ptr) =  (ElfW(Addr)) debug_addr; \
  } while (0)
*************** else if (dpnt->d_tag == DT_MIPS_RLD_MAP)
*** 114,119 ****
--- 117,123 ----
  #define INIT_GOT(GOT_BASE,MODULE)						\
  do {										\
  	unsigned long idx;							\
+ 	unsigned long *pltgot;							\
  										\
  	/* Check if this is the dynamic linker itself */			\
  	if (MODULE->libtype == program_interpreter)				\
*************** do {										\
*** 123,128 ****
--- 127,138 ----
  	GOT_BASE[0] = (unsigned long) _dl_runtime_resolve;			\
  	GOT_BASE[1] = (unsigned long) MODULE;					\
  										\
+ 	pltgot = MODULE->dynamic_info[DT_MIPS_PLTGOT_IDX];			\
+ 	if (pltgot) {								\
+ 		pltgot[0] = (unsigned long) _dl_runtime_pltresolve;		\
+ 		pltgot[1] = (unsigned long) MODULE;				\
+ 	}									\
+ 										\
  	/* Add load address displacement to all local GOT entries */		\
  	idx = 2;									\
  	while (idx < MODULE->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX])		\
*************** void _dl_perform_mips_global_got_relocat
*** 151,159 ****
  #define OFFS_ALIGN (0x10000000000UL-0x1000)
  #endif	/* O32 || N32 */
  
! #define elf_machine_type_class(type)		ELF_RTYPE_CLASS_PLT
! /* MIPS does not have COPY relocs */
! #define DL_NO_COPY_RELOCS
  
  #define OFFSET_GP_GOT 0x7ff0
  
--- 161,169 ----
  #define OFFS_ALIGN (0x10000000000UL-0x1000)
  #endif	/* O32 || N32 */
  
! #define elf_machine_type_class(type) \
!   ((((type) == R_MIPS_JUMP_SLOT) * ELF_RTYPE_CLASS_PLT)	\
!    | (((type) == R_MIPS_COPY) * ELF_RTYPE_CLASS_COPY))
  
  #define OFFSET_GP_GOT 0x7ff0
  
*** ldso/ldso/mips/elfinterp.c	(revision 230407)
--- ldso/ldso/mips/elfinterp.c	(local)
***************
*** 30,35 ****
--- 30,36 ----
  #include "ldso.h"
  
  extern int _dl_runtime_resolve(void);
+ extern int _dl_runtime_pltresolve(void);
  
  #define OFFSET_GP_GOT 0x7ff0
  
*************** unsigned long __dl_runtime_resolve(unsig
*** 83,88 ****
--- 84,144 ----
  	return new_addr;
  }
  
+ unsigned long
+ __dl_runtime_pltresolve(struct elf_resolve *tpnt, int reloc_entry)
+ {
+ 	int reloc_type;
+ 	ELF_RELOC *this_reloc;
+ 	char *strtab;
+ 	Elf32_Sym *symtab;
+ 	int symtab_index;
+ 	char *rel_addr;
+ 	char *new_addr;
+ 	char **got_addr;
+ 	unsigned long instr_addr;
+ 	char *symname;
+ 
+ 	rel_addr = (char *)tpnt->dynamic_info[DT_JMPREL];
+ 	this_reloc = (ELF_RELOC *)(intptr_t)(rel_addr + reloc_entry);
+ 	reloc_type = ELF32_R_TYPE(this_reloc->r_info);
+ 	symtab_index = ELF32_R_SYM(this_reloc->r_info);
+ 
+ 	symtab = (Elf32_Sym *)(intptr_t)tpnt->dynamic_info[DT_SYMTAB];
+ 	strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
+ 	symname = strtab + symtab[symtab_index].st_name;
+ 
+ 	/* Address of the jump instruction to fix up. */
+ 	instr_addr = ((unsigned long)this_reloc->r_offset +
+ 		      (unsigned long)tpnt->loadaddr);
+ 	got_addr = (char **)instr_addr;
+ 
+ 	/* Get the address of the GOT entry. */
+ 	new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
+ 	if (unlikely(!new_addr)) {
+ 		_dl_dprintf(2, "%s: can't resolve symbol '%s' in lib '%s'.\n", _dl_progname, symname, tpnt->libname);
+ 		_dl_exit(1);
+ 	}
+ 
+ #if defined (__SUPPORT_LD_DEBUG__)
+ 	if ((unsigned long)got_addr < 0x40000000) {
+ 		if (_dl_debug_bindings) {
+ 			_dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname);
+ 			if (_dl_debug_detail)
+ 				_dl_dprintf(_dl_debug_file,
+ 				            "\n\tpatched: %x ==> %x @ %x",
+ 				            *got_addr, new_addr, got_addr);
+ 		}
+ 	}
+ 	if (!_dl_debug_nofixups) {
+ 		*got_addr = new_addr;
+ 	}
+ #else
+ 	*got_addr = new_addr;
+ #endif
+ 
+ 	return (unsigned long)new_addr;
+ }
+ 
  void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
  	unsigned long rel_addr, unsigned long rel_size)
  {
*************** int _dl_parse_relocation_information(str
*** 115,120 ****
--- 171,177 ----
  	got = (unsigned long *) tpnt->dynamic_info[DT_PLTGOT];
  
  	for (i = 0; i < rel_size; i++, rpnt++) {
+ 		char *symname = NULL;
  		reloc_addr = (unsigned long *) (tpnt->loadaddr +
  			(unsigned long) rpnt->r_offset);
  		reloc_type = ELF_R_TYPE(rpnt->r_info);
*************** int _dl_parse_relocation_information(str
*** 128,133 ****
--- 185,200 ----
  			old_val = *reloc_addr;
  #endif
  
+ 		if (reloc_type == R_MIPS_JUMP_SLOT || reloc_type == R_MIPS_COPY) {
+ 			symname = strtab + symtab[symtab_index].st_name;
+ 			symbol_addr = (unsigned long)_dl_find_hash(symname,
+ 								   tpnt->symbol_scope,
+ 								   tpnt,
+ 								   elf_machine_type_class(reloc_type));
+ 			if (unlikely(!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK))
+ 				return 1;
+ 		}
+ 
  		switch (reloc_type) {
  #if _MIPS_SIM == _MIPS_SIM_ABI64
  		case (R_MIPS_64 << 8) | R_MIPS_REL32:
*************** int _dl_parse_relocation_information(str
*** 148,153 ****
--- 215,238 ----
  				*reloc_addr += (unsigned long) tpnt->loadaddr;
  			}
  			break;
+ 		case R_MIPS_JUMP_SLOT:
+ 			*reloc_addr = symbol_addr;
+ 			break;
+ 		case R_MIPS_COPY:
+ 			if (symbol_addr) {
+ #if defined (__SUPPORT_LD_DEBUG__)
+ 				if (_dl_debug_move)
+ 					_dl_dprintf(_dl_debug_file,
+ 						    "\n%s move %d bytes from %x to %x",
+ 						    symname, symtab[symtab_index].st_size,
+ 						    symbol_addr, reloc_addr);
+ #endif
+ 
+ 				_dl_memcpy((char *)reloc_addr,
+ 					   (char *)symbol_addr,
+ 					   symtab[symtab_index].st_size);
+ 			}
+ 			break;
  		case R_MIPS_NONE:
  			break;
  		default:
*** ldso/ldso/mips/resolve.S	(revision 230407)
--- ldso/ldso/mips/resolve.S	(local)
*************** _dl_runtime_resolve:
*** 112,114 ****
--- 112,165 ----
  .end	_dl_runtime_resolve
  .previous
  
+ /* Assembler veneer called from the PLT header code when using the
+    non-PIC ABI.
+ 
+    Code in each PLT entry puts the caller's return address into t7 ($15),
+    the PLT entry index into t8 ($24), the address of _dl_runtime_pltresolve
+    into t9 ($25) and the address of .got.plt into gp ($28).  __dl_runtime_pltresolve
+    needs a0 ($4) to hold the link map and a1 ($5) to hold the index into
+    .rel.plt (== PLT entry index * 4).  */
+ 
+ 	.text
+ 	.align	2
+ 	.globl	_dl_runtime_pltresolve
+ 	.type	_dl_runtime_pltresolve,@function
+ 	.ent	_dl_runtime_pltresolve
+ _dl_runtime_pltresolve:
+ 	.frame	$29, 40, $31
+ 	.set noreorder
+ 	# Save arguments and sp value in stack.
+ 	subu    $29, 40
+         lw      $10, 4($28)
+ 	# Modify t9 ($25) so as to point .cpload instruction.
+ 	addiu   $25, 12
+ 	# Compute GP.
+ 	.cpload $25
+ 	.set reorder
+ 
+ 	/* Store function arguments from registers to stack */
+ 	sw	$15, 36($29)
+ 	sw	$4, 16($29)
+ 	sw	$5, 20($29)
+ 	sw	$6, 24($29)
+ 	sw	$7, 28($29)
+ 
+ 	/* Setup functions args and call __dl_runtime_pltresolve.  */
+ 	move	$4, $10
+         sll     $5, $24, 3
+ 	jal	__dl_runtime_pltresolve
+ 
+ 	/* Restore function arguments from stack to registers */
+ 	lw	$31, 36($29)
+ 	lw	$4, 16($29)
+ 	lw	$5, 20($29)
+ 	lw	$6, 24($29)
+ 	lw	$7, 28($29)
+ 
+ 	/* Do a tail call to the original function */
+ 	addiu	$29, 40
+ 	move	$25, $2
+ 	jr	$25
+ 	.end	_dl_runtime_pltresolve
+ 	.previous
_______________________________________________
uClibc mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/uclibc

Reply via email to