bfd_set_error (bfd_error_bad_value);
elf32_hppa_size_stubs (stub_bfd, output_bfd, link_info)     bfd *stub_bfd;     bfd *output_bfd;     struct bfd_link_info *link_info;{  bfd *input_bfd;  asection *section, *stub_sec = 0;  Elf_Internal_Shdr *symtab_hdr;  Elf_Internal_Sym *local_syms, *isym, **all_local_syms;  Elf32_External_Sym *ext_syms, *esym;  unsigned int i, index, bfd_count = 0;  struct elf32_hppa_stub_hash_table *stub_hash_table = 0;  struct elf32_hppa_args_hash_table *args_hash_table = 0;  /* Create and initialize the stub hash table.  */  stub_hash_table = ((struct elf32_hppa_stub_hash_table *)		     malloc (sizeof (struct elf32_hppa_stub_hash_table)));  if (!stub_hash_table)    {      bfd_set_error (bfd_error_no_memory);      goto error_return;    }  if (!elf32_hppa_stub_hash_table_init (stub_hash_table, stub_bfd,					elf32_hppa_stub_hash_newfunc))    goto error_return;  /* Likewise for the argument location hash table.  */  args_hash_table = ((struct elf32_hppa_args_hash_table *)		     malloc (sizeof (struct elf32_hppa_args_hash_table)));  if (!args_hash_table)    {      bfd_set_error (bfd_error_no_memory);      goto error_return;    }  if (!elf32_hppa_args_hash_table_init (args_hash_table,					elf32_hppa_args_hash_newfunc))    goto error_return;  /* Attach the hash tables to the main hash table.  */  elf32_hppa_hash_table(link_info)->stub_hash_table = stub_hash_table;  elf32_hppa_hash_table(link_info)->args_hash_table = args_hash_table;  /* Count the number of input BFDs.  */  for (input_bfd = link_info->input_bfds;       input_bfd != NULL;       input_bfd = input_bfd->link_next)     bfd_count++;  /* We want to read in symbol extension records only once.  To do this     we need to read in the local symbols in parallel and save them for     later use; so hold pointers to the local symbols in an array.  */  all_local_syms    = (Elf_Internal_Sym **) malloc (sizeof (Elf_Internal_Sym *) * bfd_count);  if (all_local_syms == NULL)    {      bfd_set_error (bfd_error_no_memory);      goto error_return;    }  memset (all_local_syms, 0, sizeof (Elf_Internal_Sym *) * bfd_count);  /* Walk over all the input BFDs adding entries to the args hash table     for all the external functions.  */  for (input_bfd = link_info->input_bfds, index = 0;       input_bfd != NULL;       input_bfd = input_bfd->link_next, index++)    {      /* We'll need the symbol table in a second.  */      symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;      if (symtab_hdr->sh_info == 0)	continue;      /* We need an array of the local symbols attached to the input bfd.	 Unfortunately, we're going to have to read & swap them in.  */      local_syms	= (Elf_Internal_Sym *)malloc (symtab_hdr->sh_info				      * sizeof (Elf_Internal_Sym));      if (local_syms == NULL)	{	  bfd_set_error (bfd_error_no_memory);	  for (i = 0; i < bfd_count; i++)	    if (all_local_syms[i])	      free (all_local_syms[i]);	  free (all_local_syms);	  goto error_return;	}      all_local_syms[index] = local_syms;      ext_syms	= (Elf32_External_Sym *)malloc (symtab_hdr->sh_info					* sizeof (Elf32_External_Sym));      if (ext_syms == NULL)	{	  bfd_set_error (bfd_error_no_memory);	  for (i = 0; i < bfd_count; i++)	    if (all_local_syms[i])	      free (all_local_syms[i]);	  free (all_local_syms);	  goto error_return;	}      if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0	  || bfd_read (ext_syms, 1,		       (symtab_hdr->sh_info			* sizeof (Elf32_External_Sym)), input_bfd)	  != (symtab_hdr->sh_info * sizeof (Elf32_External_Sym)))	{	  for (i = 0; i < bfd_count; i++)	    if (all_local_syms[i])	      free (all_local_syms[i]);	  free (all_local_syms);	  free (ext_syms);	  goto error_return;	}      /* Swap the local symbols in.  */      isym = local_syms;      esym = ext_syms;      for (i = 0; i < symtab_hdr->sh_info; i++, esym++, isym++)	 bfd_elf32_swap_symbol_in (input_bfd, esym, isym);      /* Now we can free the external symbols.  */      free (ext_syms);      if (elf32_hppa_read_symext_info (input_bfd, symtab_hdr, args_hash_table,				       local_syms) == false)	{	  for (i = 0; i < bfd_count; i++)	    if (all_local_syms[i])	      free (all_local_syms[i]);	  free (all_local_syms);	  goto error_return;	}    }  /* Magic as we know the stub bfd only has one section.  */  stub_sec = stub_bfd->sections;  /* If generating a relocateable output file, then we don't     have to examine the relocs.  */  if (link_info->relocateable)    {      for (i = 0; i < bfd_count; i++)	if (all_local_syms[i])	  free (all_local_syms[i]);      free (all_local_syms);      return true;    }  /* Now that we have argument location information for all the global     functions we can start looking for stubs.  */  for (input_bfd = link_info->input_bfds, index = 0;       input_bfd != NULL;       input_bfd = input_bfd->link_next, index++)    {      /* We'll need the symbol table in a second.  */      symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;      if (symtab_hdr->sh_info == 0)	continue;      local_syms = all_local_syms[index];      /* Walk over each section attached to the input bfd.  */      for (section = input_bfd->sections;	   section != NULL;	   section = section->next)	{	  Elf_Internal_Shdr *input_rel_hdr;	  Elf32_External_Rela *external_relocs, *erelaend, *erela;	  Elf_Internal_Rela *internal_relocs, *irelaend, *irela;	  /* If there aren't any relocs, then there's nothing to do.  */	  if ((section->flags & SEC_RELOC) == 0	      || section->reloc_count == 0)	    continue;	  /* Allocate space for the external relocations.  */	  external_relocs	    = (Elf32_External_Rela *) malloc (section->reloc_count * sizeof (Elf32_External_Rela));	  if (external_relocs == NULL)	    {	      bfd_set_error (bfd_error_no_memory);	      for (i = 0; i < bfd_count; i++)		if (all_local_syms[i])		  free (all_local_syms[i]);	      free (all_local_syms);	      goto error_return;	    }	  /* Likewise for the internal relocations.  */	  internal_relocs	    = (Elf_Internal_Rela *) malloc (section->reloc_count * sizeof (Elf_Internal_Rela));	  if (internal_relocs == NULL)	    {	      bfd_set_error (bfd_error_no_memory);	      free (external_relocs);	      for (i = 0; i < bfd_count; i++)		if (all_local_syms[i])		  free (all_local_syms[i]);	      free (all_local_syms);	      goto error_return;	    }	  /* Read in the external relocs.  */	  input_rel_hdr = &elf_section_data (section)->rel_hdr;	  if (bfd_seek (input_bfd, input_rel_hdr->sh_offset, SEEK_SET) != 0	      || bfd_read (external_relocs, 1, input_rel_hdr->sh_size,			   input_bfd) != input_rel_hdr->sh_size)	    {	      free (external_relocs);	      free (internal_relocs);	      for (i = 0; i < bfd_count; i++)		if (all_local_syms[i])		  free (all_local_syms[i]);	      free (all_local_syms);	      goto error_return;	    }	  /* Swap in the relocs.  */	  erela = external_relocs;	  erelaend = erela + section->reloc_count;	  irela = internal_relocs;	  for (; erela < erelaend; erela++, irela++)	    bfd_elf32_swap_reloca_in (input_bfd, erela, irela);	  /* We're done with the external relocs, free them.  */	  free (external_relocs);	  /* Now examine each relocation.  */	  irela = internal_relocs;	  irelaend = irela + section->reloc_count;	  for (; irela < irelaend; irela++)	    {	      long r_type, callee_args, caller_args, size_of_stub;	      unsigned long r_index;	      struct elf_link_hash_entry *hash;	      struct elf32_hppa_stub_hash_entry *stub_hash;	      struct elf32_hppa_args_hash_entry *args_hash;	      Elf_Internal_Sym *sym;	      asection *sym_sec;	      const char *sym_name;	      symvalue sym_value;	      bfd_vma location, destination;	      char *new_name = NULL;	      r_type = ELF32_R_TYPE (irela->r_info);	      r_index = ELF32_R_SYM (irela->r_info);	      if (r_type < 0 || r_type >= (int) R_PARISC_UNIMPLEMENTED)		{		  bfd_set_error (bfd_error_bad_value);		  free (internal_relocs);		  for (i = 0; i < bfd_count; i++)		    if (all_local_syms[i])		      free (all_local_syms[i]);		  free (all_local_syms);		  goto error_return;		}	      /* Only look for stubs on call instructions or plabel		 references.  */	      if (r_type != R_PARISC_PCREL17F		  && r_type != R_PARISC_PLABEL32		  && r_type != R_PARISC_PLABEL21L		  && r_type != R_PARISC_PLABEL14R)		continue;	      /* Now determine the call target, its name, value, section		 and argument relocation bits.  */	      hash = NULL;	      sym = NULL;	      sym_sec = NULL;	      if (r_index < symtab_hdr->sh_info)		{		  /* It's a local symbol.  */		  Elf_Internal_Shdr *hdr;		  sym = local_syms + r_index;		  hdr = elf_elfsections (input_bfd)[sym->st_shndx];		  sym_sec = hdr->bfd_section;		  sym_name = bfd_elf_string_from_elf_section (input_bfd,							      symtab_hdr->sh_link,							      sym->st_name);		  sym_value = (ELF_ST_TYPE (sym->st_info) == STT_SECTION			       ? 0 : sym->st_value);		  destination = (sym_value				 + sym_sec->output_offset				 + sym_sec->output_section->vma);		  /* Tack on an ID so we can uniquely identify this local		     symbol in the stub or arg info hash tables.  */		  new_name = malloc (strlen (sym_name) + 10);		  if (new_name == 0)		    {		      bfd_set_error (bfd_error_bad_value);		      free (internal_relocs);		      for (i = 0; i < bfd_count; i++)			if (all_local_syms[i])			  free (all_local_syms[i]);		      free (all_local_syms);		      goto error_return;		    }		  sprintf (new_name, "%s_%08x", sym_name, (int)sym_sec);		  sym_name = new_name;		}	      else		{		  /* It's an external symbol.  */		  long index;		  index = r_index - symtab_hdr->sh_info;		  hash = elf_sym_hashes (input_bfd)[index];		  if (hash->root.type == bfd_link_hash_defined		      || hash->root.type == bfd_link_hash_defweak)		    {		      sym_sec = hash->root.u.def.section;		      sym_name = hash->root.root.string;		      sym_value = hash->root.u.def.value;		      destination = (sym_value				     + sym_sec->output_offset				     + sym_sec->output_section->vma);		    }		  else		    {		      bfd_set_error (bfd_error_bad_value);		      free (internal_relocs);		      for (i = 0; i < bfd_count; i++)			if (all_local_syms[i])			  free (all_local_syms[i]);		      free (all_local_syms);		      goto error_return;		    }		}	      args_hash = elf32_hppa_args_hash_lookup (args_hash_table,						       sym_name, false, false);	      /* Get both caller and callee argument information.  */	      if (args_hash == NULL)		callee_args = 0;	      else		callee_args = args_hash->arg_bits;	      /* For calls get the caller's bits from the addend of		 the call relocation.  For PLABELS the caller's bits		 are assumed to have all args & return values in general		 registers (0x155).  */	      if (r_type == R_PARISC_PCREL17F)		caller_args = HPPA_R_ARG_RELOC (irela->r_addend);	      else		caller_args = 0x155;	      /* Now determine where the call point is.  */	      location = (section->output_offset			  + section->output_section->vma			  + irela->r_offset);	      /* We only care about the destination for PCREL function		 calls (eg. we don't care for PLABELS).  */	      if (r_type != R_PARISC_PCREL17F)		location = destination;	      /* Determine what (if any) linker stub is needed and its		 size (in bytes).  */	      size_of_stub = elf32_hppa_size_of_stub (callee_args,						      caller_args,						      location,						      destination,						      sym_name);	      if (size_of_stub != 0)		{		  char *stub_name;		  unsigned int len;		  /* Get the name of this stub.  */		  len = strlen (sym_name);		  len += 23;		  stub_name = malloc (len);		  if (!stub_name)		    {		      bfd_set_error (bfd_error_no_memory);		      /* Because sym_name was mallocd above for local			 symbols.  */		      if (r_index < symtab_hdr->sh_info)			free (new_name);		      free (internal_relocs);		      for (i = 0; i < bfd_count; i++)			if (all_local_syms[i])			  free (all_local_syms[i]);		      free (all_local_syms);		      goto error_return;		    }		  elf32_hppa_name_of_stub (caller_args, callee_args,					   location, destination, stub_name);		  strcat (stub_name + 22, sym_name);		  /* Because sym_name was malloced above for local symbols.  */		  if (r_index < symtab_hdr->sh_info)		    free (new_name);		  stub_hash		    = elf32_hppa_stub_hash_lookup (stub_hash_table, stub_name,						   false, false);		  if (stub_hash != NULL)		    {		      /* The proper stub has already been created, nothing			 else to do.  */		      free (stub_name);		    }		  else		    {		      bfd_set_section_size (stub_bfd, stub_sec,					    (bfd_section_size (stub_bfd,							       stub_sec)					     + size_of_stub));		      /* Enter this entry into the linker stub hash table.  */		      stub_hash			= elf32_hppa_stub_hash_lookup (stub_hash_table,						       stub_name, true, true);		      if (stub_hash == NULL)			{			  bfd_set_error (bfd_error_no_memory);			  free (stub_name);			  free (internal_relocs);			  for (i = 0; i < bfd_count; i++)			    if (all_local_syms[i])			      free (all_local_syms[i]);			  free (all_local_syms);			  goto error_return;			}		      /* We'll need these to determine the address that the			 stub will branch to.  */		      stub_hash->target_value = sym_value;		      stub_hash->target_section = sym_sec;		    }		  free (stub_name);		}	    }	  /* We're done with the internal relocs, free them.  */	  free (internal_relocs);	}    }  /* We're done with the local symbols, free them.  */  for (i = 0; i < bfd_count; i++)    if (all_local_syms[i])      free (all_local_syms[i]);  free (all_local_syms);  return true;error_return:  /* Return gracefully, avoiding dangling references to the hash tables.  */  if (stub_hash_table)    {      elf32_hppa_hash_table(link_info)->stub_hash_table = NULL;      free (stub_hash_table);    }  if (args_hash_table)    {      elf32_hppa_hash_table(link_info)->args_hash_table = NULL;      free (args_hash_table);    }  /* Set the size of the stub section to zero since we're never going     to create them.   Avoids losing when we try to get its contents     too.  */  bfd_set_section_size (stub_bfd, stub_sec, 0);  return false;}