"__idata5_magic__",
target,
coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,			   contents, relocs, syms, sections)     bfd *output_bfd;     struct bfd_link_info *info;     bfd *input_bfd;     asection *input_section;     bfd_byte *contents;     struct internal_reloc *relocs;     struct internal_syment *syms;     asection **sections;{  struct internal_reloc *rel;  struct internal_reloc *relend;  boolean hihalf;  bfd_vma hihalf_val;  asection *toc_section = 0;  bfd_vma relocation;  reloc_howto_type *howto = 0;  #ifdef DEBUG_RELOC  fprintf(stderr, 	  "pe_ppc_relocate_section (%s) for %s \n", 	  TARGET_LITTLE_NAME,	  input_section->name);  #endif    /* If we are performing a relocateable link, we don't need to do a     thing.  The caller will take care of adjusting the reloc     addresses and symbol indices.  */  if (info->relocateable)    return true;    hihalf = false;  hihalf_val = 0;  rel = relocs;  relend = rel + input_section->reloc_count;  for (; rel < relend; rel++)    {      long symndx;      struct ppc_coff_link_hash_entry *h;      struct internal_syment *sym;      bfd_vma val;      asection *sec;      bfd_reloc_status_type rstat;      bfd_byte *loc;      unsigned short r_type  = EXTRACT_TYPE (rel->r_type);      unsigned short r_flags = EXTRACT_FLAGS(rel->r_type);      unsigned short junk    = EXTRACT_JUNK (rel->r_type);  #ifdef DEBUG_RELOC      /* now examine flags */      if (r_flags != 0) 	{	  fprintf (stderr, "Reloc with flags found!");	  if ( r_flags & IMAGE_REL_PPC_NEG ) 	    fprintf (stderr, " NEG");	  if ( r_flags & IMAGE_REL_PPC_BRTAKEN )	    fprintf (stderr, " BRTAKEN");	  if ( r_flags & IMAGE_REL_PPC_BRNTAKEN )	    fprintf (stderr, " BRNTAKEN");	  if ( r_flags & IMAGE_REL_PPC_TOCDEFN )	    fprintf (stderr, " TOCDEFN");	  fprintf(stderr, "\n");	}#endif      symndx = rel->r_symndx;      loc = contents + rel->r_vaddr - input_section->vma;      /* FIXME: check bounds on r_type */      howto = ppc_coff_howto_table + r_type;      if (symndx == -1)	{	  h = NULL;	  sym = NULL;	}      else	{	  h = (struct ppc_coff_link_hash_entry *) 	    (obj_coff_sym_hashes (input_bfd)[symndx]);	  if (h != 0) 	    {	      CHECK_EYE(h->eye_catcher);	    }	  sym = syms + symndx;	}      sec = NULL;      val = 0;      /* FIXME: PAIR unsupported in the following code */      if (h == NULL)	{	  if (symndx == -1)	    sec = bfd_abs_section_ptr;	  else	    {	      sec = sections[symndx];	      val = (sec->output_section->vma		     + sec->output_offset		     + sym->n_value		     - sec->vma);	    }	}      else	{	  CHECK_EYE(h->eye_catcher);	  if (h->root.root.type == bfd_link_hash_defined	      || h->root.root.type == bfd_link_hash_defweak)	    {	      sec = h->root.root.u.def.section;	      val = (h->root.root.u.def.value		     + sec->output_section->vma		     + sec->output_offset);	    }	  else	    {	      if (! ((*info->callbacks->undefined_symbol)		     (info, h->root.root.root.string, input_bfd, input_section,		      rel->r_vaddr - input_section->vma)))		return false;	    }	}      rstat = bfd_reloc_ok;            /* Each case must do its own relocation, setting rstat appropriately */      switch (r_type)	{	default:	  fprintf( stderr, 		  "ERROR: during reloc processing -- unsupported reloc %s\n", 		  howto->name);	  bfd_set_error (bfd_error_bad_value);	  abort();	  return false;	case IMAGE_REL_PPC_TOCREL16:	  {	    bfd_vma our_toc_offset;	    int fixit;	    DUMP_RELOC2(howto->name, rel);	    if (toc_section == 0) 	      {		toc_section = bfd_get_section_by_name (bfd_of_toc_owner, 						       TOC_SECTION_NAME);#ifdef TOC_DEBUG		fprintf(stderr,			"BFD of toc owner %p, section addr of %s %p\n",			 bfd_of_toc_owner, TOC_SECTION_NAME, toc_section);#endif		if ( toc_section == NULL ) 		  {		    fprintf(stderr, "No Toc section!\n");		    abort();		  }	      }#if 0	    if ( r_flags & IMAGE_REL_PPC_TOCDEFN )	      {		/* Somehow, we are to assume that the toc has already been		   done for this one, and the offset is the value of		   the symbol? */		fprintf(stderr,			"Symbol value %d\n", val);	      }#endif	    /* 	     *  Amazing bit tricks present. As we may have seen earlier, we	     *  use the 1 bit to tell us whether or not a toc offset has been	     *  allocated. Now that they've all been allocated, we will use	     *  the 1 bit to tell us if we've written this particular toc	     *  entry out.	     */	    fixit = false;	    if (h == 0)	      { /* it is a file local symbol */		int *local_toc_table;		const char *name;		sym = syms + symndx;		name = sym->_n._n_name;		local_toc_table = obj_coff_local_toc_table(input_bfd);		our_toc_offset = local_toc_table[symndx];		if ((our_toc_offset & 1) != 0)		  {		    /* if it has been written out, it is marked with the 		       1 bit. Fix up our offset, but do not write it out		       again.		     */		    our_toc_offset &= ~1;#ifdef TOC_DEBUG		    fprintf(stderr,			    "Not writing out toc_offset of %d for %s\n", our_toc_offset, name);#endif		  }		else		  {		    /* write out the toc entry */		    record_toc(toc_section, our_toc_offset, strdup(name));#ifdef TOC_DEBUG		    fprintf(stderr,			    "Writing out toc_offset toc_section (%p,%p)+%d val %d for %s\n", 			    toc_section,			    toc_section->contents,			    our_toc_offset, 			    val,			    name);#endif		    bfd_put_32(output_bfd,			       val,			       toc_section->contents + our_toc_offset);		    local_toc_table[symndx] |= 1;		    fixit = true;		  }	      }	    else	      {		const char *name = h->root.root.root.string;		our_toc_offset = h->toc_offset;		if ((our_toc_offset & 1) != 0)		  {		    /* if it has been written out, it is marked with the 		       1 bit. Fix up our offset, but do not write it out		       again.		     */		    our_toc_offset &= ~1;#ifdef TOC_DEBUG		    fprintf(stderr,			    "Not writing out toc_offset of %d for %s\n", our_toc_offset, name);#endif		  }		else		  {		    record_toc(toc_section, our_toc_offset, strdup(name));#ifdef TOC_DEBUG		    /* write out the toc entry */		    fprintf(stderr,			    "Writing out toc_offset toc_section (%p,%p)+%d val %d for %s\n", 			    toc_section,			    toc_section->contents,			    our_toc_offset, 			    val,			    name);#endif		    /* write out the toc entry */		    bfd_put_32(output_bfd,			       val,			       toc_section->contents + our_toc_offset);		    h->toc_offset |= 1;		    /* The tricky part is that this is the address that */		    /* needs a .reloc entry for it */		    fixit = true;		  }	      }	    if (fixit && info->base_file) 	      {		/* So if this is non pcrelative, and is referenced		   to a section or a common symbol, then it needs a reloc */		/* relocation to a symbol in a section which		   isn't absolute - we output the address here 		   to a file */		bfd_vma addr =  toc_section->output_section->vma		  + toc_section->output_offset + our_toc_offset;		    		fprintf(stderr,			"  Toc Section reloc candidate\n");		    		if (coff_data(output_bfd)->pe)		  addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;		fwrite (&addr, 1,4, (FILE *) info->base_file);	      }	    /* FIXME: this test is conservative */	    if (our_toc_offset > toc_section->_raw_size)	      {		fprintf(stderr,			"reloc offset is bigger than the toc size!\n");		abort();	      }	    /* Now we know the relocation for this toc reference */	    relocation =  our_toc_offset + TOC_LOAD_ADJUSTMENT;	    rstat = _bfd_relocate_contents (howto,					    input_bfd, 					    relocation, 					    loc);	  }	  break;	case IMAGE_REL_PPC_IFGLUE:	  {	    /* To solve this, we need to know whether or not the symbol */	    /* appearing on the call instruction is a glue function or not. */	    /* A glue function must announce itself via a IMGLUE reloc, and */	    /* the reloc contains the required toc restore instruction */	  	    bfd_vma x;	    const char *my_name;	    DUMP_RELOC2(howto->name, rel);	    if (h != 0)	      {		my_name = h->root.root.root.string;		if (h->symbol_is_glue == 1) 		  {		    x = bfd_get_32(input_bfd, loc);		    bfd_put_32(input_bfd, h->glue_insn, loc);		  }	      }	  }	  break;	case IMAGE_REL_PPC_SECREL:	  /* Unimplemented: codeview debugging information */	  /* For fast access to the header of the section 	     containing the item. */	  break;	case IMAGE_REL_PPC_SECTION:	  /* Unimplemented: codeview debugging information */	  /* Is used to indicate that the value should be relative	     to the beginning of the section that contains the	     symbol */	  break;	case IMAGE_REL_PPC_ABSOLUTE:	  {	    const char *my_name;	    if (h == 0)		my_name = (syms+symndx)->_n._n_name;	    else	      {		my_name = h->root.root.root.string;	      }	    fprintf(stderr, 		    "Warning: unsupported reloc %s <file %s, section %s>\n", 		    howto->name,		    bfd_get_filename(input_bfd),		    input_section->name);	    fprintf(stderr,"sym %d (%s), r_vaddr %d (%x)\n", 		    rel->r_symndx, my_name, rel->r_vaddr, rel->r_vaddr);  	  }	  break;	case IMAGE_REL_PPC_IMGLUE:	  {	    /* There is nothing to do now. This reloc was noted in the first	       pass over the relocs, and the glue instruction extracted */	    const char *my_name;	    if (h->symbol_is_glue == 1) 	      break;	    my_name = h->root.root.root.string;	    fprintf(stderr, 		    "Warning: previously missed IMGLUE reloc %s <file %s, section %s>\n", 		    howto->name,		    bfd_get_filename(input_bfd),		    input_section->name);	    break;	  }	  break;	case IMAGE_REL_PPC_ADDR32NB:	  {	    struct coff_link_hash_entry *myh = 0;	    const char *name = 0;	    DUMP_RELOC2(howto->name, rel);	    if (h == 0)	      { /* it is a file local symbol */		sym = syms + symndx;		name = sym->_n._n_name;	      }	    else	      {		char *target = 0;		name = h->root.root.root.string;		if (strcmp(".idata$2", name) == 0)		  target = "__idata2_magic__";		else if (strcmp(".idata$4", name) == 0)		  target = "__idata4_magic__";		else if (strcmp(".idata$5", name) == 0)		  target = "__idata5_magic__";		else		  abort();		myh = 0;		myh = coff_link_hash_lookup (coff_hash_table (info),					     target,					     false, false, true);		if (myh == 0) 		  {		    fprintf(stderr, "Missing idata magic cookies, this cannot work anyway...\n");		    abort();		  }		val = myh->root.u.def.value + 		  sec->output_section->vma + sec->output_offset;		if (first_thunk_address == 0)		  {		    int idata5offset;		    myh = coff_link_hash_lookup (coff_hash_table (info),						 "__idata5_magic__",						 false, false, true);		    first_thunk_address = myh->root.u.def.value + 		      sec->output_section->vma + 		      sec->output_offset - 			pe_data(output_bfd)->pe_opthdr.ImageBase;		    idata5offset = myh->root.u.def.value;		    myh = coff_link_hash_lookup (coff_hash_table (info),						 "__idata6_magic__",						 false, false, true);		    thunk_size = myh->root.u.def.value - idata5offset;		    myh = coff_link_hash_lookup (coff_hash_table (info),						 "__idata4_magic__",						 false, false, true);		    import_table_size = myh->root.u.def.value;		  }	      }	    rstat = _bfd_relocate_contents (howto,		      	      input_bfd, 			      val - 			      pe_data(output_bfd)->pe_opthdr.ImageBase,			      loc);	  }	  break;	case IMAGE_REL_PPC_ADDR16:	case IMAGE_REL_PPC_REL24:	case IMAGE_REL_PPC_ADDR24:	case IMAGE_REL_PPC_ADDR32:	  DUMP_RELOC2(howto->name, rel);	  rstat = _bfd_relocate_contents (howto,					  input_bfd, 					  val, 					  loc);	  break;	}      if ( info->base_file )	{	  /* So if this is non pcrelative, and is referenced	     to a section or a common symbol, then it needs a reloc */	  if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto))	    {	      /* relocation to a symbol in a section which		 isn't absolute - we output the address here 		 to a file */	      bfd_vma addr = rel->r_vaddr 		- input_section->vma 		+ input_section->output_offset 		  + input_section->output_section->vma;	      if (coff_data(output_bfd)->pe)		{		  addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;		  fprintf(stderr,			  " adjusted down to %d", addr);		}	      fprintf(stderr, "\n");	      fwrite (&addr, 1,4, (FILE *) info->base_file);	    }	}      switch (rstat)	{	default:	  abort ();	case bfd_reloc_ok:	  break;	case bfd_reloc_overflow:	  {	    const char *name;	    char buf[SYMNMLEN + 1];	    if (symndx == -1)	      name = "*ABS*";	    else if (h != NULL)	      name = h->root.root.root.string;	    else if (sym == NULL)	      name = "*unknown*";	    else if (sym->_n._n_n._n_zeroes == 0		     && sym->_n._n_n._n_offset != 0)	      name = obj_coff_strings (input_bfd) + sym->_n._n_n._n_offset;	    else	      {		strncpy (buf, sym->_n._n_name, SYMNMLEN);		buf[SYMNMLEN] = '\0';		name = buf;	      }#if 0	    else	      {		name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);		if (name == NULL)		  return false;	      }#endif	    if (! ((*info->callbacks->reloc_overflow)		   (info, name, howto->name, 		    (bfd_vma) 0, input_bfd,		    input_section, rel->r_vaddr - input_section->vma)))	      return false;	  }	}    }       return true;}