diff options
Diffstat (limited to 'binutils')
-rw-r--r-- | binutils/MAINTAINERS | 2 | ||||
-rw-r--r-- | binutils/NEWS | 4 | ||||
-rw-r--r-- | binutils/defparse.y | 2 | ||||
-rw-r--r-- | binutils/dlltool.c | 98 | ||||
-rw-r--r-- | binutils/doc/binutils.texi | 25 | ||||
-rw-r--r-- | binutils/dwarf.c | 6 | ||||
-rw-r--r-- | binutils/elfedit.c | 13 | ||||
-rw-r--r-- | binutils/nm.c | 5 | ||||
-rw-r--r-- | binutils/objcopy.c | 121 | ||||
-rw-r--r-- | binutils/objdump.c | 20 | ||||
-rw-r--r-- | binutils/readelf.c | 47 | ||||
-rw-r--r-- | binutils/resbin.c | 10 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/objcopy.exp | 89 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/riscv/property-cfi-lp-unlabeled.d | 8 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/riscv/property-cfi-ss.d | 8 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/riscv/property.s | 41 | ||||
-rw-r--r-- | binutils/testsuite/binutils-all/x86-64/x86-64.exp | 2 |
17 files changed, 432 insertions, 69 deletions
diff --git a/binutils/MAINTAINERS b/binutils/MAINTAINERS index 643a604..14c24af 100644 --- a/binutils/MAINTAINERS +++ b/binutils/MAINTAINERS @@ -63,7 +63,7 @@ maintainer. The first maintainer is free to devolve that responsibility among the other maintainers. AARCH64 Richard Earnshaw <rearnsha@arm.com> - AARCH64 Marcus Shawcroft <marcus.shawcroft@arm.com> + AARCH64 Alice Carlotti <alice.carlotti@arm.com> ARC Claudiu Zissulescu <claziss@gmail.com> ARM Nick Clifton <nickc@redhat.com> ARM Richard Earnshaw <rearnsha@arm.com> diff --git a/binutils/NEWS b/binutils/NEWS index a4599d9..a624106 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -1,5 +1,9 @@ -*- text -*- +* Readelf now recognizes RISC-V GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS and + GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED for zicfiss and zicfilp + extensions. + * For RISC-V dis-assembler, the definition of mapping symbol $x is changed, so the file needs to be rebuilt since 2.45 once used .option arch directives. diff --git a/binutils/defparse.y b/binutils/defparse.y index d50739e..a2c4c4b 100644 --- a/binutils/defparse.y +++ b/binutils/defparse.y @@ -213,7 +213,7 @@ opt_name2: ID { $$ = $1; } } ; opt_name: opt_name2 { $$ =$1; } - | { $$=""; } + | { $$ = xstrdup (""); } ; opt_ordinal: diff --git a/binutils/dlltool.c b/binutils/dlltool.c index ef21423..99c651f 100644 --- a/binutils/dlltool.c +++ b/binutils/dlltool.c @@ -2250,7 +2250,7 @@ typedef struct #define DATA_SEC_FLAGS (SEC_ALLOC | SEC_LOAD | SEC_DATA) #define BSS_SEC_FLAGS SEC_ALLOC -static sinfo secdata[NSECS] = +static sinfo secdata_plain[NSECS] = { INIT_SEC_DATA (TEXT, ".text", TEXT_SEC_FLAGS, 2), INIT_SEC_DATA (DATA, ".data", DATA_SEC_FLAGS, 2), @@ -2261,6 +2261,17 @@ static sinfo secdata[NSECS] = INIT_SEC_DATA (IDATA6, ".idata$6", SEC_HAS_CONTENTS, 1) }; +static sinfo secdata_delay[NSECS] = +{ + INIT_SEC_DATA (TEXT, ".text", TEXT_SEC_FLAGS, 2), + INIT_SEC_DATA (DATA, ".data", DATA_SEC_FLAGS, 2), + INIT_SEC_DATA (BSS, ".bss", BSS_SEC_FLAGS, 2), + INIT_SEC_DATA (IDATA7, ".didat$7", SEC_HAS_CONTENTS, 2), + INIT_SEC_DATA (IDATA5, ".didat$5", SEC_HAS_CONTENTS, 2), + INIT_SEC_DATA (IDATA4, ".didat$4", SEC_HAS_CONTENTS, 2), + INIT_SEC_DATA (IDATA6, ".didat$6", SEC_HAS_CONTENTS, 1) +}; + /* This is what we're trying to make. We generate the imp symbols with both single and double underscores, for compatibility. @@ -2323,6 +2334,7 @@ make_imp_label (bfd *abfd, const char *prefix, const char *name) static bfd * make_one_lib_file (export_type *exp, int i, int delay) { + sinfo *const secdata = delay ? secdata_delay : secdata_plain; char *outname = TMP_STUB; size_t name_len = strlen (outname); sprintf (outname + name_len - 7, "%05d.o", i); @@ -2786,7 +2798,7 @@ make_delay_head (void) /* Output the delay import descriptor */ fprintf (f, "\n%s DELAY_IMPORT_DESCRIPTOR\n", ASM_C); - fprintf (f, ".section\t.text$2\n"); + fprintf (f, ".section\t.didat$2\n"); fprintf (f, "%s __DELAY_IMPORT_DESCRIPTOR_%s\n", ASM_GLOBAL,imp_name_lab); fprintf (f, "__DELAY_IMPORT_DESCRIPTOR_%s:\n", imp_name_lab); fprintf (f, "\t%s 1\t%s grAttrs\n", ASM_LONG, ASM_C); @@ -2814,27 +2826,29 @@ make_delay_head (void) if (!no_idata5) { - fprintf (f, "\t.section\t.idata$5\n"); - /* NULL terminating list. */ - if (create_for_pep) - fprintf (f, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); - else - fprintf (f, "\t%s\t0\n", ASM_LONG); + fprintf (f, "\t.section\t.didat$5\n"); + if (use_nul_prefixed_import_tables) + { + if (create_for_pep) + fprintf (f, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); + else + fprintf (f, "\t%s\t0\n", ASM_LONG); + } fprintf (f, "__IAT_%s:\n", imp_name_lab); } if (!no_idata4) { - fprintf (f, "\t.section\t.idata$4\n"); - fprintf (f, "\t%s\t0\n", ASM_LONG); - if (create_for_pep) - fprintf (f, "\t%s\t0\n", ASM_LONG); - fprintf (f, "\t.section\t.idata$4\n"); + fprintf (f, "\t.section\t.didat$4\n"); + if (use_nul_prefixed_import_tables) + { + fprintf (f, "\t%s\t0\n", ASM_LONG); + if (create_for_pep) + fprintf (f, "\t%s\t0\n", ASM_LONG); + } fprintf (f, "__INT_%s:\n", imp_name_lab); } - fprintf (f, "\t.section\t.idata$2\n"); - fclose (f); assemble_file (TMP_HEAD_S, TMP_HEAD_O); @@ -2900,6 +2914,57 @@ make_tail (void) return abfd; } +static bfd * +make_delay_tail (void) +{ + FILE *f = fopen (TMP_TAIL_S, FOPEN_WT); + bfd *abfd; + + if (f == NULL) + { + fatal (_("failed to open temporary tail file: %s"), TMP_TAIL_S); + return NULL; + } + + temp_file_to_remove[TEMP_TAIL_FILE] = TMP_TAIL_S; + + if (!no_idata4) + { + fprintf (f, "\t.section\t.didat$4\n"); + if (create_for_pep) + fprintf (f, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); + else + fprintf (f, "\t%s\t0\n", ASM_LONG); /* NULL terminating list. */ + } + + if (!no_idata5) + { + fprintf (f, "\t.section\t.didat$5\n"); + if (create_for_pep) + fprintf (f, "\t%s\t0\n\t%s\t0\n", ASM_LONG, ASM_LONG); + else + fprintf (f, "\t%s\t0\n", ASM_LONG); /* NULL terminating list. */ + } + + fprintf (f, "\t.section\t.didat$7\n"); + fprintf (f, "\t%s\t__%s_iname\n", ASM_GLOBAL, imp_name_lab); + fprintf (f, "__%s_iname:\t%s\t\"%s\"\n", + imp_name_lab, ASM_TEXT, dll_name); + + fclose (f); + + assemble_file (TMP_TAIL_S, TMP_TAIL_O); + + abfd = bfd_openr (TMP_TAIL_O, HOW_BFD_READ_TARGET); + if (abfd == NULL) + /* xgettext:c-format */ + fatal (_("failed to open temporary tail file: %s: %s"), + TMP_TAIL_O, bfd_get_errmsg ()); + + temp_file_to_remove[TEMP_TAIL_O_FILE] = TMP_TAIL_O; + return abfd; +} + static void gen_lib_file (int delay) { @@ -2935,12 +3000,13 @@ gen_lib_file (int delay) if (delay) { ar_head = make_delay_head (); + ar_tail = make_delay_tail(); } else { ar_head = make_head (); + ar_tail = make_tail(); } - ar_tail = make_tail(); if (ar_head == NULL || ar_tail == NULL) return; diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index 7f041d9..4543341 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -879,7 +879,7 @@ symbol is defined anywhere, the common symbols are treated as undefined references. @ifclear man For more details on common symbols, see the discussion of ---warn-common in @ref{Options,,Linker options,ld.info,The GNU linker}. +--warn-common in @ref{Options,,Linker options,ld,The GNU linker}. @end ifclear The lower case @var{c} character is used when the symbol is in a special section for small commons. @@ -1362,7 +1362,7 @@ between any two formats may not work as expected. deletes them afterward. @command{objcopy} uses @sc{bfd} to do all its translation work; it has access to all the formats described in @sc{bfd} and thus is able to recognize most formats without being told -explicitly. @xref{BFD,,BFD,ld.info,Using LD}. +explicitly. @xref{BFD,,BFD,ld,Using LD}. @command{objcopy} can be used to generate S-records by using an output target of @samp{srec} (e.g., use @samp{-O srec}). @@ -3566,6 +3566,7 @@ strip [@option{-F} @var{bfdname} |@option{--target=}@var{bfdname}] [@option{--keep-section-symbols}] [@option{--keep-file-symbols}] [@option{--only-keep-debug}] + [@option{--plugin} @var{name}] [@option{-v} |@option{--verbose}] [@option{-V}|@option{--version}] [@option{--help}] [@option{--info}] @var{objfile}@dots{} @@ -3825,6 +3826,26 @@ currently only supports the presence of one filename containing debugging information, not multiple filenames on a one-per-object-file basis. +@item --plugin @var{name} +@cindex plugins +Load the plugin called @var{name} to add support for extra target +types. This option is only available if the toolchain has been built +with plugin support enabled. + +If @option{--plugin} is not provided, but plugin support has been +enabled then @command{strip} iterates over the files in +@file{$@{libdir@}/bfd-plugins} in alphabetic order and the first +plugin that claims the object in question is used. + +Please note that this plugin search directory is @emph{not} the one +used by @command{ld}'s @option{-plugin} option. In order to make +@command{strip} use the linker plugin it must be copied into the +@file{$@{libdir@}/bfd-plugins} directory. For GCC based compilations +the linker plugin is called @file{liblto_plugin.so.0.0.0}. For Clang +based compilations it is called @file{LLVMgold.so}. The GCC plugin +is always backwards compatible with earlier versions, so it is +sufficient to just copy the newest one. + @item -V @itemx --version Show the version number for @command{strip}. diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 5b3ece5..8806cde 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -10930,7 +10930,7 @@ display_debug_links (struct dwarf_section * section, (padding) If needed to reach a 4 byte boundary. (uint32_t) CRC32 value. - The .gun_debugaltlink section is formatted as: + The .gnu_debugaltlink section is formatted as: (c-string) Filename. (binary) Build-ID. */ @@ -12330,7 +12330,7 @@ load_build_id_debug_file (const char * main_filename ATTRIBUTE_UNUSED, void * ma + strlen (".debug") /* The next string should be the same as the longest name found in the prefixes[] array below. */ - + strlen ("/usrlib64/debug/usr") + + strlen ("/usr/lib64/debug/usr/") + 1); void * handle; @@ -12341,7 +12341,7 @@ load_build_id_debug_file (const char * main_filename ATTRIBUTE_UNUSED, void * ma "/usr/lib/debug/", "/usr/lib/debug/usr/", "/usr/lib64/debug/", - "/usr/lib64/debug/usr" + "/usr/lib64/debug/usr/" }; long unsigned int i; diff --git a/binutils/elfedit.c b/binutils/elfedit.c index 1178d8a..43c319f 100644 --- a/binutils/elfedit.c +++ b/binutils/elfedit.c @@ -105,7 +105,18 @@ update_gnu_property (const char *file_name, FILE *file) if (map == MAP_FAILED) { error (_("%s: mmap () failed\n"), file_name); - return 0; + return 1; + } + + if ((elf_header.e_ident[EI_CLASS] == ELFCLASS32 + ? sizeof (Elf32_External_Phdr) + : sizeof (Elf64_External_Phdr)) != elf_header.e_phentsize + || elf_header.e_phoff > (size_t) st_buf.st_size + || (elf_header.e_phnum * (size_t) elf_header.e_phentsize + > st_buf.st_size - elf_header.e_phoff)) + { + error (_("%s: can't read program headers\n"), file_name); + return 1; } phdrs = xmalloc (elf_header.e_phnum * sizeof (*phdrs)); diff --git a/binutils/nm.c b/binutils/nm.c index 7ef5d61..a5d5631 100644 --- a/binutils/nm.c +++ b/binutils/nm.c @@ -801,10 +801,7 @@ filter_symbols (bfd *abfd, bool is_dynamic, void *minisyms, if (sym == NULL) continue; - if (sym->name != NULL - && sym->name[0] == '_' - && sym->name[1] == '_' - && strcmp (sym->name + (sym->name[2] == '_'), "__gnu_lto_slim") == 0 + if (bfd_lto_slim_symbol_p (abfd, sym->name) && report_plugin_err) { report_plugin_err = false; diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 31933e1..2e98ba4 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -30,6 +30,8 @@ #include "coff/internal.h" #include "libcoff.h" #include "safe-ctype.h" +#include "plugin-api.h" +#include "plugin.h" /* FIXME: See bfd/peXXigen.c for why we include an architecture specific header in generic PE code. */ @@ -165,6 +167,11 @@ static struct section_list *change_sections; /* TRUE if some sections are to be removed. */ static bool sections_removed; +#if BFD_SUPPORTS_PLUGINS +/* TRUE if all GCC LTO sections are to be removed. */ +static bool lto_sections_removed; +#endif + /* TRUE if only some sections are to be copied. */ static bool sections_copied; @@ -359,6 +366,7 @@ enum command_line_switch OPTION_RENAME_SECTION, OPTION_REVERSE_BYTES, OPTION_PE_SECTION_ALIGNMENT, + OPTION_PLUGIN, OPTION_SET_SECTION_FLAGS, OPTION_SET_SECTION_ALIGNMENT, OPTION_SET_START, @@ -402,6 +410,7 @@ static struct option strip_options[] = {"output-file", required_argument, 0, 'o'}, {"output-format", required_argument, 0, 'O'}, /* Obsolete */ {"output-target", required_argument, 0, 'O'}, + {"plugin", required_argument, 0, OPTION_PLUGIN}, {"preserve-dates", no_argument, 0, 'p'}, {"remove-section", required_argument, 0, 'R'}, {"remove-relocations", required_argument, 0, OPTION_REMOVE_RELOCS}, @@ -758,6 +767,10 @@ strip_usage (FILE *stream, int exit_status) --info List object formats & architectures supported\n\ -o <file> Place stripped output into <file>\n\ ")); +#if BFD_SUPPORTS_PLUGINS + fprintf (stream, _("\ + --plugin NAME Load the specified plugin\n")); +#endif list_supported_targets (program_name, stream); if (REPORT_BUGS_TO[0] && exit_status == 0) @@ -1916,20 +1929,11 @@ add_redefine_syms_file (const char *filename) Returns TRUE upon success, FALSE otherwise. */ static bool -copy_unknown_object (bfd *ibfd, bfd *obfd) +copy_unknown_file (bfd *ibfd, bfd *obfd, off_t size, unsigned int mode) { char *cbuf; bfd_size_type tocopy; - off_t size; - struct stat buf; - - if (bfd_stat_arch_elt (ibfd, &buf) != 0) - { - bfd_nonfatal_message (NULL, ibfd, NULL, NULL); - return false; - } - size = buf.st_size; if (size < 0) { non_fatal (_("stat returns negative size for `%s'"), @@ -1974,11 +1978,31 @@ copy_unknown_object (bfd *ibfd, bfd *obfd) /* We should at least to be able to read it back when copying an unknown object in an archive. */ - chmod (bfd_get_filename (obfd), buf.st_mode | S_IRUSR); + chmod (bfd_get_filename (obfd), mode | S_IRUSR); free (cbuf); return true; } +/* Copy unknown object file archive member IBFD onto OBFD. + Returns TRUE upon success, FALSE otherwise. */ + +static bool +copy_unknown_object (bfd *ibfd, bfd *obfd) +{ + struct stat buf; + + if (bfd_stat_arch_elt (ibfd, &buf) != 0) + { + bfd_nonfatal_message (NULL, ibfd, NULL, NULL); + return false; + } + + if (!copy_unknown_file (ibfd, obfd, buf.st_size, buf.st_mode)) + return false; + + return true; +} + typedef struct objcopy_internal_note { Elf_Internal_Note note; @@ -3744,6 +3768,12 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target, goto cleanup_and_exit; } +#if BFD_SUPPORTS_PLUGINS + /* Copy LTO IR file as unknown object. */ + if (bfd_plugin_target_p (this_element->xvec)) + ok_object = false; + else +#endif if (ok_object) { ok = copy_object (this_element, output_element, input_arch); @@ -3845,6 +3875,7 @@ copy_file (const char *input_filename, const char *output_filename, int ofd, char **obj_matching; char **core_matching; off_t size = get_file_size (input_filename); + const char *target = input_target; if (size < 1) { @@ -3855,9 +3886,16 @@ copy_file (const char *input_filename, const char *output_filename, int ofd, return; } +#if BFD_SUPPORTS_PLUGINS + /* Enable LTO plugin in strip unless all LTO sections should be + removed. */ + if (is_strip && !target && !lto_sections_removed) + target = "plugin"; +#endif + /* To allow us to do "strip *" without dying on the first non-object file, failures are nonfatal. */ - ibfd = bfd_openr (input_filename, input_target); + ibfd = bfd_openr (input_filename, target); if (ibfd == NULL || bfd_stat (ibfd, in_stat) != 0) { bfd_nonfatal_message (input_filename, NULL, NULL, NULL); @@ -3974,17 +4012,31 @@ copy_file (const char *input_filename, const char *output_filename, int ofd, return; } - if (! copy_object (ibfd, obfd, input_arch)) - status = 1; - - /* PR 17512: file: 0f15796a. - If the file could not be copied it may not be in a writeable - state. So use bfd_close_all_done to avoid the possibility of - writing uninitialised data into the file. */ - if (! (status ? bfd_close_all_done (obfd) : bfd_close (obfd))) +#if BFD_SUPPORTS_PLUGINS + if (bfd_plugin_target_p (ibfd->xvec)) { - status = 1; - bfd_nonfatal_message (output_filename, NULL, NULL, NULL); + /* Copy LTO IR file as unknown file. */ + if (!copy_unknown_file (ibfd, obfd, in_stat->st_size, + in_stat->st_mode)) + status = 1; + else if (!bfd_close_all_done (obfd)) + status = 1; + } + else +#endif + { + if (! copy_object (ibfd, obfd, input_arch)) + status = 1; + + /* PR 17512: file: 0f15796a. + If the file could not be copied it may not be in a writeable + state. So use bfd_close_all_done to avoid the possibility of + writing uninitialised data into the file. */ + if (! (status ? bfd_close_all_done (obfd) : bfd_close (obfd))) + { + status = 1; + bfd_nonfatal_message (output_filename, NULL, NULL, NULL); + } } if (!bfd_close (ibfd)) @@ -4598,6 +4650,7 @@ copy_section (bfd *ibfd, sec_ptr isection, bfd *obfd) char *to = (char *) memhunk; char *end = (char *) memhunk + size; int i; + bfd_size_type memhunk_size = size; /* If the section address is not exactly divisible by the interleave, then we must bias the from address. If the copy_byte is less than @@ -4617,6 +4670,11 @@ copy_section (bfd *ibfd, sec_ptr isection, bfd *obfd) } size = (size + interleave - 1 - copy_byte) / interleave * copy_width; + + /* Don't extend the output section size. */ + if (size > memhunk_size) + size = memhunk_size; + osection->lma /= interleave; if (copy_byte < extra) osection->lma++; @@ -4837,6 +4895,10 @@ strip_main (int argc, char *argv[]) char *output_file = NULL; bool merge_notes_set = false; +#if BFD_SUPPORTS_PLUGINS + bfd_plugin_set_program_name (argv[0]); +#endif + while ((c = getopt_long (argc, argv, "I:O:F:K:MN:R:o:sSpdgxXHhVvwDU", strip_options, (int *) 0)) != EOF) { @@ -4927,6 +4989,13 @@ strip_main (int argc, char *argv[]) case OPTION_KEEP_SECTION_SYMBOLS: keep_section_symbols = true; break; + case OPTION_PLUGIN: /* --plugin */ +#if BFD_SUPPORTS_PLUGINS + bfd_plugin_set_plugin (optarg); +#else + fatal (_("sorry - this program has been built without plugin support\n")); +#endif + break; case 0: /* We've been given a long option. */ break; @@ -4971,6 +5040,14 @@ strip_main (int argc, char *argv[]) if (output_target == NULL) output_target = input_target; +#if BFD_SUPPORTS_PLUGINS + /* Check if all GCC LTO sections should be removed, assuming all LTO + sections will be removed with -R .gnu.lto_.*. * Remove .gnu.lto_.* + sections will also remove .gnu.debuglto_. sections. */ + lto_sections_removed = !!find_section_list (".gnu.lto_.*", false, + SECTION_CONTEXT_REMOVE); +#endif + i = optind; if (i == argc || (output_file != NULL && (i + 1) < argc)) diff --git a/binutils/objdump.c b/binutils/objdump.c index 8fdbe03..43cfb79 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -4206,12 +4206,12 @@ disassemble_data (bfd *abfd) abfd->arch_info = inf; } + const struct bfd_target *old_xvec = NULL; if (endian != BFD_ENDIAN_UNKNOWN) { - struct bfd_target *xvec; - - xvec = (struct bfd_target *) xmalloc (sizeof (struct bfd_target)); - memcpy (xvec, abfd->xvec, sizeof (struct bfd_target)); + struct bfd_target *xvec = xmalloc (sizeof (*xvec)); + old_xvec = abfd->xvec; + memcpy (xvec, old_xvec, sizeof (*xvec)); xvec->byteorder = endian; abfd->xvec = xvec; } @@ -4225,8 +4225,7 @@ disassemble_data (bfd *abfd) non_fatal (_("can't disassemble for architecture %s\n"), bfd_printable_arch_mach (bfd_get_arch (abfd), 0)); exit_status = 1; - free (sorted_syms); - return; + goto out; } disasm_info.flavour = bfd_get_flavour (abfd); @@ -4280,8 +4279,15 @@ disassemble_data (bfd *abfd) free (disasm_info.dynrelbuf); disasm_info.dynrelbuf = NULL; - free (sorted_syms); disassemble_free_target (&disasm_info); + out: + free (sorted_syms); + sorted_syms = NULL; + if (old_xvec) + { + free ((void *) abfd->xvec); + abfd->xvec = old_xvec; + } } static bool diff --git a/binutils/readelf.c b/binutils/readelf.c index dd1871d..f49092f 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -17779,13 +17779,17 @@ display_tag_value (signed int tag, else if (tag & 1) { /* PR 17531 file: 027-19978-0.004. */ - size_t maxlen = (end - p) - 1; + size_t maxlen = end - p; putchar ('"'); if (maxlen > 0) { + maxlen -= 1; /* Remove \0 from the character count. */ print_symbol_name ((int) maxlen, (const char *) p); - p += strnlen ((char *) p, maxlen) + 1; + size_t len = strnlen ((char *) p, maxlen); + if (len == maxlen && p[maxlen] != '\0') + printf (_("<corrupt string tag>")); + p += len + 1; } else { @@ -21288,6 +21292,33 @@ decode_aarch64_feature_1_and (unsigned int bitmask) } static void +decode_riscv_feature_1_and (unsigned int bitmask) +{ + while (bitmask) + { + unsigned int bit = bitmask & (- bitmask); + + bitmask &= ~ bit; + switch (bit) + { + case GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED: + printf ("CFI_LP_UNLABELED"); + break; + + case GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS: + printf ("CFI_SS"); + break; + + default: + printf (_("<unknown: %x>"), bit); + break; + } + if (bitmask) + printf (", "); + } +} + +static void decode_1_needed (unsigned int bitmask) { while (bitmask) @@ -21477,6 +21508,18 @@ print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote) goto next; } } + else if (filedata->file_header.e_machine == EM_RISCV) + { + if (type == GNU_PROPERTY_RISCV_FEATURE_1_AND) + { + printf ("RISC-V AND feature: "); + if (datasz != 4) + printf (_("<corrupt length: %#x> "), datasz); + else + decode_riscv_feature_1_and (byte_get (ptr, 4)); + goto next; + } + } } else { diff --git a/binutils/resbin.c b/binutils/resbin.c index 3bce84f..889126e 100644 --- a/binutils/resbin.c +++ b/binutils/resbin.c @@ -1250,7 +1250,7 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, vst = res_alloc (sizeof (rc_ver_stringtable)); - if (!get_version_header (wrbfd, data, length, (const char *) NULL, + if (!get_version_header (wrbfd, data, length, "version stringtable", &vst->language, &stverlen, &vallen, &type, &off)) return NULL; @@ -1284,9 +1284,9 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, vs = res_alloc (sizeof (rc_ver_stringinfo)); - if (!get_version_header (wrbfd, data, length, - (const char *) NULL, &vs->key, - &sverlen, &vallen, &type, &off)) + if (!get_version_header (wrbfd, data, length, "version string", + &vs->key, &sverlen, &vallen, + &type, &off)) return NULL; data += off; @@ -1348,7 +1348,7 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, data += off; length -= off; - if (!get_version_header (wrbfd, data, length, (const char *) NULL, + if (!get_version_header (wrbfd, data, length, "version varfileinfo", &vi->u.var.key, &verlen, &vallen, &type, &off)) return NULL; diff --git a/binutils/testsuite/binutils-all/objcopy.exp b/binutils/testsuite/binutils-all/objcopy.exp index ff93fea..6aa6d2d 100644 --- a/binutils/testsuite/binutils-all/objcopy.exp +++ b/binutils/testsuite/binutils-all/objcopy.exp @@ -180,7 +180,7 @@ proc objcopy_test_verilog {testname} { untested "verilog width-4 and width-8 tests" return } - + foreach width {4 8} { set got [binutils_run $OBJCOPY "-O verilog --verilog-data-width $width $binfile $verilog-$width.hex"] if ![string equal "" $got] then { @@ -194,7 +194,7 @@ proc objcopy_test_verilog {testname} { } } - # Test generating endian correct output. + # Test generating endian correct output. set testname "objcopy (verilog output endian-ness == input endian-ness)" set got [binutils_run $OBJCOPY "-O verilog --verilog-data-width 4 $binfile $verilog-I4.hex"] if ![string equal "" $got] then { @@ -202,9 +202,9 @@ proc objcopy_test_verilog {testname} { } send_log "regexp_diff $verilog-I4.hex $srcdir/$subdir/verilog-I4.hex\n" if {! [regexp_diff "$verilog-I4.hex" "$srcdir/$subdir/verilog-I4.hex"]} { - pass $testname + pass $testname } else { - fail $testname + fail $testname } } @@ -661,6 +661,87 @@ proc strip_test_with_saving_a_symbol { } { strip_test_with_saving_a_symbol +# Test stripping an archive. + +proc strip_test_archive { } { + global AR + global CC + global STRIP + global srcdir + global subdir + + set test "strip -g on archive" + + if { [target_compile $srcdir/$subdir/testprog.c tmpdir/testprog.o object debug] != "" } { + untested $test + return + } + + set stripobjfile tmpdir/striptestprog.o + set stripobjarchive testprog.o + if [is_remote host] { + set archive libstrip.a + set objfile [remote_download host tmpdir/testprog.o] + remote_file host delete $archive + remote_file host delete $stripobjfile + remote_file host delete $stripobjarchive + } else { + set archive tmpdir/libstrip.a + set objfile tmpdir/testprog.o + remote_file build delete $stripobjfile + remote_file build delete $stripobjarchive + } + + remote_file build delete tmpdir/libstrip.a + + set exec_output [binutils_run $STRIP "-g -o $stripobjfile $objfile"] + set exec_output [prune_warnings $exec_output] + if ![string equal "" $exec_output] { + fail $test + return + } + + set exec_output [binutils_run $AR "rc $archive ${objfile}"] + set exec_output [prune_warnings $exec_output] + if ![string equal "" $exec_output] { + fail $test + return + } + + set exec_output [binutils_run $STRIP "-g $archive"] + set exec_output [prune_warnings $exec_output] + if ![string equal "" $exec_output] { + fail $test + return + } + + set exec_output [binutils_run $AR "x $archive"] + set exec_output [prune_warnings $exec_output] + if ![string equal "" $exec_output] { + fail $test + return + } + + if [is_remote host] { + set stripobjfile [remote_download host $stripobjfile] + set stripobjarchive [remote_download host $stripobjarchive] + } + + send_log "cmp $stripobjarchive $stripobjfile\n" + verbose "cmp $stripobjarchive $stripobjfile" + set status [remote_exec build cmp "$stripobjarchive $stripobjfile"] + set exec_output [lindex $status 1] + set exec_output [prune_warnings $exec_output] + + if [string equal "" $exec_output] then { + pass $test + } else { + fail $test + } +} + +strip_test_archive + # Build a final executable. set exe [exeext] diff --git a/binutils/testsuite/binutils-all/riscv/property-cfi-lp-unlabeled.d b/binutils/testsuite/binutils-all/riscv/property-cfi-lp-unlabeled.d new file mode 100644 index 0000000..396b4cd --- /dev/null +++ b/binutils/testsuite/binutils-all/riscv/property-cfi-lp-unlabeled.d @@ -0,0 +1,8 @@ +#as: -defsym __property_zicfilp_unlabeled__=1 -march=rv64i -mabi=lp64 +#readelf: -n +#source: property.s + +Displaying notes found in: .note.gnu.property +[ ]+Owner[ ]+Data size[ ]+Description +[ ]+GNU[ ]+0x00000010[ ]+NT_GNU_PROPERTY_TYPE_0 +[ ]+Properties: RISC-V AND feature: CFI_LP_UNLABELED diff --git a/binutils/testsuite/binutils-all/riscv/property-cfi-ss.d b/binutils/testsuite/binutils-all/riscv/property-cfi-ss.d new file mode 100644 index 0000000..5bc844a --- /dev/null +++ b/binutils/testsuite/binutils-all/riscv/property-cfi-ss.d @@ -0,0 +1,8 @@ +#as: -defsym __property_zicfiss__=1 -march=rv64i -mabi=lp64 +#readelf: -n +#source: property.s + +Displaying notes found in: .note.gnu.property +[ ]+Owner[ ]+Data size[ ]+Description +[ ]+GNU[ ]+0x00000010[ ]+NT_GNU_PROPERTY_TYPE_0 +[ ]+Properties: RISC-V AND feature: CFI_SS diff --git a/binutils/testsuite/binutils-all/riscv/property.s b/binutils/testsuite/binutils-all/riscv/property.s new file mode 100644 index 0000000..1b62654 --- /dev/null +++ b/binutils/testsuite/binutils-all/riscv/property.s @@ -0,0 +1,41 @@ + .text + .globl _start + .type _start,@function +_start: + ret + +.ifdef __property_zicfilp_unlabeled__ + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align 3 +2: .long 0xc0000000 /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x1 /* GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED. */ +4: + .p2align 3 +5: +.endif + +.ifdef __property_zicfiss__ + .section ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f /* name length */ + .long 5f - 2f /* data length */ + .long 5 /* note type */ +0: .asciz "GNU" /* vendor name */ +1: + .p2align 3 +2: .long 0xc0000000 /* pr_type. */ + .long 4f - 3f /* pr_datasz. */ +3: + .long 0x2 /* GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS. */ +4: + .p2align 3 +5: +.endif diff --git a/binutils/testsuite/binutils-all/x86-64/x86-64.exp b/binutils/testsuite/binutils-all/x86-64/x86-64.exp index 2df0269..05c7304 100644 --- a/binutils/testsuite/binutils-all/x86-64/x86-64.exp +++ b/binutils/testsuite/binutils-all/x86-64/x86-64.exp @@ -81,7 +81,7 @@ if {[catch "system \"bzip2 -dc $t > $tempfile\""] != 0} { fail $testname } else { send_log "cmp tmpdir/pr27708.out $srcdir/$subdir/pr27708.dump\n" - verbose "cmp tmpdir/pr27708.out $srcdir/$subdir/pr26808.dump" 1 + verbose "cmp tmpdir/pr27708.out $srcdir/$subdir/pr27708.dump" 1 set status [remote_exec build cmp "tmpdir/pr27708.out $srcdir/$subdir/pr27708.dump"] set exec_output [lindex $status 1] set exec_output [prune_warnings $exec_output] |