+ free (stub_name);
+ }
+
+ return hsh;
+}
+
+/* Add a new stub entry to the stub hash. Not all fields of the new
+ stub entry are initialised. */
+static struct elf32_nios2_stub_hash_entry *
+nios2_add_stub (const char *stub_name,
+ asection *section,
+ struct elf32_nios2_link_hash_table *htab,
+ enum elf32_nios2_stub_type stub_type)
+{
+ asection *link_sec;
+ asection *stub_sec;
+ asection **secptr, **linkptr;
+ struct elf32_nios2_stub_hash_entry *hsh;
+ bfd_boolean afterp;
+
+ if (stub_type == nios2_stub_call26_before)
+ {
+ link_sec = htab->stub_group[section->id].first_sec;
+ secptr = &(htab->stub_group[section->id].first_stub_sec);
+ linkptr = &(htab->stub_group[link_sec->id].first_stub_sec);
+ afterp = FALSE;
+ }
+ else
+ {
+ link_sec = htab->stub_group[section->id].last_sec;
+ secptr = &(htab->stub_group[section->id].last_stub_sec);
+ linkptr = &(htab->stub_group[link_sec->id].last_stub_sec);
+ afterp = TRUE;
+ }
+ stub_sec = *secptr;
+ if (stub_sec == NULL)
+ {
+ stub_sec = *linkptr;
+ if (stub_sec == NULL)
+ {
+ size_t namelen;
+ bfd_size_type len;
+ char *s_name;
+
+ namelen = strlen (link_sec->name);
+ len = namelen + sizeof (STUB_SUFFIX);
+ s_name = bfd_alloc (htab->stub_bfd, len);
+ if (s_name == NULL)
+ return NULL;
+
+ memcpy (s_name, link_sec->name, namelen);
+ memcpy (s_name + namelen, STUB_SUFFIX, sizeof (STUB_SUFFIX));
+
+ stub_sec = (*htab->add_stub_section) (s_name, link_sec, afterp);
+ if (stub_sec == NULL)
+ return NULL;
+ *linkptr = stub_sec;
+ }
+ *secptr = stub_sec;
+ }
+
+ /* Enter this entry into the linker stub hash table. */
+ hsh = nios2_stub_hash_lookup (&htab->bstab, stub_name,
+ TRUE, FALSE);
+ if (hsh == NULL)
+ {
+ (*_bfd_error_handler) (_("%B: cannot create stub entry %s"),
+ section->owner,
+ stub_name);
+ return NULL;
+ }
+
+ hsh->stub_sec = stub_sec;
+ hsh->stub_offset = 0;
+ hsh->id_sec = link_sec;
+ return hsh;
+}
+
+/* Set up various things so that we can make a list of input sections
+ for each output section included in the link. Returns -1 on error,
+ 0 when no stubs will be needed, and 1 on success. */
+int
+nios2_elf32_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info)
+{
+ bfd *input_bfd;
+ unsigned int bfd_count;
+ unsigned int top_id, top_index;
+ asection *section;
+ asection **input_list, **list;
+ bfd_size_type amt;
+ struct elf32_nios2_link_hash_table *htab = elf32_nios2_hash_table (info);
+
+ /* Count the number of input BFDs and find the top input section id. */
+ for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next)
+ {
+ bfd_count += 1;
+ for (section = input_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ if (top_id < section->id)
+ top_id = section->id;
+ }
+ }
+
+ htab->bfd_count = bfd_count;
+
+ amt = sizeof (struct map_stub) * (top_id + 1);
+ htab->stub_group = bfd_zmalloc (amt);
+ if (htab->stub_group == NULL)
+ return -1;
+
+ /* We can't use output_bfd->section_count here to find the top output
+ section index as some sections may have been removed, and
+ strip_excluded_output_sections doesn't renumber the indices. */
+ for (section = output_bfd->sections, top_index = 0;
+ section != NULL;
+ section = section->next)
+ {
+ if (top_index < section->index)
+ top_index = section->index;
+ }
+
+ htab->top_index = top_index;
+ amt = sizeof (asection *) * (top_index + 1);
+ input_list = bfd_malloc (amt);
+ htab->input_list = input_list;
+ if (input_list == NULL)
+ return -1;
+
+ /* For sections we aren't interested in, mark their entries with a
+ value we can check later. */
+ list = input_list + top_index;
+ do
+ *list = bfd_abs_section_ptr;
+ while (list-- != input_list);
+
+ for (section = output_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ /* FIXME: This is a bit of hack. Currently our .ctors and .dtors
+ * have PC relative relocs in them but no code flag set. */
+ if (((section->flags & SEC_CODE) != 0) ||
+ strcmp(".ctors", section->name) ||
+ strcmp(".dtors", section->name))
+ input_list[section->index] = NULL;
+ }
+
+ return 1;
+}
+
+/* The linker repeatedly calls this function for each input section,
+ in the order that input sections are linked into output sections.
+ Build lists of input sections to determine groupings between which
+ we may insert linker stubs. */
+void
+nios2_elf32_next_input_section (struct bfd_link_info *info, asection *isec)
+{
+ struct elf32_nios2_link_hash_table *htab = elf32_nios2_hash_table (info);
+
+ if (isec->output_section->index <= htab->top_index)
+ {
+ asection **list = htab->input_list + isec->output_section->index;
+ if (*list != bfd_abs_section_ptr)
+ {
+ /* Steal the last_sec pointer for our list.
+ This happens to make the list in reverse order,
+ which is what we want. */
+ htab->stub_group[isec->id].last_sec = *list;
+ *list = isec;
+ }
+ }
+}
+
+/* Segment mask for CALL26 relocation relaxation. */
+#define CALL26_SEGMENT(x) ((x) & 0xf0000000)
+
+/* Fudge factor for approximate maximum size of all stubs that might
+ be inserted by the linker. This does not actually limit the number
+ of stubs that might be inserted, and only affects strategy for grouping
+ and placement of stubs. Perhaps this should be computed based on number
+ of relocations seen, or be specifiable on the command line. */
+#define MAX_STUB_SECTION_SIZE 0xffff
+
+/* See whether we can group stub sections together. Grouping stub
+ sections may result in fewer stubs. More importantly, we need to
+ put all .init* and .fini* stubs at the end of the .init or
+ .fini output sections respectively, because glibc splits the
+ _init and _fini functions into multiple parts. Putting a stub in
+ the middle of a function is not a good idea.
+ Rather than computing groups of a maximum fixed size, for Nios II
+ CALL26 relaxation it makes more sense to compute the groups based on
+ sections that fit within a 256MB address segment. Also do not allow
+ a group to span more than one output section, since different output
+ sections might correspond to different memory banks on a bare-metal
+ target, etc. */
+static void
+group_sections (struct elf32_nios2_link_hash_table *htab)
+{
+ asection **list = htab->input_list + htab->top_index;
+ do
+ {
+ /* The list is in reverse order so we'll search backwards looking
+ for the first section that begins in the same memory segment,
+ marking sections along the way to point at the tail for this
+ group. */
+ asection *tail = *list;
+ if (tail == bfd_abs_section_ptr)
+ continue;
+ while (tail != NULL)
+ {
+ bfd_vma start = tail->output_section->vma + tail->output_offset;
+ bfd_vma end = start + tail->size;
+ bfd_vma segment = CALL26_SEGMENT (end);
+ asection *prev;
+
+ if (segment != CALL26_SEGMENT (start)
+ || segment != CALL26_SEGMENT (end + MAX_STUB_SECTION_SIZE))
+ /* This section spans more than one memory segment, or is
+ close enough to the end of the segment that adding stub
+ sections before it might cause it to move so that it
+ spans memory segments, or that stubs added at the end of
+ this group might overflow into the next memory segment.
+ Put it in a group by itself to localize the effects. */
+ {
+ prev = htab->stub_group[tail->id].last_sec;
+ htab->stub_group[tail->id].last_sec = tail;
+ htab->stub_group[tail->id].first_sec = tail;
+ }
+ else
+ /* Collect more sections for this group. */
+ {
+ asection *curr, *first;
+ for (curr = tail; ; curr = prev)
+ {
+ prev = htab->stub_group[curr->id].last_sec;
+ if (!prev
+ || tail->output_section != prev->output_section
+ || (CALL26_SEGMENT (prev->output_section->vma
+ + prev->output_offset)
+ != segment))
+ break;
+ }
+ first = curr;
+ for (curr = tail; ; curr = prev)
+ {
+ prev = htab->stub_group[curr->id].last_sec;
+ htab->stub_group[curr->id].last_sec = tail;
+ htab->stub_group[curr->id].first_sec = first;
+ if (curr == first)
+ break;
+ }
+ }
+
+ /* Reset tail for the next group. */
+ tail = prev;
+ }
+ }
+ while (list-- != htab->input_list);
+ free (htab->input_list);
+}
+
+/* Determine the type of stub needed, if any, for a call. */
+static enum elf32_nios2_stub_type
+nios2_type_of_stub (asection *input_sec,
+ const Elf_Internal_Rela *rel,
+ struct elf32_nios2_link_hash_entry *hh,
+ struct elf32_nios2_link_hash_table *htab,
+ bfd_vma destination,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED)
+{
+ bfd_vma location, segment, start, end;
+ asection *s0, *s1, *s;
+
+ if (hh != NULL &&
+ !(hh->root.root.type == bfd_link_hash_defined
+ || hh->root.root.type == bfd_link_hash_defweak))
+ return nios2_stub_none;
+
+ /* Determine where the call point is. */
+ location = (input_sec->output_section->vma
+ + input_sec->output_offset + rel->r_offset);
+ segment = CALL26_SEGMENT (location);
+
+ /* Nios II CALL and JMPI instructions can transfer control to addresses
+ within the same 256MB segment as the PC. */
+ if (segment == CALL26_SEGMENT (destination))
+ return nios2_stub_none;
+
+ /* Find the start and end addresses of the stub group. Also account for
+ any already-created stub sections for this group. Note that for stubs
+ in the end section, only the first instruction of the last stub
+ (12 bytes long) needs to be within range. */
+ s0 = htab->stub_group[input_sec->id].first_sec;
+ s = htab->stub_group[s0->id].first_stub_sec;
+ if (s != NULL && s->size > 0)
+ start = s->output_section->vma + s->output_offset;
+ else
+ start = s0->output_section->vma + s0->output_offset;
+
+ s1 = htab->stub_group[input_sec->id].last_sec;
+ s = htab->stub_group[s1->id].last_stub_sec;
+ if (s != NULL && s->size > 0)
+ end = s->output_section->vma + s->output_offset + s->size - 8;
+ else
+ end = s1->output_section->vma + s1->output_offset + s1->size;
+
+ BFD_ASSERT (start < end);
+ BFD_ASSERT (start <= location);
+ BFD_ASSERT (location < end);
+
+ /* Put stubs at the end of the group unless that is not a valid
+ location and the beginning of the group is. It might be that
+ neither the beginning nor end works if we have an input section
+ so large that it spans multiple segment boundaries. In that
+ case, punt; the end result will be a relocation overflow error no
+ matter what we do here.
+
+ Note that adding stubs pushes up the addresses of all subsequent
+ sections, so that stubs allocated on one pass through the
+ relaxation loop may not be valid on the next pass. (E.g., we may
+ allocate a stub at the beginning of the section on one pass and
+ find that the call site has been bumped into the next memory
+ segment on the next pass.) The important thing to note is that
+ we never try to reclaim the space allocated to such unused stubs,
+ so code size and section addresses can only increase with each
+ iteration. Accounting for the start and end addresses of the
+ already-created stub sections ensures that when the algorithm
+ converges, it converges accurately, with the entire appropriate
+ stub section accessible from the call site and not just the
+ address at the start or end of the stub group proper. */
+
+ if (segment == CALL26_SEGMENT (end))
+ return nios2_stub_call26_after;
+ else if (segment == CALL26_SEGMENT (start))
+ return nios2_stub_call26_before;
+ else
+ /* Perhaps this should be a dedicated error code. */
+ return nios2_stub_none;
+}
+
+static bfd_boolean
+nios2_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg ATTRIBUTE_UNUSED)
+{
+ struct elf32_nios2_stub_hash_entry *hsh
+ = (struct elf32_nios2_stub_hash_entry *) gen_entry;
+ asection *stub_sec = hsh->stub_sec;
+ bfd_vma sym_value;
+
+ /* Make a note of the offset within the stubs for this entry. */
+ hsh->stub_offset = stub_sec->size;
+
+ switch (hsh->stub_type)
+ {
+ case nios2_stub_call26_before:
+ case nios2_stub_call26_after:
+ /* A call26 stub looks like:
+ orhi at, %hiadj(dest)
+ addi at, at, %lo(dest)
+ jmp at
+ Note that call/jmpi instructions can't be used in PIC code
+ so there is no reason for the stub to be PIC, either. */
+ sym_value = (hsh->target_value
+ + hsh->target_section->output_offset
+ + hsh->target_section->output_section->vma
+ + hsh->addend);
+
+ nios2_elf32_install_data (stub_sec, nios2_call26_stub_entry,
+ hsh->stub_offset, 3);
+ nios2_elf32_install_imm16 (stub_sec, hsh->stub_offset,
+ hiadj (sym_value));
+ nios2_elf32_install_imm16 (stub_sec, hsh->stub_offset + 4,
+ (sym_value & 0xffff));
+ stub_sec->size += 12;
+ break;
+ default:
+ BFD_FAIL ();
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* As above, but don't actually build the stub. Just bump offset so
+ we know stub section sizes. */
+static bfd_boolean
+nios2_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg ATTRIBUTE_UNUSED)
+{
+ struct elf32_nios2_stub_hash_entry *hsh
+ = (struct elf32_nios2_stub_hash_entry *) gen_entry;
+
+ switch (hsh->stub_type)
+ {
+ case nios2_stub_call26_before:
+ case nios2_stub_call26_after:
+ hsh->stub_sec->size += 12;
+ break;
+ default:
+ BFD_FAIL ();
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* Read in all local syms for all input bfds.
+ Returns -1 on error, 0 otherwise. */
+
+static int
+get_local_syms (bfd *output_bfd ATTRIBUTE_UNUSED, bfd *input_bfd,
+ struct bfd_link_info *info)
+{
+ unsigned int bfd_indx;
+ Elf_Internal_Sym *local_syms, **all_local_syms;
+ struct elf32_nios2_link_hash_table *htab = elf32_nios2_hash_table (info);
+
+ /* 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. */
+ bfd_size_type amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count;
+ all_local_syms = bfd_zmalloc (amt);
+ htab->all_local_syms = all_local_syms;
+ if (all_local_syms == NULL)
+ return -1;
+
+ /* Walk over all the input BFDs, swapping in local symbols. */
+ for (bfd_indx = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next, bfd_indx++)
+ {
+ Elf_Internal_Shdr *symtab_hdr;
+
+ /* 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. */
+ local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (local_syms == NULL)
+ {
+ local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ /* Cache them for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) local_syms;
+ }
+ if (local_syms == NULL)
+ return -1;
+
+ all_local_syms[bfd_indx] = local_syms;
+ }
+
+ return 0;
+}
+
+/* Determine and set the size of the stub section for a final link. */
+bfd_boolean
+nios2_elf32_size_stubs (bfd *output_bfd, bfd *stub_bfd,
+ struct bfd_link_info *info,
+ asection *(*add_stub_section) (const char *,
+ asection *, bfd_boolean),
+ void (*layout_sections_again) (void))
+{
+ bfd_boolean stub_changed = FALSE;
+ struct elf32_nios2_link_hash_table *htab = elf32_nios2_hash_table (info);
+
+ /* Stash our params away. */
+ htab->stub_bfd = stub_bfd;
+ htab->add_stub_section = add_stub_section;
+ htab->layout_sections_again = layout_sections_again;
+
+ /* FIXME: We only compute the section groups once. This could cause
+ problems if adding a large stub section causes following sections,
+ or parts of them, to move into another segment. However, this seems
+ to be consistent with the way other back ends handle this.... */
+ group_sections (htab);
+
+ if (get_local_syms (output_bfd, info->input_bfds, info))
+ {
+ if (htab->all_local_syms)
+ goto error_ret_free_local;
+ return FALSE;
+ }
+
+ while (1)
+ {
+ bfd *input_bfd;
+ unsigned int bfd_indx;
+ asection *stub_sec;
+
+ for (input_bfd = info->input_bfds, bfd_indx = 0;
+ input_bfd != NULL;
+ input_bfd = input_bfd->link.next, bfd_indx++)
+ {
+ Elf_Internal_Shdr *symtab_hdr;
+ asection *section;
+ Elf_Internal_Sym *local_syms;
+
+ /* 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 = htab->all_local_syms[bfd_indx];
+
+ /* Walk over each section attached to the input bfd. */
+ for (section = input_bfd->sections;
+ section != NULL;
+ section = section->next)
+ {
+ Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
+
+ /* If there aren't any relocs, then there's nothing more
+ to do. */
+ if ((section->flags & SEC_RELOC) == 0
+ || section->reloc_count == 0)
+ continue;
+
+ /* If this section is a link-once section that will be
+ discarded, then don't create any stubs. */
+ if (section->output_section == NULL
+ || section->output_section->owner != output_bfd)
+ continue;
+
+ /* Get the relocs. */
+ internal_relocs
+ = _bfd_elf_link_read_relocs (input_bfd, section, NULL, NULL,
+ info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_ret_free_local;
+
+ /* Now examine each relocation. */
+ irela = internal_relocs;
+ irelaend = irela + section->reloc_count;
+ for (; irela < irelaend; irela++)
+ {
+ unsigned int r_type, r_indx;
+ enum elf32_nios2_stub_type stub_type;
+ struct elf32_nios2_stub_hash_entry *hsh;
+ asection *sym_sec;
+ bfd_vma sym_value;
+ bfd_vma destination;
+ struct elf32_nios2_link_hash_entry *hh;
+ char *stub_name;
+ const asection *id_sec;
+
+ r_type = ELF32_R_TYPE (irela->r_info);
+ r_indx = ELF32_R_SYM (irela->r_info);
+
+ if (r_type >= (unsigned int) R_NIOS2_ILLEGAL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ error_ret_free_internal:
+ if (elf_section_data (section)->relocs == NULL)
+ free (internal_relocs);
+ goto error_ret_free_local;
+ }
+
+ /* Only look for stubs on CALL and JMPI instructions. */
+ if (r_type != (unsigned int) R_NIOS2_CALL26)
+ continue;
+
+ /* Now determine the call target, its name, value,
+ section. */
+ sym_sec = NULL;
+ sym_value = 0;
+ destination = 0;
+ hh = NULL;
+ if (r_indx < symtab_hdr->sh_info)
+ {
+ /* It's a local symbol. */
+ Elf_Internal_Sym *sym;
+ Elf_Internal_Shdr *hdr;
+ unsigned int shndx;
+
+ sym = local_syms + r_indx;
+ if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
+ sym_value = sym->st_value;
+ shndx = sym->st_shndx;
+ if (shndx < elf_numsections (input_bfd))
+ {
+ hdr = elf_elfsections (input_bfd)[shndx];
+ sym_sec = hdr->bfd_section;
+ destination = (sym_value + irela->r_addend
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ }
+ }
+ else
+ {
+ /* It's an external symbol. */
+ int e_indx;
+
+ e_indx = r_indx - symtab_hdr->sh_info;
+ hh = ((struct elf32_nios2_link_hash_entry *)
+ elf_sym_hashes (input_bfd)[e_indx]);
+
+ while (hh->root.root.type == bfd_link_hash_indirect
+ || hh->root.root.type == bfd_link_hash_warning)
+ hh = ((struct elf32_nios2_link_hash_entry *)
+ hh->root.root.u.i.link);
+
+ if (hh->root.root.type == bfd_link_hash_defined
+ || hh->root.root.type == bfd_link_hash_defweak)
+ {
+ sym_sec = hh->root.root.u.def.section;
+ sym_value = hh->root.root.u.def.value;
+
+ if (sym_sec->output_section != NULL)
+ destination = (sym_value + irela->r_addend
+ + sym_sec->output_offset
+ + sym_sec->output_section->vma);
+ else
+ continue;
+ }
+ else if (hh->root.root.type == bfd_link_hash_undefweak)
+ {
+ if (! bfd_link_pic (info))
+ continue;
+ }
+ else if (hh->root.root.type == bfd_link_hash_undefined)
+ {
+ if (! (info->unresolved_syms_in_objects == RM_IGNORE
+ && (ELF_ST_VISIBILITY (hh->root.other)
+ == STV_DEFAULT)))
+ continue;
+ }
+ else
+ {
+ bfd_set_error (bfd_error_bad_value);
+ goto error_ret_free_internal;
+ }
+ }