OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gas/] [write.c] - Diff between revs 147 and 160

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 147 Rev 160
Line 1... Line 1...
/* write.c - emit .o file
/* write.c - emit .o file
   Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
   Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
   2010 Free Software Foundation, Inc.
   2010, 2011 Free Software Foundation, Inc.
 
 
   This file is part of GAS, the GNU Assembler.
   This file is part of GAS, the GNU Assembler.
 
 
   GAS is free software; you can redistribute it and/or modify
   GAS is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   it under the terms of the GNU General Public License as published by
Line 706... Line 706...
            {
            {
              as_bad_where (r->file, r->line, _("invalid reloc expression"));
              as_bad_where (r->file, r->line, _("invalid reloc expression"));
              sec = NULL;
              sec = NULL;
            }
            }
          else if (sym != NULL)
          else if (sym != NULL)
 
            {
 
              if (S_IS_LOCAL (sym) && !symbol_section_p (sym))
 
                {
 
                  asection *symsec = S_GET_SEGMENT (sym);
 
                  if (!(((symsec->flags & SEC_MERGE) != 0
 
                         && addend != 0)
 
                        || (symsec->flags & SEC_THREAD_LOCAL) != 0))
 
                    {
 
                      addend += S_GET_VALUE (sym);
 
                      sym = section_symbol (symsec);
 
                    }
 
                }
            symbol_mark_used_in_reloc (sym);
            symbol_mark_used_in_reloc (sym);
        }
        }
 
        }
      if (sym == NULL)
      if (sym == NULL)
        {
        {
          if (abs_section_sym == NULL)
          if (abs_section_sym == NULL)
            abs_section_sym = section_symbol (absolute_section);
            abs_section_sym = section_symbol (absolute_section);
          sym = abs_section_sym;
          sym = abs_section_sym;
Line 1144... Line 1157...
      as_fatal (_("%s:%u: bad return from bfd_install_relocation: %x"),
      as_fatal (_("%s:%u: bad return from bfd_install_relocation: %x"),
                file, line, s);
                file, line, s);
    }
    }
}
}
 
 
 
static fragS *
 
get_frag_for_reloc (fragS *last_frag,
 
                    const segment_info_type *seginfo,
 
                    const struct reloc_list *r)
 
{
 
  fragS *f;
 
 
 
  for (f = last_frag; f != NULL; f = f->fr_next)
 
    if (f->fr_address <= r->u.b.r.address
 
        && r->u.b.r.address < f->fr_address + f->fr_fix)
 
      return f;
 
 
 
  for (f = seginfo->frchainP->frch_root; f != NULL; f = f->fr_next)
 
    if (f->fr_address <= r->u.b.r.address
 
        && r->u.b.r.address < f->fr_address + f->fr_fix)
 
      return f;
 
 
 
  as_bad_where (r->file, r->line,
 
                _("reloc not within (fixed part of) section"));
 
  return NULL;
 
}
 
 
static void
static void
write_relocs (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
write_relocs (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
{
{
  segment_info_type *seginfo = seg_info (sec);
  segment_info_type *seginfo = seg_info (sec);
  unsigned int i;
 
  unsigned int n;
  unsigned int n;
  struct reloc_list *my_reloc_list, **rp, *r;
  struct reloc_list *my_reloc_list, **rp, *r;
  arelent **relocs;
  arelent **relocs;
  fixS *fixp;
  fixS *fixp;
 
  fragS *last_frag;
 
 
  /* If seginfo is NULL, we did not create this section; don't do
  /* If seginfo is NULL, we did not create this section; don't do
     anything with it.  */
     anything with it.  */
  if (seginfo == NULL)
  if (seginfo == NULL)
    return;
    return;
