archive.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,234 行 · 第 1/5 页
C
2,234 行
if (tmp->arch_header[0] == '/' && tmp->arch_header[1] == ' ') { ardata->first_file_filepos += (tmp->parsed_size + sizeof (struct ar_hdr) + 1) & ~1; } bfd_release (abfd, tmp); } } return true;release_raw_armap: bfd_release (abfd, (PTR) raw_armap);release_symdefs: bfd_release (abfd, (PTR) (ardata)->symdefs); return false;}/* This routine can handle either coff-style or bsd-style armaps. Returns false on error, true otherwise */booleanbfd_slurp_armap (abfd) bfd *abfd;{ char nextname[17]; int i = bfd_read ((PTR) nextname, 1, 16, abfd); if (i == 0) return true; if (i != 16) return false; if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0) return false; if (!strncmp (nextname, "__.SYMDEF ", 16) || !strncmp (nextname, "__.SYMDEF/ ", 16)) /* old Linux archives */ return do_slurp_bsd_armap (abfd); else if (!strncmp (nextname, "/ ", 16)) return do_slurp_coff_armap (abfd); else if (!strncmp (nextname, "/SYM64/ ", 16)) { /* Irix 6 archive--must be recognized by code in elf64-mips.c. */ bfd_set_error (bfd_error_wrong_format); return false; } bfd_has_map (abfd) = false; return true;}/* Returns false on error, true otherwise *//* flavor 2 of a bsd armap, similar to bfd_slurp_bsd_armap except the header is in a slightly different order and the map name is '/'. This flavour is used by hp300hpux. */#define HPUX_SYMDEF_COUNT_SIZE 2booleanbfd_slurp_bsd_armap_f2 (abfd) bfd *abfd;{ struct areltdata *mapdata; char nextname[17]; unsigned int counter; bfd_byte *raw_armap, *rbase; struct artdata *ardata = bfd_ardata (abfd); char *stringbase; unsigned int stringsize; carsym *set; int i = bfd_read ((PTR) nextname, 1, 16, abfd); if (i == 0) return true; if (i != 16) return false; /* The archive has at least 16 bytes in it. */ if (bfd_seek (abfd, -16L, SEEK_CUR) != 0) return false; if (!strncmp (nextname, "__.SYMDEF ", 16) || !strncmp (nextname, "__.SYMDEF/ ", 16)) /* old Linux archives */ return do_slurp_bsd_armap (abfd); if (strncmp (nextname, "/ ", 16)) { bfd_has_map (abfd) = false; return true; } mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd); if (mapdata == NULL) return false; raw_armap = (bfd_byte *) bfd_zalloc (abfd, mapdata->parsed_size); if (raw_armap == NULL) { byebye: bfd_release (abfd, (PTR) mapdata); return false; } if (bfd_read ((PTR) raw_armap, 1, mapdata->parsed_size, abfd) != mapdata->parsed_size) { if (bfd_get_error () != bfd_error_system_call) bfd_set_error (bfd_error_malformed_archive); byebyebye: bfd_release (abfd, (PTR) raw_armap); goto byebye; } ardata->symdef_count = bfd_h_get_16 (abfd, (PTR) raw_armap); if (ardata->symdef_count * BSD_SYMDEF_SIZE > mapdata->parsed_size - HPUX_SYMDEF_COUNT_SIZE) { /* Probably we're using the wrong byte ordering. */ bfd_set_error (bfd_error_wrong_format); goto byebyebye; } ardata->cache = 0; stringsize = bfd_h_get_32 (abfd, raw_armap + HPUX_SYMDEF_COUNT_SIZE); /* Skip sym count and string sz. */ stringbase = ((char *) raw_armap + HPUX_SYMDEF_COUNT_SIZE + BSD_STRING_COUNT_SIZE); rbase = (bfd_byte *) stringbase + stringsize; ardata->symdefs = (carsym *) bfd_alloc (abfd, (ardata->symdef_count * BSD_SYMDEF_SIZE)); if (!ardata->symdefs) return false; for (counter = 0, set = ardata->symdefs; counter < ardata->symdef_count; counter++, set++, rbase += BSD_SYMDEF_SIZE) { set->name = bfd_h_get_32 (abfd, rbase) + stringbase; set->file_offset = bfd_h_get_32 (abfd, rbase + BSD_SYMDEF_OFFSET_SIZE); } ardata->first_file_filepos = bfd_tell (abfd); /* Pad to an even boundary if you have to. */ ardata->first_file_filepos += (ardata->first_file_filepos) % 2; /* FIXME, we should provide some way to free raw_ardata when we are done using the strings from it. For now, it seems to be allocated on an objalloc anyway... */ bfd_has_map (abfd) = true; return true;}/** Extended name table. Normally archives support only 14-character filenames. Intel has extended the format: longer names are stored in a special element (the first in the archive, or second if there is an armap); the name in the ar_hdr is replaced by <space><index into filename element>. Index is the P.R. of an int (decimal). Data General have extended the format by using the prefix // for the special element. *//* Returns false on error, true otherwise. */boolean_bfd_slurp_extended_name_table (abfd) bfd *abfd;{ char nextname[17]; struct areltdata *namedata; /* FIXME: Formatting sucks here, and in case of failure of BFD_READ, we probably don't want to return true. */ bfd_seek (abfd, bfd_ardata (abfd)->first_file_filepos, SEEK_SET); if (bfd_read ((PTR) nextname, 1, 16, abfd) == 16) { if (bfd_seek (abfd, (file_ptr) - 16, SEEK_CUR) != 0) return false; if (strncmp (nextname, "ARFILENAMES/ ", 16) != 0 && strncmp (nextname, "// ", 16) != 0) { bfd_ardata (abfd)->extended_names = NULL; return true; } namedata = (struct areltdata *) _bfd_read_ar_hdr (abfd); if (namedata == NULL) return false; bfd_ardata (abfd)->extended_names = bfd_zalloc (abfd, namedata->parsed_size); if (bfd_ardata (abfd)->extended_names == NULL) { byebye: bfd_release (abfd, (PTR) namedata); return false; } if (bfd_read ((PTR) bfd_ardata (abfd)->extended_names, 1, namedata->parsed_size, abfd) != namedata->parsed_size) { if (bfd_get_error () != bfd_error_system_call) bfd_set_error (bfd_error_malformed_archive); bfd_release (abfd, (PTR) (bfd_ardata (abfd)->extended_names)); bfd_ardata (abfd)->extended_names = NULL; goto byebye; } /* Since the archive is supposed to be printable if it contains text, the entries in the list are newline-padded, not null padded. In SVR4-style archives, the names also have a trailing '/'. DOS/NT created archive often have \ in them We'll fix all problems here.. */ { char *temp = bfd_ardata (abfd)->extended_names; char *limit = temp + namedata->parsed_size; for (; temp < limit; ++temp) { if (*temp == '\012') temp[temp[-1] == '/' ? -1 : 0] = '\0'; if (*temp == '\\') *temp = '/'; } } /* Pad to an even boundary if you have to. */ bfd_ardata (abfd)->first_file_filepos = bfd_tell (abfd); bfd_ardata (abfd)->first_file_filepos += (bfd_ardata (abfd)->first_file_filepos) % 2; /* FIXME, we can't release namedata here because it was allocated below extended_names on the objalloc... */#if 0 bfd_release (abfd, namedata);#endif } return true;}#ifdef VMS/* Return a copy of the stuff in the filename between any :]> and a semicolon. */static const char *normalize (abfd, file) bfd *abfd; const char *file;{ CONST char *first; CONST char *last; char *copy; first = file + strlen (file) - 1; last = first + 1; while (first != file) { if (*first == ';') last = first; if (*first == ':' || *first == ']' || *first == '>') { first++; break; } first--; } copy = (char *) bfd_alloc (abfd, last - first + 1); if (copy == NULL) return NULL; memcpy (copy, first, last - first); copy[last - first] = 0; return copy;}#elsestatic const char *normalize (abfd, file) bfd *abfd ATTRIBUTE_UNUSED; const char *file;{ const char *filename = strrchr (file, '/');#ifdef HAVE_DOS_BASED_FILE_SYSTEM { /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */ char *bslash = strrchr (file, '\\'); if (filename == NULL || (bslash != NULL && bslash > filename)) filename = bslash; if (filename == NULL && file[0] != '\0' && file[1] == ':') filename = file + 1; }#endif if (filename != (char *) NULL) filename++; else filename = file; return filename;}#endif/* Build a BFD style extended name table. */boolean_bfd_archive_bsd_construct_extended_name_table (abfd, tabloc, tablen, name) bfd *abfd; char **tabloc; bfd_size_type *tablen; const char **name;{ *name = "ARFILENAMES/"; return _bfd_construct_extended_name_table (abfd, false, tabloc, tablen);}/* Build an SVR4 style extended name table. */boolean_bfd_archive_coff_construct_extended_name_table (abfd, tabloc, tablen, name) bfd *abfd; char **tabloc; bfd_size_type *tablen; const char **name;{ *name = "//"; return _bfd_construct_extended_name_table (abfd, true, tabloc, tablen);}/* Follows archive_head and produces an extended name table if necessary. Returns (in tabloc) a pointer to an extended name table, and in tablen the length of the table. If it makes an entry it clobbers the filename so that the element may be written without further massage. Returns true if it ran successfully, false if something went wrong. A successful return may still involve a zero-length tablen! */boolean_bfd_construct_extended_name_table (abfd, trailing_slash, tabloc, tablen) bfd *abfd; boolean trailing_slash; char **tabloc; bfd_size_type *tablen;{ unsigned int maxname = abfd->xvec->ar_max_namelen; unsigned int total_namelen = 0; bfd *current; char *strptr; *tablen = 0; /* Figure out how long the table should be. */ for (current = abfd->archive_head; current != NULL; current = current->next) { const char *normal; unsigned int thislen; normal = normalize (current, current->filename); if (normal == NULL) return false; thislen = strlen (normal); if (thislen > maxname && (bfd_get_file_flags (abfd) & BFD_TRADITIONAL_FORMAT) != 0) thislen = maxname; if (thislen > maxname) { /* Add one to leave room for \n. */ total_namelen += thislen + 1; if (trailing_slash) { /* Leave room for trailing slash. */ ++total_namelen; } } else { struct ar_hdr *hdr = arch_hdr (current); if (strncmp (normal, hdr->ar_name, thislen) != 0 || (thislen < sizeof hdr->ar_name && hdr->ar_name[thislen] != ar_padchar (current))) { /* Must have been using extended format even though it didn't need to. Fix it to use normal format. */ memcpy (hdr->ar_name, normal, thislen); if (thislen < maxname || (thislen == maxname && thislen < sizeof hdr->ar_name)) hdr->ar_name[thislen] = ar_padchar (current); } } } if (total_namelen == 0) return true; *tabloc = bfd_zalloc (abfd, total_namelen); if (*tabloc == NULL) return false; *tablen = total_namelen; strptr = *tabloc; for (current = abfd->archive_head; current != NULL; current = current->next) { const char *normal; unsigned int thislen; normal = normalize (current, current->filename); if (normal == NULL) return false; thislen = strlen (normal); if (thislen > maxname) { /* Works for now; may need to be re-engineered if we encounter an oddball archive format and want to generalise this hack. */ struct ar_hdr *hdr = arch_hdr (current); strcpy (strptr, normal); if (! trailing_slash) strptr[thislen] = '\012'; else { strptr[thislen] = '/'; strptr[thislen + 1] = '\012'; } hdr->ar_name[0] = ar_padchar (current); /* We know there will always be enough room (one of the few cases where you may safely use sprintf). */ sprintf ((hdr->ar_name) + 1, "%-d", (unsigned) (strptr - *tabloc)); /* Kinda Kludgy. We should just use the returned value of sprintf but not all implementations get this right. */ { char *temp = hdr->ar_name + 2; for (; temp < hdr->ar_name + maxname; temp++) if (*temp == '\0') *temp = ' ';
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?