aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
Diffstat (limited to 'binutils')
-rw-r--r--binutils/MAINTAINERS2
-rw-r--r--binutils/NEWS4
-rw-r--r--binutils/defparse.y2
-rw-r--r--binutils/dlltool.c98
-rw-r--r--binutils/doc/binutils.texi25
-rw-r--r--binutils/dwarf.c6
-rw-r--r--binutils/elfedit.c13
-rw-r--r--binutils/nm.c5
-rw-r--r--binutils/objcopy.c121
-rw-r--r--binutils/objdump.c20
-rw-r--r--binutils/readelf.c47
-rw-r--r--binutils/resbin.c10
-rw-r--r--binutils/testsuite/binutils-all/objcopy.exp89
-rw-r--r--binutils/testsuite/binutils-all/riscv/property-cfi-lp-unlabeled.d8
-rw-r--r--binutils/testsuite/binutils-all/riscv/property-cfi-ss.d8
-rw-r--r--binutils/testsuite/binutils-all/riscv/property.s41
-rw-r--r--binutils/testsuite/binutils-all/x86-64/x86-64.exp2
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]