Develop and Download Open Source Software

Browse Subversion Repository

Diff of /trunk/bfd/coff-rs6000.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 20 by monamour, Thu Dec 4 05:12:56 2008 UTC revision 21 by monamour, Mon Jul 27 20:34:36 2009 UTC
# Line 1  Line 1 
1  /* BFD back-end for IBM RS/6000 "XCOFF" files.  /* BFD back-end for IBM RS/6000 "XCOFF" files.
2     Copyright 1990-1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,     Copyright 1990-1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
3     2008  Free Software Foundation, Inc.     2008, 2009  Free Software Foundation, Inc.
4     Written by Metin G. Ozisik, Mimi Phuong-Thao Vo, and John Gilmore.     Written by Metin G. Ozisik, Mimi Phuong-Thao Vo, and John Gilmore.
5     Archive support from Damon A. Permezel.     Archive support from Damon A. Permezel.
6     Contributed by IBM Corporation and Cygnus Support.     Contributed by IBM Corporation and Cygnus Support.
# Line 180  static bfd_boolean do_pad Line 180  static bfd_boolean do_pad
180    PARAMS ((bfd *, unsigned int));    PARAMS ((bfd *, unsigned int));
181  static bfd_boolean do_copy  static bfd_boolean do_copy
182    PARAMS ((bfd *, bfd *));    PARAMS ((bfd *, bfd *));
 static bfd_boolean do_shared_object_padding  
   PARAMS ((bfd *, bfd *, file_ptr *, int));  
183    
184  /* Relocation functions */  /* Relocation functions */
185  static bfd_boolean xcoff_reloc_type_br  static bfd_boolean xcoff_reloc_type_br
# Line 238  bfd_boolean (*xcoff_complain_overflow[XC Line 236  bfd_boolean (*xcoff_complain_overflow[XC
236    xcoff_complain_overflow_unsigned_func,    xcoff_complain_overflow_unsigned_func,
237  };  };
238    
239    /* Information about one member of an archive.  */
240    struct member_layout {
241      /* The archive member that this structure describes.  */
242      bfd *member;
243    
244      /* The number of bytes of padding that must be inserted before the
245         start of the member in order to ensure that the section contents
246         are correctly aligned.  */
247      unsigned int leading_padding;
248    
249      /* The offset of MEMBER from the start of the archive (i.e. the end
250         of the leading padding).  */
251      file_ptr offset;
252    
253      /* The normalized name of MEMBER.  */
254      const char *name;
255    
256      /* The length of NAME, without padding.  */
257      bfd_size_type namlen;
258    
259      /* The length of NAME, with padding.  */
260      bfd_size_type padded_namlen;
261    
262      /* The size of MEMBER's header, including the name and magic sequence.  */
263      bfd_size_type header_size;
264    
265      /* The size of the MEMBER's contents.  */
266      bfd_size_type contents_size;
267    
268      /* The number of bytes of padding that must be inserted after MEMBER
269         in order to preserve even alignment.  */
270      bfd_size_type trailing_padding;
271    };
272    
273    /* A structure used for iterating over the members of an archive.  */
274    struct archive_iterator {
275      /* The archive itself.  */
276      bfd *archive;
277    
278      /* Information about the current archive member.  */
279      struct member_layout current;
280    
281      /* Information about the next archive member.  MEMBER is null if there
282         are no more archive members, in which case OFFSET is the offset of
283         the first unused byte.  */
284      struct member_layout next;
285    };
286    
287    /* Initialize INFO so that it describes member MEMBER of archive ARCHIVE.
288       OFFSET is the even-padded offset of MEMBER, not including any leading
289       padding needed for section alignment.  */
290    
291    static void
292    member_layout_init (struct member_layout *info, bfd *archive,
293                        bfd *member, file_ptr offset)
294    {
295      info->member = member;
296      info->leading_padding = 0;
297      if (member)
298        {
299          info->name = normalize_filename (member);
300          info->namlen = strlen (info->name);
301          info->padded_namlen = info->namlen + (info->namlen & 1);
302          if (xcoff_big_format_p (archive))
303            info->header_size = SIZEOF_AR_HDR_BIG;
304          else
305            info->header_size = SIZEOF_AR_HDR;
306          info->header_size += info->padded_namlen + SXCOFFARFMAG;
307          info->contents_size = arelt_size (member);
308          info->trailing_padding = info->contents_size & 1;
309    
310          if (bfd_check_format (member, bfd_object)
311              && bfd_get_flavour (member) == bfd_target_xcoff_flavour
312              && (member->flags & DYNAMIC) != 0)
313            info->leading_padding
314              = (-(offset + info->header_size)
315                 & ((1 << bfd_xcoff_text_align_power (member)) - 1));
316        }
317      info->offset = offset + info->leading_padding;
318    }
319    
320    /* Set up ITERATOR to iterate through archive ARCHIVE.  */
321    
322    static void
323    archive_iterator_begin (struct archive_iterator *iterator,
324                            bfd *archive)
325    {
326      iterator->archive = archive;
327      member_layout_init (&iterator->next, archive, archive->archive_head,
328                          xcoff_big_format_p (archive)
329                          ? SIZEOF_AR_FILE_HDR_BIG
330                          : SIZEOF_AR_FILE_HDR);
331    }
332    
333    /* Make ITERATOR visit the first unvisited archive member.  Return true
334       on success; return false if all members have been visited.  */
335    
336    static bfd_boolean
337    archive_iterator_next (struct archive_iterator *iterator)
338    {
339      if (!iterator->next.member)
340        return FALSE;
341    
342      iterator->current = iterator->next;
343      member_layout_init (&iterator->next, iterator->archive,
344                          iterator->current.member->archive_next,
345                          iterator->current.offset
346                          + iterator->current.header_size
347                          + iterator->current.contents_size
348                          + iterator->current.trailing_padding);
349      return TRUE;
350    }
351    
352  /* We use our own tdata type.  Its first field is the COFF tdata type,  /* We use our own tdata type.  Its first field is the COFF tdata type,
353     so the COFF routines are compatible.  */     so the COFF routines are compatible.  */
354    
# Line 422  _bfd_xcoff_swap_aux_in (abfd, ext1, type Line 533  _bfd_xcoff_swap_aux_in (abfd, ext1, type
533    
534        /* RS/6000 "csect" auxents */        /* RS/6000 "csect" auxents */
535      case C_EXT:      case C_EXT:
536        case C_AIX_WEAKEXT:
537      case C_HIDEXT:      case C_HIDEXT:
538        if (indx + 1 == numaux)        if (indx + 1 == numaux)
539          {          {
# Line 531  _bfd_xcoff_swap_aux_out (abfd, inp, type Line 643  _bfd_xcoff_swap_aux_out (abfd, inp, type
643    
644        /* RS/6000 "csect" auxents */        /* RS/6000 "csect" auxents */
645      case C_EXT:      case C_EXT:
646        case C_AIX_WEAKEXT:
647      case C_HIDEXT:      case C_HIDEXT:
648        if (indx + 1 == numaux)        if (indx + 1 == numaux)
649          {          {
# Line 1601  xcoff_write_armap_old (abfd, elength, ma Line 1714  xcoff_write_armap_old (abfd, elength, ma
1714       unsigned int orl_count;       unsigned int orl_count;
1715       int stridx;       int stridx;
1716  {  {
1717      struct archive_iterator iterator;
1718    struct xcoff_ar_hdr hdr;    struct xcoff_ar_hdr hdr;
1719    char *p;    char *p;
1720    unsigned char buf[4];    unsigned char buf[4];
   bfd *sub;  
   file_ptr fileoff;  
1721    unsigned int i;    unsigned int i;
1722    
1723    memset (&hdr, 0, sizeof hdr);    memset (&hdr, 0, sizeof hdr);
# Line 1633  xcoff_write_armap_old (abfd, elength, ma Line 1745  xcoff_write_armap_old (abfd, elength, ma
1745    if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)    if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
1746      return FALSE;      return FALSE;
1747    
   sub = abfd->archive_head;  
   fileoff = SIZEOF_AR_FILE_HDR;  
1748    i = 0;    i = 0;
1749    while (sub != NULL && i < orl_count)    archive_iterator_begin (&iterator, abfd);
1750      {    while (i < orl_count && archive_iterator_next (&iterator))
1751        size_t namlen;      while (map[i].u.abfd == iterator.current.member)
1752          {
1753        while (map[i].u.abfd == sub)          H_PUT_32 (abfd, iterator.current.offset, buf);
1754          {          if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)
1755            H_PUT_32 (abfd, fileoff, buf);            return FALSE;
1756            if (bfd_bwrite (buf, (bfd_size_type) 4, abfd) != 4)          ++i;
1757              return FALSE;        }
           ++i;  
         }  
       namlen = strlen (normalize_filename (sub));  
       namlen = (namlen + 1) &~ (size_t) 1;  
       fileoff += (SIZEOF_AR_HDR  
                   + namlen  
                   + SXCOFFARFMAG  
                   + arelt_size (sub));  
       fileoff = (fileoff + 1) &~ 1;  
       sub = sub->archive_next;  
     }  
1758    
1759    for (i = 0; i < orl_count; i++)    for (i = 0; i < orl_count; i++)
1760      {      {
# Line 1757  do_copy (out_bfd, in_bfd) Line 1856  do_copy (out_bfd, in_bfd)
1856  }  }
1857    
1858  static bfd_boolean  static bfd_boolean
 do_shared_object_padding (out_bfd, in_bfd, offset, ar_header_size)  
      bfd *out_bfd;  
      bfd *in_bfd;  
      file_ptr *offset;  
      int ar_header_size;  
 {  
   if (bfd_check_format (in_bfd, bfd_object)  
       && bfd_get_flavour (in_bfd) == bfd_target_xcoff_flavour  
       && (in_bfd->flags & DYNAMIC) != 0)  
     {  
       bfd_size_type pad = 0;  
       int text_align_power;  
   
       text_align_power = bfd_xcoff_text_align_power (in_bfd);  
   
       pad = 1 << text_align_power;  
       pad -= (*offset + ar_header_size) & (pad - 1);  
   
       if (! do_pad (out_bfd, pad))  
         return FALSE;  
   
       *offset += pad;  
     }  
   
   return TRUE;  
 }  
   
 static bfd_boolean  
1859  xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)  xcoff_write_armap_big (abfd, elength, map, orl_count, stridx)
1860       bfd *abfd;       bfd *abfd;
1861       unsigned int elength ATTRIBUTE_UNUSED;       unsigned int elength ATTRIBUTE_UNUSED;
# Line 1792  xcoff_write_armap_big (abfd, elength, ma Line 1863  xcoff_write_armap_big (abfd, elength, ma
1863       unsigned int orl_count;       unsigned int orl_count;
1864       int stridx;       int stridx;
1865  {  {
1866      struct archive_iterator iterator;
1867    struct xcoff_ar_file_hdr_big *fhdr;    struct xcoff_ar_file_hdr_big *fhdr;
1868    bfd_vma i, sym_32, sym_64, str_32, str_64;    bfd_vma i, sym_32, sym_64, str_32, str_64;
1869    const bfd_arch_info_type *arch_info = NULL;    const bfd_arch_info_type *arch_info;
1870    bfd *current_bfd;    bfd *current_bfd;
1871    size_t string_length;    size_t string_length;
1872    file_ptr nextoff, prevoff;    file_ptr nextoff, prevoff;
# Line 1803  xcoff_write_armap_big (abfd, elength, ma Line 1875  xcoff_write_armap_big (abfd, elength, ma
1875       from 32-bit objects and which from 64-bit ones.  */       from 32-bit objects and which from 64-bit ones.  */
1876    sym_32 = sym_64 = str_32 = str_64 = 0;    sym_32 = sym_64 = str_32 = str_64 = 0;
1877    
1878    current_bfd = abfd->archive_head;    i = 0;
1879    if (current_bfd != NULL)    for (current_bfd = abfd->archive_head;
1880      arch_info = bfd_get_arch_info (current_bfd);         current_bfd != NULL && i < orl_count;
1881      i = 0;         current_bfd = current_bfd->archive_next)
     while (current_bfd != NULL && i < orl_count)  
1882      {      {
1883          arch_info = bfd_get_arch_info (current_bfd);
1884        while (map[i].u.abfd == current_bfd)        while (map[i].u.abfd == current_bfd)
1885          {          {
1886            string_length = strlen (*map[i].name) + 1;            string_length = strlen (*map[i].name) + 1;
   
1887            if (arch_info->bits_per_address == 64)            if (arch_info->bits_per_address == 64)
1888              {              {
1889                sym_64++;                sym_64++;
# Line 1825  xcoff_write_armap_big (abfd, elength, ma Line 1896  xcoff_write_armap_big (abfd, elength, ma
1896              }              }
1897            i++;            i++;
1898          }          }
       current_bfd = current_bfd->archive_next;  
       if (current_bfd != NULL)  
         arch_info = bfd_get_arch_info (current_bfd);  
1899      }      }
1900    
1901    /* A quick sanity check... */    /* A quick sanity check... */
# Line 1869  xcoff_write_armap_big (abfd, elength, ma Line 1937  xcoff_write_armap_big (abfd, elength, ma
1937        struct xcoff_ar_hdr_big *hdr;        struct xcoff_ar_hdr_big *hdr;
1938        char *symbol_table;        char *symbol_table;
1939        char *st;        char *st;
       file_ptr fileoff;  
1940    
1941        bfd_vma symbol_table_size =        bfd_vma symbol_table_size =
1942          SIZEOF_AR_HDR_BIG          SIZEOF_AR_HDR_BIG
# Line 1906  xcoff_write_armap_big (abfd, elength, ma Line 1973  xcoff_write_armap_big (abfd, elength, ma
1973        st += 8;        st += 8;
1974    
1975        /* loop over the 32 bit offsets */        /* loop over the 32 bit offsets */
       current_bfd = abfd->archive_head;  
       if (current_bfd != NULL)  
         arch_info = bfd_get_arch_info (current_bfd);  
       fileoff = SIZEOF_AR_FILE_HDR_BIG;  
1976        i = 0;        i = 0;
1977        while (current_bfd != NULL && i < orl_count)        archive_iterator_begin (&iterator, abfd);
1978          while (i < orl_count && archive_iterator_next (&iterator))
1979          {          {
1980            while (map[i].u.abfd == current_bfd)            arch_info = bfd_get_arch_info (iterator.current.member);
1981              while (map[i].u.abfd == iterator.current.member)
1982              {              {
1983                if (arch_info->bits_per_address == 32)                if (arch_info->bits_per_address == 32)
1984                  {                  {
1985                    bfd_h_put_64 (abfd, fileoff, st);                    bfd_h_put_64 (abfd, iterator.current.offset, st);
1986                    st += 8;                    st += 8;
1987                  }                  }
1988                i++;                i++;
1989              }              }
           string_length = strlen (normalize_filename (current_bfd));  
           string_length += string_length & 1;  
           fileoff += (SIZEOF_AR_HDR_BIG  
                       + string_length  
                       + SXCOFFARFMAG  
                       + arelt_size (current_bfd));  
           fileoff += fileoff & 1;  
           current_bfd = current_bfd->archive_next;  
           if (current_bfd != NULL)  
             arch_info = bfd_get_arch_info (current_bfd);  
1990          }          }
1991    
1992        /* loop over the 32 bit symbol names */        /* loop over the 32 bit symbol names */
       current_bfd = abfd->archive_head;  
       if (current_bfd != NULL)  
         arch_info = bfd_get_arch_info (current_bfd);  
1993        i = 0;        i = 0;
1994        while (current_bfd != NULL && i < orl_count)        for (current_bfd = abfd->archive_head;
1995               current_bfd != NULL && i < orl_count;
1996               current_bfd = current_bfd->archive_next)
1997          {          {
1998              arch_info = bfd_get_arch_info (current_bfd);
1999            while (map[i].u.abfd == current_bfd)            while (map[i].u.abfd == current_bfd)
2000              {              {
2001                if (arch_info->bits_per_address == 32)                if (arch_info->bits_per_address == 32)
# Line 1950  xcoff_write_armap_big (abfd, elength, ma Line 2005  xcoff_write_armap_big (abfd, elength, ma
2005                  }                  }
2006                i++;                i++;
2007              }              }
           current_bfd = current_bfd->archive_next;  
           if (current_bfd != NULL)  
             arch_info = bfd_get_arch_info (current_bfd);  
2008          }          }
2009    
2010        bfd_bwrite (symbol_table, symbol_table_size, abfd);        bfd_bwrite (symbol_table, symbol_table_size, abfd);
# Line 1970  xcoff_write_armap_big (abfd, elength, ma Line 2022  xcoff_write_armap_big (abfd, elength, ma
2022        struct xcoff_ar_hdr_big *hdr;        struct xcoff_ar_hdr_big *hdr;
2023        char *symbol_table;        char *symbol_table;
2024        char *st;        char *st;
       file_ptr fileoff;  
2025    
2026        bfd_vma symbol_table_size =        bfd_vma symbol_table_size =
2027          SIZEOF_AR_HDR_BIG          SIZEOF_AR_HDR_BIG
# Line 2002  xcoff_write_armap_big (abfd, elength, ma Line 2053  xcoff_write_armap_big (abfd, elength, ma
2053        st += 8;        st += 8;
2054    
2055        /* loop over the 64 bit offsets */        /* loop over the 64 bit offsets */
       current_bfd = abfd->archive_head;  
       if (current_bfd != NULL)  
         arch_info = bfd_get_arch_info (current_bfd);  
       fileoff = SIZEOF_AR_FILE_HDR_BIG;  
2056        i = 0;        i = 0;
2057        while (current_bfd != NULL && i < orl_count)        archive_iterator_begin (&iterator, abfd);
2058          while (i < orl_count && archive_iterator_next (&iterator))
2059          {          {
2060            while (map[i].u.abfd == current_bfd)            arch_info = bfd_get_arch_info (iterator.current.member);
2061              while (map[i].u.abfd == iterator.current.member)
2062              {              {
2063                if (arch_info->bits_per_address == 64)                if (arch_info->bits_per_address == 64)
2064                  {                  {
2065                    bfd_h_put_64 (abfd, fileoff, st);                    bfd_h_put_64 (abfd, iterator.current.offset, st);
2066                    st += 8;                    st += 8;
2067                  }                  }
2068                i++;                i++;
2069              }              }
           string_length = strlen (normalize_filename (current_bfd));  
           string_length += string_length & 1;  
           fileoff += (SIZEOF_AR_HDR_BIG  
                       + string_length  
                       + SXCOFFARFMAG  
                       + arelt_size (current_bfd));  
           fileoff += fileoff & 1;  
           current_bfd = current_bfd->archive_next;  
           if (current_bfd != NULL)  
             arch_info = bfd_get_arch_info (current_bfd);  
2070          }          }
2071    
2072        /* loop over the 64 bit symbol names */        /* loop over the 64 bit symbol names */
       current_bfd = abfd->archive_head;  
       if (current_bfd != NULL)  
         arch_info = bfd_get_arch_info (current_bfd);  
2073        i = 0;        i = 0;
2074        while (current_bfd != NULL && i < orl_count)        for (current_bfd = abfd->archive_head;
2075               current_bfd != NULL && i < orl_count;
2076               current_bfd = current_bfd->archive_next)
2077          {          {
2078              arch_info = bfd_get_arch_info (current_bfd);
2079            while (map[i].u.abfd == current_bfd)            while (map[i].u.abfd == current_bfd)
2080              {              {
2081                if (arch_info->bits_per_address == 64)                if (arch_info->bits_per_address == 64)
# Line 2046  xcoff_write_armap_big (abfd, elength, ma Line 2085  xcoff_write_armap_big (abfd, elength, ma
2085                  }                  }
2086                i++;                i++;
2087              }              }
           current_bfd = current_bfd->archive_next;  
           if (current_bfd != NULL)  
             arch_info = bfd_get_arch_info (current_bfd);  
2088          }          }
2089    
2090        bfd_bwrite (symbol_table, symbol_table_size, abfd);        bfd_bwrite (symbol_table, symbol_table_size, abfd);
# Line 2084  static bfd_boolean Line 2120  static bfd_boolean
2120  xcoff_write_archive_contents_old (abfd)  xcoff_write_archive_contents_old (abfd)
2121       bfd *abfd;       bfd *abfd;
2122  {  {
2123      struct archive_iterator iterator;
2124    struct xcoff_ar_file_hdr fhdr;    struct xcoff_ar_file_hdr fhdr;
2125    bfd_size_type count;    bfd_size_type count;
2126    bfd_size_type total_namlen;    bfd_size_type total_namlen;
# Line 2109  xcoff_write_archive_contents_old (abfd) Line 2146  xcoff_write_archive_contents_old (abfd)
2146      {      {
2147        ++count;        ++count;
2148        total_namlen += strlen (normalize_filename (sub)) + 1;        total_namlen += strlen (normalize_filename (sub)) + 1;
2149      }        if (sub->arelt_data == NULL)
   offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr));  
   if (offsets == NULL)  
     return FALSE;  
   
   if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR, SEEK_SET) != 0)  
     return FALSE;  
   
   makemap = bfd_has_map (abfd);  
   hasobjects = FALSE;  
   prevoff = 0;  
   nextoff = SIZEOF_AR_FILE_HDR;  
   for (sub = abfd->archive_head, i = 0;  
        sub != NULL;  
        sub = sub->archive_next, i++)  
     {  
       const char *name;  
       bfd_size_type namlen;  
       struct xcoff_ar_hdr *ahdrp;  
       bfd_size_type remaining;  
   
       if (makemap && ! hasobjects)  
2150          {          {
2151            if (bfd_check_format (sub, bfd_object))            sub->arelt_data = bfd_zalloc (sub, sizeof (struct areltdata));
2152              hasobjects = TRUE;            if (sub->arelt_data == NULL)
2153                return FALSE;
2154          }          }
2155          if (arch_xhdr (sub) == NULL)
       name = normalize_filename (sub);  
       namlen = strlen (name);  
   
       if (sub->arelt_data != NULL)  
         ahdrp = arch_xhdr (sub);  
       else  
         ahdrp = NULL;  
   
       if (ahdrp == NULL)  
2156          {          {
2157              struct xcoff_ar_hdr *ahdrp;
2158            struct stat s;            struct stat s;
2159    
           memset (&ahdr, 0, sizeof ahdr);  
           ahdrp = &ahdr;  
2160            if (stat (bfd_get_filename (sub), &s) != 0)            if (stat (bfd_get_filename (sub), &s) != 0)
2161              {              {
2162                bfd_set_error (bfd_error_system_call);                bfd_set_error (bfd_error_system_call);
2163                return FALSE;                return FALSE;
2164              }              }
2165    
2166              ahdrp = bfd_zalloc (sub, sizeof (*ahdrp));
2167              if (ahdrp == NULL)
2168                return FALSE;
2169    
2170            sprintf (ahdrp->size, "%ld", (long) s.st_size);            sprintf (ahdrp->size, "%ld", (long) s.st_size);
2171            sprintf (ahdrp->date, "%ld", (long) s.st_mtime);            sprintf (ahdrp->date, "%ld", (long) s.st_mtime);
2172            sprintf (ahdrp->uid, "%ld", (long) s.st_uid);            sprintf (ahdrp->uid, "%ld", (long) s.st_uid);
2173            sprintf (ahdrp->gid, "%ld", (long) s.st_gid);            sprintf (ahdrp->gid, "%ld", (long) s.st_gid);
2174            sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode);            sprintf (ahdrp->mode, "%o", (unsigned int) s.st_mode);
2175    
2176            if (sub->arelt_data == NULL)            arch_eltdata (sub)->arch_header = (char *) ahdrp;
             {  
               size = sizeof (struct areltdata);  
               sub->arelt_data = bfd_alloc (sub, size);  
               if (sub->arelt_data == NULL)  
                 return FALSE;  
             }  
   
2177            arch_eltdata (sub)->parsed_size = s.st_size;            arch_eltdata (sub)->parsed_size = s.st_size;
2178          }          }
2179        }
2180      offsets = (file_ptr *) bfd_alloc (abfd, count * sizeof (file_ptr));
2181      if (offsets == NULL)
2182        return FALSE;
2183    
2184        sprintf (ahdrp->prevoff, "%ld", (long) prevoff);    if (bfd_seek (abfd, (file_ptr) SIZEOF_AR_FILE_HDR, SEEK_SET) != 0)
2185        sprintf (ahdrp->namlen, "%ld", (long) namlen);      return FALSE;
   
       /* If the length of the name is odd, we write out the null byte  
          after the name as well.  */  
       namlen = (namlen + 1) &~ (bfd_size_type) 1;  
   
       remaining = arelt_size (sub);  
       size = (SIZEOF_AR_HDR  
               + namlen  
               + SXCOFFARFMAG  
               + remaining);  
   
       BFD_ASSERT (nextoff == bfd_tell (abfd));  