Line 1186... Line 1221...
        rp = &r->next;
        rp = &r->next;
    }
    }
 
 
  relocs = (arelent **) xcalloc (n, sizeof (arelent *));
  relocs = (arelent **) xcalloc (n, sizeof (arelent *));
 
 
  i = 0;
  n = 0;
 
  r = my_reloc_list;
 
  last_frag = NULL;
  for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next)
  for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next)
    {
    {
      int j;
 
      int fx_size, slack;
      int fx_size, slack;
      offsetT loc;
      offsetT loc;
 
      arelent **reloc;
 
#ifndef RELOC_EXPANSION_POSSIBLE
 
      arelent *rel;
 
 
 
      reloc = &rel;
 
#endif
 
 
      if (fixp->fx_done)
      if (fixp->fx_done)
        continue;
        continue;
 
 
      fx_size = fixp->fx_size;
      fx_size = fixp->fx_size;
Line 1206... Line 1248...
      if (slack >= 0 && loc > fixp->fx_frag->fr_fix)
      if (slack >= 0 && loc > fixp->fx_frag->fr_fix)
        as_bad_where (fixp->fx_file, fixp->fx_line,
        as_bad_where (fixp->fx_file, fixp->fx_line,
                      _("internal error: fixup not contained within frag"));
                      _("internal error: fixup not contained within frag"));
 
 
#ifndef RELOC_EXPANSION_POSSIBLE
#ifndef RELOC_EXPANSION_POSSIBLE
      {
      *reloc = tc_gen_reloc (sec, fixp);
        arelent *reloc = tc_gen_reloc (sec, fixp);
 
 
 
        if (!reloc)
 
          continue;
 
        relocs[i++] = reloc;
 
        j = 1;
 
      }
 
#else
#else
      {
      reloc = tc_gen_reloc (sec, fixp);
        arelent **reloc = tc_gen_reloc (sec, fixp);
#endif
 
 
        for (j = 0; reloc[j]; j++)
      while (*reloc)
          relocs[i++] = reloc[j];
        {
 
          while (r != NULL && r->u.b.r.address < (*reloc)->address)
 
            {
 
              fragS *f = get_frag_for_reloc (last_frag, seginfo, r);
 
              if (f != NULL)
 
                {
 
                  last_frag = f;
 
                  relocs[n++] = &r->u.b.r;
 
                  install_reloc (sec, &r->u.b.r, f, r->file, r->line);
 
                }
 
              r = r->next;
      }
      }
 
          relocs[n++] = *reloc;
 
          install_reloc (sec, *reloc, fixp->fx_frag,
 
                         fixp->fx_file, fixp->fx_line);
 
#ifndef RELOC_EXPANSION_POSSIBLE
 
          break;
 
#else
 
          reloc++;
#endif
#endif
 
        }
 
    }
 
 
      for ( ; j != 0; --j)
  while (r != NULL)
        install_reloc (sec, relocs[i - j], fixp->fx_frag,
    {
                       fixp->fx_file, fixp->fx_line);
      fragS *f = get_frag_for_reloc (last_frag, seginfo, r);
 
      if (f != NULL)
 
        {
 
          last_frag = f;
 
          relocs[n++] = &r->u.b.r;
 
          install_reloc (sec, &r->u.b.r, f, r->file, r->line);
 
        }
 
      r = r->next;
    }
    }
  n = i;
 
 
 
#ifdef DEBUG4
#ifdef DEBUG4
  {
  {
    unsigned int i, j, nsyms;
    unsigned int k, j, nsyms;
    asymbol **sympp;
    asymbol **sympp;
    sympp = bfd_get_outsymbols (stdoutput);
    sympp = bfd_get_outsymbols (stdoutput);
    nsyms = bfd_get_symcount (stdoutput);
    nsyms = bfd_get_symcount (stdoutput);
    for (i = 0; i < n; i++)
    for (k = 0; k < n; k++)
      if (((*relocs[i]->sym_ptr_ptr)->flags & BSF_SECTION_SYM) == 0)
      if (((*relocs[k]->sym_ptr_ptr)->flags & BSF_SECTION_SYM) == 0)
        {
        {
          for (j = 0; j < nsyms; j++)
          for (j = 0; j < nsyms; j++)
            if (sympp[j] == *relocs[i]->sym_ptr_ptr)
            if (sympp[j] == *relocs[k]->sym_ptr_ptr)
              break;
              break;
          if (j == nsyms)
          if (j == nsyms)
            abort ();
            abort ();
        }
        }
  }
  }
#endif
#endif
 
 
  for (r = my_reloc_list; r != NULL; r = r->next)
 
    {
 
      fragS *f;
 
      for (f = seginfo->frchainP->frch_root; f; f = f->fr_next)
 
        if (f->fr_address <= r->u.b.r.address
 
            && r->u.b.r.address < f->fr_address + f->fr_fix)
 
          break;
 
      if (f == NULL)
 
        as_bad_where (r->file, r->line,
 
                      _("reloc not within (fixed part of) section"));
 
      else
 
        {
 
          relocs[n++] = &r->u.b.r;
 
          install_reloc (sec, &r->u.b.r, f, r->file, r->line);
 
        }
 
    }
 
 
 
  if (n)
  if (n)
    {
    {
      flagword flags = bfd_get_section_flags (abfd, sec);
      flagword flags = bfd_get_section_flags (abfd, sec);
      flags |= SEC_RELOC;
      flags |= SEC_RELOC;
      bfd_set_section_flags (abfd, sec, flags);
      bfd_set_section_flags (abfd, sec, flags);
Line 1278... Line 1321...
  SET_SECTION_RELOCS (sec, relocs, n);
  SET_SECTION_RELOCS (sec, relocs, n);
#endif
#endif
 
 
#ifdef DEBUG3
#ifdef DEBUG3
  {
  {
    unsigned int i;
    unsigned int k;
    arelent *r;
 
    asymbol *s;
 
    fprintf (stderr, "relocs for sec %s\n", sec->name);
    fprintf (stderr, "relocs for sec %s\n", sec->name);
    for (i = 0; i < n; i++)
    for (k = 0; k < n; k++)
      {
      {
        r = relocs[i];
        arelent *rel = relocs[k];
        s = *r->sym_ptr_ptr;
        asymbol *s = *rel->sym_ptr_ptr;
        fprintf (stderr, "  reloc %2d @%p off %4lx : sym %-10s addend %lx\n",
        fprintf (stderr, "  reloc %2d @%p off %4lx : sym %-10s addend %lx\n",
                 i, r, (unsigned long)r->address, s->name, (unsigned long)r->addend);
                 k, rel, (unsigned long)rel->address, s->name,
 
                 (unsigned long)rel->addend);
      }
      }
  }
  }
#endif
#endif
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.