This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


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

[patch] to bfd: embedded relocs for m68k ELF, part 1 of 2


Hi there,

As promised, I have implemented the embedded relocs feature for m68k ELF. Here
is the bfd part. It must be installed before the ld part, which will follow
right next.

--
Michael Sokolov		Harhan Engineering Laboratory
Public Service Agent	International Free Computing Task Force
			International Engineering and Science Task Force
			615 N GOOD LATIMER EXPY STE #4
			DALLAS TX 75204-5852 USA

Phone: +1-214-824-7693 (Harhan Eng Lab office)
E-mail: msokolov@ivan.Harhan.ORG (ARPA TCP/SMTP) (UUCP coming soon)

2000-09-10  Michael Sokolov  <msokolov@ivan.Harhan.ORG>

	* elf32-m68k.c (bfd_m68k_elf32_create_embedded_relocs): New function.
	* bfd-in.h (bfd_m68k_elf32_create_embedded_relocs): Add declaration.
	* bfd-in2.h: Regenerate.

Index: elf32-m68k.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m68k.c,v
retrieving revision 1.16
diff -c -r1.16 elf32-m68k.c
*** elf32-m68k.c	2000/08/21 23:41:32	1.16
--- elf32-m68k.c	2000/09/11 03:46:17
***************
*** 2179,2184 ****
--- 2179,2322 ----
    return true;
  }
  
+ /* Given a .data section and a .emreloc in-memory section, store
+    relocation information into the .emreloc section which can be
+    used at runtime to relocate the section.  This is called by the
+    linker when the --embedded-relocs switch is used.  This is called
+    after the add_symbols entry point has been called for all the
+    objects, and before the final_link entry point is called.  */
+ 
+ boolean
+ bfd_m68k_elf32_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
+      bfd *abfd;
+      struct bfd_link_info *info;
+      asection *datasec;
+      asection *relsec;
+      char **errmsg;
+ {
+   Elf_Internal_Shdr *symtab_hdr;
+   Elf32_External_Sym *extsyms;
+   Elf32_External_Sym *free_extsyms = NULL;
+   Elf_Internal_Rela *internal_relocs;
+   Elf_Internal_Rela *free_relocs = NULL;
+   Elf_Internal_Rela *irel, *irelend;
+   bfd_byte *p;
+ 
+   BFD_ASSERT (! info->relocateable);
+ 
+   *errmsg = NULL;
+ 
+   if (datasec->reloc_count == 0)
+     return true;
+ 
+   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+   /* Read this BFD's symbols if we haven't done so already, or get the cached
+      copy if it exists.  */
+   if (symtab_hdr->contents != NULL)
+     extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
+   else
+     {
+       /* Go get them off disk.  */
+       if (info.keep_memory)
+ 	extsyms = ((Elf32_External_Sym *)
+ 		   bfd_alloc (abfd, symtab_hdr->sh_size));
+       else
+ 	extsyms = ((Elf32_External_Sym *)
+ 		   bfd_malloc (symtab_hdr->sh_size));
+       if (extsyms == NULL)
+ 	goto error_return;
+       if (! info.keep_memory)
+ 	free_extsyms = extsyms;
+       if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
+ 	  || (bfd_read (extsyms, 1, symtab_hdr->sh_size, abfd)
+ 	      != symtab_hdr->sh_size))
+ 	goto error_return;
+       if (info.keep_memory)
+ 	symtab_hdr->contents = extsyms;
+     }
+ 
+   /* Get a copy of the native relocations.  */
+   internal_relocs = (_bfd_elf32_link_read_relocs
+ 		     (abfd, datasec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
+ 		      info->keep_memory));
+   if (internal_relocs == NULL)
+     goto error_return;
+   if (! info->keep_memory)
+     free_relocs = internal_relocs;
+ 
+   relsec->contents = (bfd_byte *) bfd_alloc (abfd, datasec->reloc_count * 12);
+   if (relsec->contents == NULL)
+     goto error_return;
+ 
+   p = relsec->contents;
+ 
+   irelend = internal_relocs + datasec->reloc_count;
+   for (irel = internal_relocs; irel < irelend; irel++, p += 12)
+     {
+       asection *targetsec;
+ 
+       /* We are going to write a four byte longword into the runtime
+        reloc section.  The longword will be the address in the data
+        section which must be relocated.  It is followed by the name
+        of the target section NUL-padded or truncated to 8
+        characters.  */
+ 
+       /* We can only relocate absolute longword relocs at run time.  */
+       if (ELF32_R_TYPE (irel->r_info) != (int) R_68K_32)
+ 	{
+ 	  *errmsg = _("unsupported reloc type");
+ 	  bfd_set_error (bfd_error_bad_value);
+ 	  goto error_return;
+ 	}
+ 
+       /* Get the target section referred to by the reloc.  */
+       if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
+ 	{
+ 	  Elf_Internal_Sym isym;
+ 
+ 	  /* A local symbol.  */
+ 	  bfd_elf32_swap_symbol_in (abfd,
+ 				    extsyms + ELF32_R_SYM (irel->r_info),
+ 				    &isym);
+ 
+ 	  targetsec = bfd_section_from_elf_index (abfd, isym.st_shndx);
+ 	}
+       else
+ 	{
+ 	  unsigned long indx;
+ 	  struct elf_link_hash_entry *h;
+ 
+ 	  /* An external symbol.  */
+ 	  indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
+ 	  h = elf_sym_hashes (abfd)[indx];
+ 	  BFD_ASSERT (h != NULL);
+ 	  if (h->root.type == bfd_link_hash_defined
+ 	      || h->root.type == bfd_link_hash_defweak)
+ 	    targetsec = h->root.u.def.section;
+ 	  else
+ 	    targetsec = NULL;
+ 	}
+ 
+       bfd_put_32 (abfd, irel->r_offset + datasec->output_offset, p);
+       memset (p + 4, 0, 8);
+       if (targetsec != NULL)
+ 	strncpy (p + 4, targetsec->output_section->name, 8);
+     }
+   
+   if (free_extsyms != NULL)
+     free (free_extsyms);
+   if (free_relocs != NULL)
+     free (free_relocs);
+   return true;
+ 
+ error_return:
+   if (free_extsyms != NULL)
+     free (free_extsyms);
+   if (free_relocs != NULL)
+     free (free_relocs);
+   return false;
+ }
+ 
  #define TARGET_BIG_SYM			bfd_elf32_m68k_vec
  #define TARGET_BIG_NAME			"elf32-m68k"
  #define ELF_MACHINE_CODE		EM_68K
Index: bfd-in.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in.h,v
retrieving revision 1.18
diff -c -r1.18 bfd-in.h
*** bfd-in.h	2000/08/22 19:33:16	1.18
--- bfd-in.h	2000/09/11 03:46:21
***************
*** 652,657 ****
--- 652,661 ----
  /* Return true if address "naturally" sign extends, or -1 if not elf. */
  extern int bfd_get_sign_extend_vma PARAMS ((bfd *));
  
+ extern boolean bfd_m68k_elf32_create_embedded_relocs
+   PARAMS ((bfd *, struct bfd_link_info *, struct sec *, struct sec *,
+ 	   char **));
+ 
  /* SunOS shared library support routines for the linker.  */
  
  extern struct bfd_link_needed_list *bfd_sunos_get_needed_list

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