2186    
2187        offsets[i] = nextoff;    makemap = bfd_has_map (abfd);
2188      hasobjects = FALSE;
2189      prevoff = 0;
2190      for (archive_iterator_begin (&iterator, abfd), i = 0;
2191           archive_iterator_next (&iterator);
2192           i++)
2193        {
2194          bfd_size_type namlen;
2195          struct xcoff_ar_hdr *ahdrp;
2196    
2197        prevoff = nextoff;        if (makemap && ! hasobjects)
2198        nextoff += size + (size & 1);          {
2199              if (bfd_check_format (iterator.current.member, bfd_object))
2200                hasobjects = TRUE;
2201            }
2202    
2203        sprintf (ahdrp->nextoff, "%ld", (long) nextoff);        ahdrp = arch_xhdr (iterator.current.member);
2204          sprintf (ahdrp->prevoff, "%ld", (long) prevoff);
2205          sprintf (ahdrp->namlen, "%ld", (long) iterator.current.namlen);
2206          sprintf (ahdrp->nextoff, "%ld", (long) iterator.next.offset);
2207    
2208        /* We need spaces, not null bytes, in the header.  */        /* We need spaces, not null bytes, in the header.  */
2209        for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR; p++)        for (p = (char *) ahdrp; p < (char *) ahdrp + SIZEOF_AR_HDR; p++)
2210          if (*p == '\0')          if (*p == '\0')
2211            *p = ' ';            *p = ' ';
2212    
2213        if ((bfd_bwrite ((PTR) ahdrp, (bfd_size_type) SIZEOF_AR_HDR, abfd)        if (!do_pad (abfd, iterator.current.leading_padding))
            != SIZEOF_AR_HDR)  
           || bfd_bwrite ((PTR) name, namlen, abfd) != namlen  
           || bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG,  
                          abfd) != SXCOFFARFMAG)  
         return FALSE;  
   
       if (bfd_seek (sub, (file_ptr) 0, SEEK_SET) != 0)  
