coff-rs6000.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,164 行 · 第 1/5 页
C
2,164 行
struct xcoff_ar_file_hdr_big hdr; /* Copy over the magic string. */ memcpy (hdr.magic, magic, SXCOFFARMAG); /* Now read the rest of the file header. */ if (bfd_read ((PTR) &hdr.memoff, SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG, 1, abfd) != SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG) { if (bfd_get_error () != bfd_error_system_call) bfd_set_error (bfd_error_wrong_format); return NULL; } /* XXX This actually has to be a call to strtoll (at least on 32-bit machines) since the field width is 20 and there numbers with more than 32 bits can be represented. */ bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff, (char **) NULL, 10); bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, SIZEOF_AR_FILE_HDR_BIG); if (bfd_ardata (abfd)->tdata == NULL) return NULL; memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG); } if (! _bfd_xcoff_slurp_armap (abfd)) { bfd_release (abfd, bfd_ardata (abfd)); abfd->tdata.aout_ar_data = (struct artdata *) NULL; return NULL; } return abfd->xvec;}/* Read the archive header in an XCOFF archive. */PTR_bfd_xcoff_read_ar_hdr (abfd) bfd *abfd;{ size_t namlen; struct areltdata *ret; ret = (struct areltdata *) bfd_alloc (abfd, sizeof (struct areltdata)); if (ret == NULL) return NULL; if (! xcoff_big_format_p (abfd)) { struct xcoff_ar_hdr hdr; struct xcoff_ar_hdr *hdrp; if (bfd_read ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR) { free (ret); return NULL; } namlen = strtol (hdr.namlen, (char **) NULL, 10); hdrp = (struct xcoff_ar_hdr *) bfd_alloc (abfd, SIZEOF_AR_HDR + namlen + 1); if (hdrp == NULL) { free (ret); return NULL; } memcpy (hdrp, &hdr, SIZEOF_AR_HDR); if (bfd_read ((char *) hdrp + SIZEOF_AR_HDR, 1, namlen, abfd) != namlen) { free (ret); return NULL; } ((char *) hdrp)[SIZEOF_AR_HDR + namlen] = '\0'; ret->arch_header = (char *) hdrp; ret->parsed_size = strtol (hdr.size, (char **) NULL, 10); ret->filename = (char *) hdrp + SIZEOF_AR_HDR; } else { struct xcoff_ar_hdr_big hdr; struct xcoff_ar_hdr_big *hdrp; if (bfd_read ((PTR) &hdr, SIZEOF_AR_HDR_BIG, 1, abfd) != SIZEOF_AR_HDR_BIG) { free (ret); return NULL; } namlen = strtol (hdr.namlen, (char **) NULL, 10); hdrp = (struct xcoff_ar_hdr_big *) bfd_alloc (abfd, SIZEOF_AR_HDR_BIG + namlen + 1); if (hdrp == NULL) { free (ret); return NULL; } memcpy (hdrp, &hdr, SIZEOF_AR_HDR_BIG); if (bfd_read ((char *) hdrp + SIZEOF_AR_HDR_BIG, 1, namlen, abfd) != namlen) { free (ret); return NULL; } ((char *) hdrp)[SIZEOF_AR_HDR_BIG + namlen] = '\0'; ret->arch_header = (char *) hdrp; /* XXX This actually has to be a call to strtoll (at least on 32-bit machines) since the field width is 20 and there numbers with more than 32 bits can be represented. */ ret->parsed_size = strtol (hdr.size, (char **) NULL, 10); ret->filename = (char *) hdrp + SIZEOF_AR_HDR_BIG; } /* Skip over the XCOFFARFMAG at the end of the file name. */ if (bfd_seek (abfd, (namlen & 1) + SXCOFFARFMAG, SEEK_CUR) != 0) return NULL; return (PTR) ret;}/* Open the next element in an XCOFF archive. */bfd *_bfd_xcoff_openr_next_archived_file (archive, last_file) bfd *archive; bfd *last_file;{ file_ptr filestart; if (xcoff_ardata (archive) == NULL) { bfd_set_error (bfd_error_invalid_operation); return NULL; } if (! xcoff_big_format_p (archive)) { if (last_file == NULL) filestart = bfd_ardata (archive)->first_file_filepos; else filestart = strtol (arch_xhdr (last_file)->nextoff, (char **) NULL, 10); if (filestart == 0 || filestart == strtol (xcoff_ardata (archive)->memoff, (char **) NULL, 10) || filestart == strtol (xcoff_ardata (archive)->symoff, (char **) NULL, 10)) { bfd_set_error (bfd_error_no_more_archived_files); return NULL; } } else { if (last_file == NULL) filestart = bfd_ardata (archive)->first_file_filepos; else /* XXX These actually have to be a calls to strtoll (at least on 32-bit machines) since the fields's width is 20 and there numbers with more than 32 bits can be represented. */ filestart = strtol (arch_xhdr_big (last_file)->nextoff, (char **) NULL, 10); /* XXX These actually have to be calls to strtoll (at least on 32-bit machines) since the fields's width is 20 and there numbers with more than 32 bits can be represented. */ if (filestart == 0 || filestart == strtol (xcoff_ardata_big (archive)->memoff, (char **) NULL, 10) || filestart == strtol (xcoff_ardata_big (archive)->symoff, (char **) NULL, 10)) { bfd_set_error (bfd_error_no_more_archived_files); return NULL; } } return _bfd_get_elt_at_filepos (archive, filestart);}/* Stat an element in an XCOFF archive. */int_bfd_xcoff_generic_stat_arch_elt (abfd, s) bfd *abfd; struct stat *s;{ if (abfd->arelt_data == NULL) { bfd_set_error (bfd_error_invalid_operation); return -1; } if (! xcoff_big_format_p (abfd)) { struct xcoff_ar_hdr *hdrp = arch_xhdr (abfd); s->st_mtime = strtol (hdrp->date, (char **) NULL, 10); s->st_uid = strtol (hdrp->uid, (char **) NULL, 10); s->st_gid = strtol (hdrp->gid, (char **) NULL, 10); s->st_mode = strtol (hdrp->mode, (char **) NULL, 8); s->st_size = arch_eltdata (abfd)->parsed_size; } else { struct xcoff_ar_hdr_big *hdrp = arch_xhdr_big (abfd); s->st_mtime = strtol (hdrp->date, (char **) NULL, 10); s->st_uid = strtol (hdrp->uid, (char **) NULL, 10); s->st_gid = strtol (hdrp->gid, (char **) NULL, 10); s->st_mode = strtol (hdrp->mode, (char **) NULL, 8); s->st_size = arch_eltdata (abfd)->parsed_size; } return 0;}/* Normalize a file name for inclusion in an archive. */static const char *normalize_filename (abfd) bfd *abfd;{ const char *file; const char *filename; file = bfd_get_filename (abfd); filename = strrchr (file, '/'); if (filename != NULL) filename++; else filename = file; return filename;}/* Write out an XCOFF armap. */static booleanxcoff_write_armap_old (abfd, elength, map, orl_count, stridx) bfd *abfd; unsigned int elength ATTRIBUTE_UNUSED; struct orl *map; unsigned int orl_count; int stridx;{ struct xcoff_ar_hdr hdr; char *p; unsigned char buf[4]; bfd *sub; file_ptr fileoff; unsigned int i; memset (&hdr, 0, sizeof hdr); sprintf (hdr.size, "%ld", (long) (4 + orl_count * 4 + stridx)); sprintf (hdr.nextoff, "%d", 0); memcpy (hdr.prevoff, xcoff_ardata (abfd)->memoff, 12); sprintf (hdr.date, "%d", 0); sprintf (hdr.uid, "%d", 0); sprintf (hdr.gid, "%d", 0); sprintf (hdr.mode, "%d", 0); sprintf (hdr.namlen, "%d", 0); /* We need spaces, not null bytes, in the header. */ for (p = (char *) &hdr; p < (char *) &hdr + SIZEOF_AR_HDR; p++) if (*p == '\0') *p = ' '; if (bfd_write ((PTR) &hdr, SIZEOF_AR_HDR, 1, abfd) != SIZEOF_AR_HDR || bfd_write (XCOFFARFMAG, 1, SXCOFFARFMAG, abfd) != SXCOFFARFMAG) return false; bfd_h_put_32 (abfd, orl_count, buf); if (bfd_write (buf, 1, 4, abfd) != 4) return false; sub = abfd->archive_head; fileoff = SIZEOF_AR_FILE_HDR; i = 0; while (sub != NULL && i < orl_count) { size_t namlen; while (((bfd *) (map[i]).pos) == sub) { bfd_h_put_32 (abfd, fileoff, buf); if (bfd_write (buf, 1, 4, abfd) != 4) return false; ++i; } namlen = strlen (normalize_filename (sub)); namlen = (namlen + 1) &~ 1; fileoff += (SIZEOF_AR_HDR + namlen + SXCOFFARFMAG + arelt_size (sub)); fileoff = (fileoff + 1) &~ 1; sub = sub->next; } for (i = 0; i < orl_count; i++) { const char *name; size_t namlen; name = *map[i].name; namlen = strlen (name); if (bfd_write (name, 1, namlen + 1, abfd) != namlen + 1) return false; } if ((stridx & 1) != 0) { char b; b = '\0'; if (bfd_write (&b, 1, 1, abfd) != 1) return false; } return true;}/* Write a single armap in the big format. */static booleanxcoff_write_one_armap_big (abfd, map, orl_count, orl_ccount, stridx, bits64, prevoff, nextoff) bfd *abfd; struct orl *map; unsigned int orl_count; unsigned int orl_ccount; unsigned int stridx; int bits64; const char *prevoff; char *nextoff;{ struct xcoff_ar_hdr_big hdr; char *p; unsigned char buf[4]; const bfd_arch_info_type *arch_info = NULL; bfd *sub; file_ptr fileoff; bfd *object_bfd; unsigned int i; memset (&hdr, 0, sizeof hdr); /* XXX This call actually should use %lld (at least on 32-bit machines) since the fields's width is 20 and there numbers with more than 32 bits can be represented. */ sprintf (hdr.size, "%ld", (long) (4 + orl_ccount * 4 + stridx)); if (bits64) sprintf (hdr.nextoff, "%d", 0); else sprintf (hdr.nextoff, "%ld", (strtol (prevoff, (char **) NULL, 10) + 4 + orl_ccount * 4 + stridx)); memcpy (hdr.prevoff, prevoff, sizeof (hdr.prevoff)); sprintf (hdr.date, "%d", 0); sprintf (hdr.uid, "%d", 0); sprintf (hdr.gid, "%d", 0); sprintf (hdr.mode, "%d", 0); sprintf (hdr.namlen, "%d", 0); /* We need spaces, not null bytes, in the header. */ for (p = (char *) &hdr; p < (char *) &hdr + SIZEOF_AR_HDR_BIG; p++) if (*p == '\0') *p = ' '; memcpy (nextoff, hdr.nextoff, sizeof (hdr.nextoff)); if (bfd_write ((PTR) &hdr, SIZEOF_AR_HDR_BIG, 1, abfd) != SIZEOF_AR_HDR_BIG || bfd_write (XCOFFARFMAG, 1, SXCOFFARFMAG, abfd) != SXCOFFARFMAG) return false; bfd_h_put_32 (abfd, orl_ccount, buf); if (bfd_write (buf, 1, 4, abfd) != 4) return false; sub = abfd->archive_head; fileoff = SIZEOF_AR_FILE_HDR_BIG; i = 0; while (sub != NULL && i < orl_count) { size_t namlen; if ((bfd_arch_bits_per_address ((bfd *) map[i].pos) == 64) == bits64) while (((bfd *) (map[i]).pos) == sub) { bfd_h_put_32 (abfd, fileoff, buf); if (bfd_write (buf, 1, 4, abfd) != 4) return false; i++; } else while (((bfd *) (map[i]).pos) == sub) i++; namlen = strlen (normalize_filename (sub)); namlen = (namlen + 1) &~ 1; fileoff += (SIZEOF_AR_HDR_BIG + namlen + SXCOFFARFMAG + arelt_size (sub)); fileoff = (fileoff + 1) &~ 1; sub = sub->next; } object_bfd = NULL; for (i = 0; i < orl_count; i++) { const char *name; size_t namlen; bfd *ob = (bfd *)map[i].pos; if (ob != object_bfd) arch_info = bfd_get_arch_info (ob); if (arch_info && (arch_info->bits_per_address == 64) != bits64) continue; name = *map[i].name; namlen = strlen (name); if (bfd_write (name, 1, namlen + 1, abfd) != namlen + 1) return false; } if ((stridx & 1) != 0) { char b;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?