2214          return FALSE;          return FALSE;
2215    
2216        if (! do_copy (abfd, sub))        BFD_ASSERT (iterator.current.offset == bfd_tell (abfd));
2217          namlen = iterator.current.padded_namlen;
2218          if (bfd_bwrite (ahdrp, SIZEOF_AR_HDR, abfd) != SIZEOF_AR_HDR
2219              || bfd_bwrite (iterator.current.name, namlen, abfd) != namlen
2220              || bfd_bwrite (XCOFFARFMAG, SXCOFFARFMAG, abfd) != SXCOFFARFMAG
2221              || bfd_seek (iterator.current.member, 0, SEEK_SET) != 0
2222              || !do_copy (abfd, iterator.current.member)
2223              || !do_pad (abfd, iterator.current.trailing_padding))
2224          return FALSE;          return FALSE;
2225    
2226        if (! do_pad (abfd, size & 1))        offsets[i] = iterator.current.offset;
2227          return FALSE;        prevoff = iterator.current.offset;
2228      }      }
2229    
2230    sprintf (fhdr.lastmemoff, "%ld", (long) prevoff);    sprintf (fhdr.lastmemoff, "%ld", (long) prevoff);
2231    
2232    /* Write out the member table.  */    /* Write out the member table.  */
2233    
2234      nextoff = iterator.next.offset;
2235    BFD_ASSERT (nextoff == bfd_tell (abfd));    BFD_ASSERT (nextoff == bfd_tell (abfd));
2236    sprintf (fhdr.memoff, "%ld", (long) nextoff);    sprintf (fhdr.memoff, "%ld", (long) nextoff);
2237    
# Line 2325  xcoff_write_archive_contents_big (abfd) Line 2336  xcoff_write_archive_contents_big (abfd)
2336    file_ptr prevoff, nextoff;    file_ptr prevoff, nextoff;
2337    bfd *current_bfd;    bfd *current_bfd;
2338    size_t i;    size_t i;
2339    struct xcoff_ar_hdr_big *hdr, ahdr;    struct xcoff_ar_hdr_big *hdr;
2340    bfd_size_type size;    bfd_size_type size;
2341    char *member_table, *mt;    char *member_table, *mt;
2342    bfd_vma member_table_size;    bfd_vma member_table_size;
2343      struct archive_iterator iterator;
2344    
2345    memset (&fhdr, 0, SIZEOF_AR_FILE_HDR_BIG);    memset (&fhdr, 0, SIZEOF_AR_FILE_HDR_BIG);
2346    memcpy (fhdr.magic, XCOFFARMAGBIG, SXCOFFARMAG);    memcpy (fhdr.magic, XCOFFARMAGBIG, SXCOFFARMAG);
# Line 2349  xcoff_write_archive_contents_big (abfd) Line 2361  xcoff_write_archive_contents_big (abfd)
2361            && ! hasobjects            && ! hasobjects
2362            && bfd_check_format (current_bfd, bfd_object))            && bfd_check_format (current_bfd, bfd_object))
2363          hasobjects = TRUE;          hasobjects = TRUE;
     }  
2364    
2365    offsets = NULL;        if (current_bfd->arelt_data == NULL)
2366    if (count)          {
2367      {            size = sizeof (struct areltdata);
2368        offsets = (file_ptr *) bfd_malloc (count * sizeof (file_ptr));            current_bfd->arelt_data = bfd_zalloc (current_bfd, size);
2369        if (offsets == NULL)            if (current_bfd->arelt_data == NULL)
2370          return FALSE;              return FALSE;
2371      }          }
   
   prevoff = 0;  
   nextoff = SIZEOF_AR_FILE_HDR_BIG;  
   for (current_bfd = abfd->archive_head, i = 0;  
        current_bfd != NULL;  
        current_bfd = current_bfd->archive_next, i++)  
     {  
       const char *name;  
       bfd_size_type namlen;  
       struct xcoff_ar_hdr_big *ahdrp;  
       bfd_size_type remaining;  
   
       name = normalize_filename (current_bfd);  
       namlen = strlen (name);  
   
       if (current_bfd->arelt_data != NULL)  
         ahdrp = arch_xhdr_big (current_bfd);  
       else  
         ahdrp = NULL;  
2372    
2373        if (ahdrp == NULL)        if (arch_xhdr_big (current_bfd) == NULL)
2374          {          {
2375              struct xcoff_ar_hdr_big *ahdrp;
2376            struct stat s;            struct stat s;
2377    
           ahdrp = &ahdr;  
2378            /* XXX This should actually be a call to stat64 (at least on            /* XXX This should actually be a call to stat64 (at least on
2379               32-bit machines).               32-bit machines).
2380               XXX This call will fail if the original object is not found.  */               XXX This call will fail if the original object is not found.  */
# Line 2392  xcoff_write_archive_contents_big (abfd) Line 2384  xcoff_write_archive_contents_big (abfd)
2384                return FALSE;                return FALSE;
2385              }              }
2386    
2387              ahdrp = bfd_zalloc (current_bfd, sizeof (*ahdrp));
2388              if (ahdrp == NULL)
2389                return FALSE;
2390    
2391            PRINT20 (ahdrp->size, s.st_size);            PRINT20 (ahdrp->size, s.st_size);
2392            PRINT12 (ahdrp->date, s.st_mtime);            PRINT12 (ahdrp->date, s.st_mtime);
2393            PRINT12 (ahdrp->uid,  s.st_uid);            PRINT12 (ahdrp->uid,  s.st_uid);
2394            PRINT12 (ahdrp->gid,  s.st_gid);            PRINT12 (ahdrp->gid,  s.st_gid);
2395            PRINT12_OCTAL (ahdrp->mode, s.st_mode);            PRINT12_OCTAL (ahdrp->mode, s.st_mode);
2396    
2397            if (current_bfd->arelt_data == NULL)            arch_eltdata (current_bfd)->arch_header = (char *) ahdrp;
             {  
               size = sizeof (struct areltdata);  
               current_bfd->arelt_data = bfd_alloc (current_bfd, size);  
               if (current_bfd->arelt_data == NULL)  
                 return FALSE;  
             }  
   
2398            arch_eltdata (current_bfd)->parsed_size = s.st_size;            arch_eltdata (current_bfd)->parsed_size = s.st_size;
2399          }          }
2400        }
2401    
2402        PRINT20 (ahdrp->prevoff, prevoff);    offsets = NULL;
2403        PRINT4 (ahdrp->namlen, namlen);    if (count)
2404        {
2405        /* If the length of the name is odd, we write out the null byte        offsets = (file_ptr *) bfd_malloc (count * sizeof (file_ptr));
2406           after the name as well.  */        if (offsets == NULL)
       namlen = (namlen + 1) &~ (bfd_size_type) 1;  
   
       remaining = arelt_size (current_bfd);  
       size = (SIZEOF_AR_HDR_BIG  
               + namlen  
               + SXCOFFARFMAG  
               + remaining);  
   
       BFD_ASSERT (nextoff == bfd_tell (abfd));  
   
       /* Check for xcoff shared objects.  
          Their text section needs to be aligned wrt the archive file position.  
          This requires extra padding before the archive header.  */  
       if (! do_shared_object_padding (abfd, current_bfd, & nextoff,  
                                       SIZEOF_AR_HDR_BIG + namlen  
                                       + SXCOFFARFMAG))  
2407          return FALSE;          return FALSE;
2408        }
2409    
2410        offsets[i] = nextoff;    prevoff = 0;
2411      for (archive_iterator_begin (&iterator, abfd), i = 0;
2412        prevoff = nextoff;         archive_iterator_next (&iterator);
2413        nextoff += size + (size & 1);         i++)
2414        {
2415        PRINT20 (ahdrp->nextoff, nextoff);        bfd_size_type namlen;
2416          struct xcoff_ar_hdr_big *ahdrp;
2417    
2418        if ((bfd_bwrite ((PTR) ahdrp, (bfd_size_type) SIZEOF_AR_HDR_BIG, abfd)        ahdrp = arch_xhdr_big (iterator.current.member);
2419             != SIZEOF_AR_HDR_BIG)        PRINT20 (ahdrp->prevoff, prevoff);
2420            || bfd_bwrite ((PTR) name, (bfd_size_type) namlen, abfd) != namlen        PRINT4 (ahdrp->namlen, iterator.current.namlen);
2421            || (bfd_bwrite ((PTR) XCOFFARFMAG, (bfd_size_type) SXCOFFARFMAG,        PRINT20 (ahdrp->nextoff, iterator.next.offset);
                           abfd) != SXCOFFARFMAG))  
         return FALSE;  
2422    
2423        if (bfd_seek (current_bfd, (file_ptr) 0, SEEK_SET) != 0)        if (!do_pad (abfd, iterator.current.leading_padding))
2424          return FALSE;          return FALSE;
2425    
2426        if (! do_copy (abfd, current_bfd))        BFD_ASSERT (iterator.current.offset == bfd_tell (abfd));
2427          namlen = iterator.current.padded_namlen;
2428          if (bfd_bwrite (ahdrp, SIZEOF_AR_HDR_BIG, abfd) != SIZEOF_AR_HDR_BIG
2429              || bfd_bwrite (iterator.current.name, namlen, abfd) != namlen
2430              || bfd_bwrite (XCOFFARFMAG, SXCOFFARFMAG, abfd) != SXCOFFARFMAG
2431              || bfd_seek (iterator.current.member, 0, SEEK_SET) != 0
2432              || !do_copy (abfd, iterator.current.member)
2433              || !do_pad (abfd, iterator.current.trailing_padding))
2434          return FALSE;          return FALSE;
2435    
2436        if (! do_pad (abfd, size & 1))        offsets[i] = iterator.current.offset;
2437          return FALSE;        prevoff = iterator.current.offset;
2438      }      }
2439    
2440    if (count)    if (count)
# Line 2483  xcoff_write_archive_contents_big (abfd) Line 2464  xcoff_write_archive_contents_big (abfd)
2464       ??                       pad to even bytes.       ??                       pad to even bytes.
2465     */     */
2466    
2467      nextoff = iterator.next.offset;
2468    BFD_ASSERT (nextoff == bfd_tell (abfd));    BFD_ASSERT (nextoff == bfd_tell (abfd));
2469    
2470    member_table_size = (SIZEOF_AR_HDR_BIG    member_table_size = (SIZEOF_AR_HDR_BIG
# Line 2947  xcoff_reloc_type_br (input_bfd, input_se Line 2929  xcoff_reloc_type_br (input_bfd, input_se
2929       bfd_byte *contents;       bfd_byte *contents;
2930  {  {
2931    struct xcoff_link_hash_entry *h;    struct xcoff_link_hash_entry *h;
2932      bfd_vma section_offset;
2933    
2934    if (0 > rel->r_symndx)    if (0 > rel->r_symndx)
2935      return FALSE;      return FALSE;
2936    
2937    h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];    h = obj_xcoff_sym_hashes (input_bfd)[rel->r_symndx];
2938      section_offset = rel->r_vaddr - input_section->vma;
2939    
2940    /* If we see an R_BR or R_RBR reloc which is jumping to global    /* If we see an R_BR or R_RBR reloc which is jumping to global
2941       linkage code, and it is followed by an appropriate cror nop       linkage code, and it is followed by an appropriate cror nop
# Line 2961  xcoff_reloc_type_br (input_bfd, input_se Line 2945  xcoff_reloc_type_br (input_bfd, input_se
2945       going to global linkage code, we can replace the load with a       going to global linkage code, we can replace the load with a
2946       cror.  */       cror.  */
2947    if (NULL != h    if (NULL != h
2948        && bfd_link_hash_defined == h->root.type        && (bfd_link_hash_defined == h->root.type
2949        && rel->r_vaddr - input_section->vma + 8 <= input_section->size)            || bfd_link_hash_defweak == h->root.type)
2950          && section_offset + 8 <= input_section->size)
2951      {      {
2952        bfd_byte *pnext;        bfd_byte *pnext;
2953        unsigned long next;        unsigned long next;
2954    
2955        pnext = contents + (rel->r_vaddr - input_section->vma) + 4;        pnext = contents + section_offset + 4;
2956        next = bfd_get_32 (input_bfd, pnext);        next = bfd_get_32 (input_bfd, pnext);
2957    
2958        /* The _ptrgl function is magic.  It is used by the AIX        /* The _ptrgl function is magic.  It is used by the AIX
# Line 2977  xcoff_reloc_type_br (input_bfd, input_se Line 2962  xcoff_reloc_type_br (input_bfd, input_se
2962            if (next == 0x4def7b82                        /* cror 15,15,15 */            if (next == 0x4def7b82                        /* cror 15,15,15 */
2963                || next == 0x4ffffb82                     /* cror 31,31,31 */                || next == 0x4ffffb82                     /* cror 31,31,31 */
2964                || next == 0x60000000)                    /* ori r0,r0,0 */                || next == 0x60000000)                    /* ori r0,r0,0 */
2965              bfd_put_32 (input_bfd, 0x80410014, pnext);  /* lwz r1,20(r1) */              bfd_put_32 (input_bfd, 0x80410014, pnext);  /* lwz r2,20(r1) */
2966    
2967          }          }
2968        else        else
2969          {          {
2970            if (next == 0x80410014)                       /* lwz r1,20(r1) */            if (next == 0x80410014)                       /* lwz r2,20(r1) */
2971              bfd_put_32 (input_bfd, 0x60000000, pnext);  /* ori r0,r0,0 */              bfd_put_32 (input_bfd, 0x60000000, pnext);  /* ori r0,r0,0 */
2972          }          }
2973      }      }
# Line 2998  xcoff_reloc_type_br (input_bfd, input_se Line 2983  xcoff_reloc_type_br (input_bfd, input_se
2983        howto->complain_on_overflow = complain_overflow_dont;        howto->complain_on_overflow = complain_overflow_dont;
2984      }      }
2985    
2986    howto->pc_relative = TRUE;    /* The original PC-relative relocation is biased by -r_vaddr, so adding
2987         the value below will give the absolute target address.  */
2988      *relocation = val + addend + rel->r_vaddr;
2989    
2990    howto->src_mask &= ~3;    howto->src_mask &= ~3;
2991    howto->dst_mask = howto->src_mask;    howto->dst_mask = howto->src_mask;
2992    
2993    /* A PC relative reloc includes the section address.  */    if (h != NULL
2994    addend += input_section->vma;        && (h->root.type == bfd_link_hash_defined
2995              || h->root.type == bfd_link_hash_defweak)
2996    *relocation = val + addend;        && bfd_is_abs_section (h->root.u.def.section)
2997    *relocation -= (input_section->output_section->vma        && section_offset + 4 <= input_section->size)
2998                    + input_section->output_offset);      {
2999          bfd_byte *ptr;
3000          bfd_vma insn;
3001    
3002          /* Turn the relative branch into an absolute one by setting the
3003             AA bit.  */
3004          ptr = contents + section_offset;
3005          insn = bfd_get_32 (input_bfd, ptr);
3006          insn |= 2;
3007          bfd_put_32 (input_bfd, insn, ptr);
3008    
3009          /* Make the howto absolute too.  */
3010          howto->pc_relative = FALSE;
3011          howto->complain_on_overflow = complain_overflow_bitfield;
3012        }
3013      else
3014        {
3015          /* Use a PC-relative howto and subtract the instruction's address
3016             from the target address we calculated above.  */
3017          howto->pc_relative = TRUE;
3018          *relocation -= (input_section->output_section->vma
3019                          + input_section->output_offset
3020                          + section_offset);
3021        }
3022    return TRUE;    return TRUE;
3023  }  }
3024    
# Line 3323  xcoff_complain_overflow_unsigned_func (i Line 3334  xcoff_complain_overflow_unsigned_func (i
3334    
3335     R_RBR:     R_RBR:
3336     A relative branch which may be modified to become an     A relative branch which may be modified to become an
3337     absolute branch.  FIXME: We don't implement this,     absolute branch.
    although we should for symbols of storage mapping class  
    XMC_XO.  
3338    
3339     R_RL:     R_RL:
3340     The PowerPC AIX ABI describes this as a load which may be     The PowerPC AIX ABI describes this as a load which may be
# Line 3422  xcoff_ppc_relocate_section (output_bfd, Line 3431  xcoff_ppc_relocate_section (output_bfd,
3431              }              }
3432            else            else
3433              {              {
3434                  if (info->unresolved_syms_in_objects != RM_IGNORE
3435                      && (h->flags & XCOFF_WAS_UNDEFINED) != 0)
3436                    {
3437                      if (! ((*info->callbacks->undefined_symbol)
3438                             (info, h->root.root.string,
3439                              input_bfd, input_section,
3440                              rel->r_vaddr - input_section->vma,
3441                              (info->unresolved_syms_in_objects
3442                               == RM_GENERATE_ERROR))))
3443                        return FALSE;
3444                    }
3445                if (h->root.type == bfd_link_hash_defined                if (h->root.type == bfd_link_hash_defined
3446                    || h->root.type == bfd_link_hash_defweak)                    || h->root.type == bfd_link_hash_defweak)
3447                  {                  {
# Line 3437  xcoff_ppc_relocate_section (output_bfd, Line 3457  xcoff_ppc_relocate_section (output_bfd,
3457                           + sec->output_offset);                           + sec->output_offset);
3458    
3459                  }                  }
3460                else if ((0 == (h->flags & (XCOFF_DEF_DYNAMIC | XCOFF_IMPORT)))                else
                        && ! info->relocatable)  
3461                  {                  {
3462                    if (! ((*info->callbacks->undefined_symbol)                    BFD_ASSERT (info->relocatable
3463                           (info, h->root.root.string, input_bfd, input_section,                                || (info->static_link
3464                            rel->r_vaddr - input_section->vma, TRUE)))                                    && (h->flags & XCOFF_WAS_UNDEFINED) != 0)
3465                      return FALSE;                                || (h->flags & XCOFF_DEF_DYNAMIC) != 0
3466                                  || (h->flags & XCOFF_IMPORT) != 0);
                   /* Don't try to process the reloc.  It can't help, and  
                      it may generate another error.  */  
                   continue;  
3467                  }                  }
3468              }              }
3469          }          }
# Line 4011  static const struct xcoff_backend_data_r Line 4027  static const struct xcoff_backend_data_r
4027        LINESZ,        LINESZ,
4028        FILNMLEN,        FILNMLEN,
4029        TRUE,                     /* _bfd_coff_long_filenames */        TRUE,                     /* _bfd_coff_long_filenames */
4030        FALSE,                    /* _bfd_coff_long_section_names */        XCOFF_NO_LONG_SECTION_NAMES,  /* _bfd_coff_long_section_names */
4031        3,                        /* _bfd_coff_default_section_alignment_power */        3,                        /* _bfd_coff_default_section_alignment_power */
4032        FALSE,                    /* _bfd_coff_force_symnames_in_strings */        FALSE,                    /* _bfd_coff_force_symnames_in_strings */
4033        2,                        /* _bfd_coff_debug_string_prefix_length */        2,                        /* _bfd_coff_debug_string_prefix_length */
# Line 4219  const bfd_target rs6000coff_vec = Line 4235  const bfd_target rs6000coff_vec =
4235      bfd_generic_is_group_section,      bfd_generic_is_group_section,
4236      bfd_generic_discard_group,      bfd_generic_discard_group,
4237      _bfd_generic_section_already_linked,      _bfd_generic_section_already_linked,
4238        _bfd_xcoff_define_common_symbol,
4239    
4240      /* Dynamic */      /* Dynamic */
4241      _bfd_xcoff_get_dynamic_symtab_upper_bound,      _bfd_xcoff_get_dynamic_symtab_upper_bound,
# Line 4263  static const struct xcoff_backend_data_r Line 4280  static const struct xcoff_backend_data_r
4280        LINESZ,        LINESZ,
4281        FILNMLEN,        FILNMLEN,
4282        TRUE,                     /* _bfd_coff_long_filenames */        TRUE,                     /* _bfd_coff_long_filenames */
4283        FALSE,                    /* _bfd_coff_long_section_names */        XCOFF_NO_LONG_SECTION_NAMES,  /* _bfd_coff_long_section_names */
4284        3,                        /* _bfd_coff_default_section_alignment_power */        3,                        /* _bfd_coff_default_section_alignment_power */
4285        FALSE,                    /* _bfd_coff_force_symnames_in_strings */        FALSE,                    /* _bfd_coff_force_symnames_in_strings */
4286        2,                        /* _bfd_coff_debug_string_prefix_length */        2,                        /* _bfd_coff_debug_string_prefix_length */
# Line 4471  const bfd_target pmac_xcoff_vec = Line 4488  const bfd_target pmac_xcoff_vec =
4488      bfd_generic_is_group_section,      bfd_generic_is_group_section,
4489      bfd_generic_discard_group,      bfd_generic_discard_group,
4490      _bfd_generic_section_already_linked,      _bfd_generic_section_already_linked,
4491        _bfd_xcoff_define_common_symbol,
4492    
4493      /* Dynamic */      /* Dynamic */
4494      _bfd_xcoff_get_dynamic_symtab_upper_bound,      _bfd_xcoff_get_dynamic_symtab_upper_bound,

Legend:
Removed from v.20  
changed lines
  Added in v.21

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26