aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.pre-commit-config.yaml2
-rw-r--r--bfd/aout-target.h4
-rw-r--r--bfd/aoutx.h9
-rw-r--r--bfd/coffgen.c18
-rw-r--r--bfd/cofflink.c47
-rw-r--r--bfd/elflink.c11
-rw-r--r--bfd/elfxx-aarch64.c32
-rw-r--r--bfd/elfxx-x86.c20
-rw-r--r--bfd/format.c45
-rw-r--r--bfd/i386aout.c1
-rw-r--r--bfd/libaout.h7
-rw-r--r--bfd/pdp11.c9
-rw-r--r--bfd/version.h2
-rw-r--r--binutils/doc/binutils.texi8
-rw-r--r--binutils/resbin.c768
-rw-r--r--binutils/rescoff.c288
-rw-r--r--binutils/resrc.c9
-rw-r--r--binutils/resres.c42
-rw-r--r--binutils/windres.c30
-rw-r--r--binutils/windres.h6
-rw-r--r--gas/config/loongarch-parse.y32
-rw-r--r--gas/config/tc-m68k.c15
-rw-r--r--gas/testsuite/gas/loongarch/fix_op.d3
-rw-r--r--gas/testsuite/gas/loongarch/fix_op.s5
-rw-r--r--gas/testsuite/gas/loongarch/insn_alias_32.d3
-rw-r--r--gas/testsuite/gas/loongarch/insn_alias_32.s5
-rw-r--r--gdb/MAINTAINERS1
-rw-r--r--gdb/ada-lang.c115
-rw-r--r--gdb/ada-varobj.c14
-rw-r--r--gdb/cli/cli-decode.h2
-rw-r--r--gdb/cli/cli-dump.c2
-rw-r--r--gdb/config/djgpp/README2
-rw-r--r--gdb/config/djgpp/djconfig.sh2
-rwxr-xr-xgdb/copyright.py101
-rw-r--r--gdb/corelow.c38
-rw-r--r--gdb/dwarf2/comp-unit-head.c23
-rw-r--r--gdb/dwarf2/comp-unit-head.h7
-rw-r--r--gdb/dwarf2/read.c225
-rw-r--r--gdb/dwarf2/read.h36
-rw-r--r--gdb/dwarf2/section.h13
-rw-r--r--gdb/maint.h3
-rw-r--r--gdb/python/py-value.c3
-rw-r--r--gdb/testsuite/gdb.ada/scalar_storage.exp28
-rw-r--r--gdb/testsuite/gdb.arch/aarch64-sve-sigunwind.c205
-rw-r--r--gdb/testsuite/gdb.arch/aarch64-sve-sigunwind.exp106
-rw-r--r--gdb/testsuite/gdb.base/bg-execution-repeat.c2
-rw-r--r--gdb/testsuite/gdb.base/corefile3.c118
-rw-r--r--gdb/testsuite/gdb.base/corefile3.exp71
-rw-r--r--gdb/testsuite/gdb.base/dlmopen-ns-ids.exp20
-rw-r--r--gdb/testsuite/gdb.base/printcmds.exp7
-rw-r--r--gdb/testsuite/gdb.cp/cplusfuncs.exp3
-rw-r--r--gdb/testsuite/gdb.dwarf2/fission-with-type-unit.exp4
-rw-r--r--gdb/testsuite/gdb.threads/clone-attach-detach.exp2
-rw-r--r--gdb/unittests/rsp-low-selftests.c2
-rw-r--r--gdb/valops.c28
-rw-r--r--gdb/value.h5
-rw-r--r--gprofng/src/gp-archive.cc3
-rw-r--r--gprofng/src/gp-collect-app.cc3
-rw-r--r--gprofng/src/gp-display-src.cc3
-rw-r--r--gprofng/src/gp-display-text.cc3
-rw-r--r--gprofng/src/gprofng.cc3
-rw-r--r--ld/emultempl/pe.em13
-rw-r--r--ld/emultempl/pep.em19
-rw-r--r--ld/ld.texi11
-rw-r--r--ld/ldmain.c6
-rw-r--r--ld/testsuite/ld-aarch64/protections/bti-and-memory-seal-plt-1-a.d45
-rw-r--r--ld/testsuite/ld-aarch64/protections/bti-and-memory-seal-plt-1-b.d14
-rw-r--r--ld/testsuite/ld-aarch64/protections/bti-plt-1-b.d2
-rw-r--r--ld/testsuite/ld-plugin/lto.exp32
-rw-r--r--ld/testsuite/ld-plugin/pr32846a.c6
-rw-r--r--ld/testsuite/ld-plugin/pr32846b.c4
-rw-r--r--ld/testsuite/ld-plugin/pr32846c.c6
-rw-r--r--ld/testsuite/ld-plugin/pr32846d.c12
-rw-r--r--ld/testsuite/ld-plugin/pr32846e.c4
-rw-r--r--opcodes/i386-gen.c4
-rw-r--r--opcodes/i386-init.h30
-rw-r--r--opcodes/i386-opc.h12
-rw-r--r--opcodes/i386-tbl.h16
-rw-r--r--opcodes/loongarch-opc.c6
-rw-r--r--opcodes/riscv-dis.c6
80 files changed, 2026 insertions, 846 deletions
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 488e781..f432d51 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -69,7 +69,7 @@ repos:
rev: v2.4.1
hooks:
- id: codespell
- files: '^(gdbsupport|gdbserver|gdb/(tui|target|data-directory|po|system-gdbinit|mi|syscalls|arch|regformats|compile|python|guile))/'
+ files: '^(gdbsupport|gdbserver|gdb/(tui|target|data-directory|po|system-gdbinit|mi|syscalls|arch|regformats|compile|python|guile|config|unittests|cli))/'
args: [--config, gdb/contrib/setup.cfg]
- repo: local
hooks:
diff --git a/bfd/aout-target.h b/bfd/aout-target.h
index f513e1b..1b71104 100644
--- a/bfd/aout-target.h
+++ b/bfd/aout-target.h
@@ -286,9 +286,6 @@ MY (set_sizes) (bfd *abfd)
#ifndef MY_add_dynamic_symbols
#define MY_add_dynamic_symbols 0
#endif
-#ifndef MY_add_one_symbol
-#define MY_add_one_symbol 0
-#endif
#ifndef MY_link_dynamic_object
#define MY_link_dynamic_object 0
#endif
@@ -312,7 +309,6 @@ static const struct aout_backend_data MY (backend_data) =
MY_set_sizes,
MY_exec_header_not_counted,
MY_add_dynamic_symbols,
- MY_add_one_symbol,
MY_link_dynamic_object,
MY_write_dynamic_symbol,
MY_check_dynamic_reloc,
diff --git a/bfd/aoutx.h b/bfd/aoutx.h
index 63c654f..81e0804 100644
--- a/bfd/aoutx.h
+++ b/bfd/aoutx.h
@@ -2973,9 +2973,6 @@ NAME (aout, link_hash_table_create) (bfd *abfd)
static bool
aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
{
- bool (*add_one_symbol)
- (struct bfd_link_info *, bfd *, const char *, flagword, asection *,
- bfd_vma, const char *, bool, bool, struct bfd_link_hash_entry **);
struct external_nlist *syms;
bfd_size_type sym_count;
char *strings;
@@ -3013,10 +3010,6 @@ aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
return false;
obj_aout_sym_hashes (abfd) = sym_hash;
- add_one_symbol = aout_backend_info (abfd)->add_one_symbol;
- if (add_one_symbol == NULL)
- add_one_symbol = _bfd_generic_link_add_one_symbol;
-
p = syms;
pend = p + sym_count;
for (; p < pend; p++, sym_hash++)
@@ -3167,7 +3160,7 @@ aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
break;
}
- if (! ((*add_one_symbol)
+ if (! (_bfd_generic_link_add_one_symbol
(info, abfd, name, flags, section, value, string, copy, false,
(struct bfd_link_hash_entry **) sym_hash)))
return false;
diff --git a/bfd/coffgen.c b/bfd/coffgen.c
index f87e54f..ab4d790 100644
--- a/bfd/coffgen.c
+++ b/bfd/coffgen.c
@@ -42,6 +42,7 @@
#include "libbfd.h"
#include "coff/internal.h"
#include "libcoff.h"
+#include "elf-bfd.h"
#include "hashtab.h"
/* Extract a long section name at STRINDEX and copy it to the bfd objstack.
@@ -1270,9 +1271,24 @@ coff_write_alien_symbol (bfd *abfd,
if (c != (coff_symbol_type *) NULL)
native->u.syment.n_flags = bfd_asymbol_bfd (&c->symbol)->flags;
}
+
+ const elf_symbol_type *elfsym = elf_symbol_from (symbol);
+ if (elfsym
+ && (symbol->flags & BSF_FUNCTION)
+ && elfsym->internal_elf_sym.st_size)
+ {
+ /* coff_data (abfd)->local_n_btshft is what ought to be used here,
+ just that it's set only when reading in COFF objects. */
+ native->u.syment.n_type = DT_FCN << 4;
+ native->u.syment.n_numaux = 1;
+ native[1].u.auxent.x_sym.x_misc.x_fsize
+ = elfsym->internal_elf_sym.st_size;
+ /* FIXME .u.auxent.x_sym.x_fcnary.x_fcn.x_endndx would better also
+ be set, which would require updating the field once the next
+ function is seen. */
+ }
}
- native->u.syment.n_type = 0;
if (symbol->flags & BSF_FILE)
native->u.syment.n_sclass = C_FILE;
else if (symbol->flags & BSF_LOCAL)
diff --git a/bfd/cofflink.c b/bfd/cofflink.c
index 501731b..38278e2 100644
--- a/bfd/cofflink.c
+++ b/bfd/cofflink.c
@@ -27,6 +27,7 @@
#include "libbfd.h"
#include "coff/internal.h"
#include "libcoff.h"
+#include "elf-bfd.h"
#include "safe-ctype.h"
static bool coff_link_add_object_symbols (bfd *, struct bfd_link_info *);
@@ -931,14 +932,52 @@ _bfd_coff_final_link (bfd *abfd,
bfd_vma written = 0;
bool rewrite = false;
- if (! (sym->flags & BSF_LOCAL)
- || (sym->flags & (BSF_SECTION_SYM | BSF_DEBUGGING_RELOC
- | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC
- | BSF_SYNTHETIC))
+ if ((sym->flags & (BSF_SECTION_SYM | BSF_DEBUGGING_RELOC
+ | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC
+ | BSF_SYNTHETIC))
|| ((sym->flags & BSF_DEBUGGING)
&& ! (sym->flags & BSF_FILE)))
continue;
+ if (! (sym->flags & BSF_LOCAL))
+ {
+ /* For ELF symbols try to represent their function-ness and
+ size, if available. */
+ if (! (sym->flags & BSF_FUNCTION))
+ continue;
+
+ const elf_symbol_type *elfsym = elf_symbol_from (sym);
+ if (!elfsym)
+ continue;
+
+ struct coff_link_hash_entry *hent
+ = (struct coff_link_hash_entry *) bfd_hash_lookup
+ (&info->hash->table, bfd_asymbol_name (sym),
+ false, false);
+ if (!hent)
+ continue;
+
+ /* coff_data (abfd)->local_n_btshft is what ought to be used
+ here, just that it's set only when reading in COFF
+ objects. */
+ hent->type = DT_FCN << 4;
+ if (!elfsym->internal_elf_sym.st_size)
+ continue;
+
+ hent->aux = bfd_zalloc (abfd, sizeof (*hent->aux));
+ if (!hent->aux)
+ continue;
+
+ hent->numaux = 1;
+ hent->aux->x_sym.x_misc.x_fsize
+ = elfsym->internal_elf_sym.st_size;
+ /* FIXME ->x_sym.x_fcnary.x_fcn.x_endndx would better
+ also be set, yet that would likely need to happen
+ elsewhere anyway. */
+
+ continue;
+ }
+
/* See if we are discarding symbols with this name. */
if ((flaginfo.info->strip == strip_some
&& (bfd_hash_lookup (flaginfo.info->keep_hash,
diff --git a/bfd/elflink.c b/bfd/elflink.c
index a76e8e3..919f2a7 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -6290,8 +6290,8 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
continue;
/* In the pre-LTO-plugin pass we must not mistakenly
- include this archive member if an earlier BFD
- defined this symbol. */
+ include this archive member if an earlier shared
+ library defined this symbol. */
struct elf_link_hash_table *htab = elf_hash_table (info);
if (htab->first_hash)
{
@@ -6299,7 +6299,9 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
= ((struct elf_link_first_hash_entry *)
bfd_hash_lookup (htab->first_hash, symdef->name,
false, false));
- if (e && e->abfd != abfd)
+ if (e
+ && (e->abfd->flags & DYNAMIC) != 0
+ && e->abfd != abfd)
continue;
}
}
@@ -14408,7 +14410,8 @@ elf_gc_sweep (bfd *abfd, struct bfd_link_info *info)
if (o->flags & SEC_GROUP)
{
asection *first = elf_next_in_group (o);
- o->gc_mark = first->gc_mark;
+ if (first != NULL)
+ o->gc_mark = first->gc_mark;
}
if (o->gc_mark)
diff --git a/bfd/elfxx-aarch64.c b/bfd/elfxx-aarch64.c
index 45a0205..68e004ef 100644
--- a/bfd/elfxx-aarch64.c
+++ b/bfd/elfxx-aarch64.c
@@ -930,28 +930,20 @@ _bfd_aarch64_elf_link_setup_gnu_properties (struct bfd_link_info *info)
GNU properties (if found). */
bfd *pbfd = _bfd_elf_link_setup_gnu_properties (info);
- /* If pbfd has any GNU_PROPERTY_AARCH64_FEATURE_1_AND properties, update
- outprop accordingly. */
if (pbfd != NULL)
{
- /* The property list is sorted in order of type. */
- for (elf_property_list *p = elf_properties (pbfd);
- (p != NULL)
- && (GNU_PROPERTY_AARCH64_FEATURE_1_AND <= p->property.pr_type);
- p = p->next)
- {
- /* This merge of features should happen only once as all the identical
- properties are supposed to have been merged at this stage by
- _bfd_elf_link_setup_gnu_properties(). */
- if (p->property.pr_type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
- {
- outprop = (p->property.u.number
- & (GNU_PROPERTY_AARCH64_FEATURE_1_BTI
- | GNU_PROPERTY_AARCH64_FEATURE_1_PAC
- | GNU_PROPERTY_AARCH64_FEATURE_1_GCS));
- break;
- }
- }
+ elf_property_list *p;
+ elf_property_list *plist = elf_properties (pbfd);
+
+ /* If pbfd has any GNU_PROPERTY_AARCH64_FEATURE_1_AND properties, update
+ outprop accordingly. */
+ if ((p = _bfd_elf_find_property (plist,
+ GNU_PROPERTY_AARCH64_FEATURE_1_AND, NULL))
+ != NULL)
+ outprop = p->property.u.number
+ & (GNU_PROPERTY_AARCH64_FEATURE_1_BTI
+ | GNU_PROPERTY_AARCH64_FEATURE_1_PAC
+ | GNU_PROPERTY_AARCH64_FEATURE_1_GCS);
}
tdata->gnu_property_aarch64_feature_1_and = outprop;
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 6ea41f2..bc9bb70 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -609,8 +609,7 @@ _bfd_elf_x86_get_local_sym_hash (struct elf_x86_link_hash_table *htab,
return &ret->elf;
}
-/* Create an entry in a x86 ELF linker hash table. NB: THIS MUST BE IN
- SYNC WITH _bfd_elf_link_hash_newfunc. */
+/* Create an entry in an x86 ELF linker hash table. */
struct bfd_hash_entry *
_bfd_x86_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
@@ -629,27 +628,14 @@ _bfd_x86_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
}
/* Call the allocation method of the superclass. */
- entry = _bfd_link_hash_newfunc (entry, table, string);
+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
if (entry != NULL)
{
struct elf_x86_link_hash_entry *eh
= (struct elf_x86_link_hash_entry *) entry;
- struct elf_link_hash_table *htab
- = (struct elf_link_hash_table *) table;
- memset (&eh->elf.size, 0,
- (sizeof (struct elf_x86_link_hash_entry)
- - offsetof (struct elf_link_hash_entry, size)));
+ memset (&eh->elf + 1, 0, sizeof (*eh) - sizeof (eh->elf));
/* Set local fields. */
- eh->elf.indx = -1;
- eh->elf.dynindx = -1;
- eh->elf.got = htab->init_got_refcount;
- eh->elf.plt = htab->init_plt_refcount;
- /* Assume that we have been called by a non-ELF symbol reader.
- This flag is then reset by the code which reads an ELF input
- file. This ensures that a symbol created by a non-ELF symbol
- reader will have the flag set correctly. */
- eh->elf.non_elf = 1;
eh->plt_second.offset = (bfd_vma) -1;
eh->plt_got.offset = (bfd_vma) -1;
eh->tlsdesc_got = (bfd_vma) -1;
diff --git a/bfd/format.c b/bfd/format.c
index 7769ad0..a909b70 100644
--- a/bfd/format.c
+++ b/bfd/format.c
@@ -331,6 +331,25 @@ print_and_clear_messages (struct per_xvec_messages *list,
free (iter);
iter = next;
}
+
+ /* Don't retain a pointer to free'd memory. */
+ list->next = NULL;
+}
+
+/* Discard all messages associated with TARG in LIST. Unlike
+ print_and_clear_messages, PER_XVEC_NO_TARGET is not valid for TARG. */
+
+static void
+clear_messages (struct per_xvec_messages *list,
+ const bfd_target *targ)
+{
+ struct per_xvec_messages *iter;
+
+ for (iter = list; iter != NULL; iter = iter->next)
+ {
+ if (iter->targ == targ)
+ clear_warnmsg (&iter->messages);
+ }
}
/* This a copy of lto_section defined in GCC (lto-streamer.h). */
@@ -451,7 +470,18 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
/* Avoid clashes with bfd_cache_close_all running in another
thread. */
if (!bfd_cache_set_uncloseable (abfd, true, &old_in_format_matches))
- return false;
+ {
+ free (matching_vector);
+ return false;
+ }
+
+ /* Locking is required here in order to manage _bfd_section_id. */
+ if (!bfd_lock ())
+ {
+ bfd_cache_set_uncloseable (abfd, old_in_format_matches, NULL);
+ free (matching_vector);
+ return false;
+ }
/* Presume the answer is yes. */
abfd->format = format;
@@ -461,10 +491,6 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
of an archive. */
orig_messages = _bfd_set_error_handler_caching (&messages);
- /* Locking is required here in order to manage _bfd_section_id. */
- if (!bfd_lock ())
- return false;
-
preserve_match.marker = NULL;
if (!bfd_preserve_save (abfd, &preserve, NULL))
goto err_ret;
@@ -545,6 +571,12 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
/* Change BFD's target temporarily. */
abfd->xvec = *target;
+ /* It is possible that targets appear multiple times in
+ bfd_target_vector. If this is the case, then we want to avoid
+ accumulating duplicate messages for a target in MESSAGES, so
+ discard any previous messages associated with this target. */
+ clear_messages (&messages, abfd->xvec);
+
if (bfd_seek (abfd, 0, SEEK_SET) != 0)
goto err_ret;
@@ -754,7 +786,8 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
out:
if (preserve_match.marker != NULL)
bfd_preserve_finish (abfd, &preserve_match);
- bfd_preserve_restore (abfd, &preserve);
+ if (preserve.marker != NULL)
+ bfd_preserve_restore (abfd, &preserve);
_bfd_restore_error_handler_caching (orig_messages);
print_and_clear_messages (&messages, PER_XVEC_NO_TARGET);
bfd_cache_set_uncloseable (abfd, old_in_format_matches, NULL);
diff --git a/bfd/i386aout.c b/bfd/i386aout.c
index fb09597..082ebfb 100644
--- a/bfd/i386aout.c
+++ b/bfd/i386aout.c
@@ -79,7 +79,6 @@ static const struct aout_backend_data MY (backend_data) =
MY (set_sizes),
1, /* Exec header not counted. */
0, /* Add_dynamic_symbols. */
- 0, /* Add_one_symbol. */
0, /* Link_dynamic_object. */
0, /* Write_dynamic_symbol. */
0, /* Check_dynamic_reloc. */
diff --git a/bfd/libaout.h b/bfd/libaout.h
index ca4faec..7628d6a 100644
--- a/bfd/libaout.h
+++ b/bfd/libaout.h
@@ -177,13 +177,6 @@ struct aout_backend_data
(bfd *, struct bfd_link_info *, struct external_nlist **,
bfd_size_type *, char **);
- /* Callback from the add symbols phase of the linker code to handle
- adding a single symbol to the global linker hash table. */
- bool (*add_one_symbol)
- (struct bfd_link_info *, bfd *, const char *, flagword,
- asection *, bfd_vma, const char *, bool, bool,
- struct bfd_link_hash_entry **);
-
/* Called to handle linking a dynamic object. */
bool (*link_dynamic_object)
(struct bfd_link_info *, bfd *);
diff --git a/bfd/pdp11.c b/bfd/pdp11.c
index bdd9fc2..2d12033 100644
--- a/bfd/pdp11.c
+++ b/bfd/pdp11.c
@@ -2839,9 +2839,6 @@ aout_link_check_archive_element (bfd *abfd,
static bool
aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
{
- bool (*add_one_symbol)
- (struct bfd_link_info *, bfd *, const char *, flagword, asection *,
- bfd_vma, const char *, bool, bool, struct bfd_link_hash_entry **);
struct external_nlist *syms;
bfd_size_type sym_count;
char *strings;
@@ -2875,10 +2872,6 @@ aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
return false;
obj_aout_sym_hashes (abfd) = sym_hash;
- add_one_symbol = aout_backend_info (abfd)->add_one_symbol;
- if (add_one_symbol == NULL)
- add_one_symbol = _bfd_generic_link_add_one_symbol;
-
p = syms;
pend = p + sym_count;
for (; p < pend; p++, sym_hash++)
@@ -2951,7 +2944,7 @@ aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
break;
}
- if (! ((*add_one_symbol)
+ if (! (_bfd_generic_link_add_one_symbol
(info, abfd, name, flags, section, value, string, copy, false,
(struct bfd_link_hash_entry **) sym_hash)))
return false;
diff --git a/bfd/version.h b/bfd/version.h
index 434f5d5..9ddeb48 100644
--- a/bfd/version.h
+++ b/bfd/version.h
@@ -16,7 +16,7 @@
In releases, the date is not included in either version strings or
sonames. */
-#define BFD_VERSION_DATE 20250410
+#define BFD_VERSION_DATE 20250421
#define BFD_VERSION @bfd_version@
#define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@
#define REPORT_BUGS_TO @report_bugs_to@
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index b291670..c74526e 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -2701,6 +2701,14 @@ but the result again may not be as you expect.
For RISC-V, the following options are supported:
@table @code
+@item max
+Disassemble without checking architecture string. This is a best effort mode, so
+for overlapping ISA extensions the first match (possibly incorrect in a given
+context) will be used to decode the instruction. It's useful, if the ELF file
+doesn't expose ISA string, preventing automatic ISA subset deduction, and the
+default fallback ISA string (@code{rv64gc}) doesn't cover all instructions in
+the binary.
+
@item numeric
Print numeric register names, rather than ABI names (e.g., print @code{x2}
instead of @code{sp}).
diff --git a/binutils/resbin.c b/binutils/resbin.c
index 388b016..98dd68b 100644
--- a/binutils/resbin.c
+++ b/binutils/resbin.c
@@ -54,8 +54,8 @@ static rc_res_resource *bin_to_res_group_cursor (windres_bfd *, const bfd_byte *
static rc_res_resource *bin_to_res_group_icon (windres_bfd *, const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_version (windres_bfd *, const bfd_byte *, rc_uint_type);
static rc_res_resource *bin_to_res_userdata (windres_bfd *, const bfd_byte *, rc_uint_type);
-static rc_res_resource *bin_to_res_toolbar (windres_bfd *, const bfd_byte *);
-static void get_version_header (windres_bfd *, const bfd_byte *, rc_uint_type, const char *,
+static rc_res_resource *bin_to_res_toolbar (windres_bfd *, const bfd_byte *, rc_uint_type);
+static bool get_version_header (windres_bfd *, const bfd_byte *, rc_uint_type, const char *,
unichar **, rc_uint_type *, rc_uint_type *, rc_uint_type *,
rc_uint_type *);
@@ -105,7 +105,7 @@ bin_to_res (windres_bfd *wrbfd, rc_res_id type, const bfd_byte *data,
case RT_VERSION:
return bin_to_res_version (wrbfd, data, length);
case RT_TOOLBAR:
- return bin_to_res_toolbar (wrbfd, data);
+ return bin_to_res_toolbar (wrbfd, data, length);
}
}
@@ -116,7 +116,7 @@ bin_to_res (windres_bfd *wrbfd, rc_res_id type, const bfd_byte *data,
static void
toosmall (const char *msg)
{
- fatal (_("%s: not enough binary data"), msg);
+ non_fatal (_("%s: not enough binary data"), msg);
}
/* Swap in a NULL terminated unicode string. */
@@ -132,13 +132,16 @@ get_unicode (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length,
while (1)
{
if (length < c * 2 + 2)
- toosmall (_("null terminated unicode string"));
+ {
+ toosmall (_("null terminated unicode string"));
+ return NULL;
+ }
if (windres_get_16 (wrbfd, data + c * 2, 2) == 0)
break;
++c;
}
- ret = (unichar *) res_alloc ((c + 1) * sizeof (unichar));
+ ret = res_alloc ((c + 1) * sizeof (unichar));
for (i = 0; i < c; i++)
ret[i] = windres_get_16 (wrbfd, data + i * 2, 2);
@@ -159,13 +162,19 @@ get_resid (windres_bfd *wrbfd, rc_res_id *id, const bfd_byte *data,
rc_uint_type first;
if (length < 2)
- toosmall (_("resource ID"));
+ {
+ toosmall (_("resource ID"));
+ return -1;
+ }
first = windres_get_16 (wrbfd, data, 2);
if (first == 0xffff)
{
if (length < 4)
- toosmall (_("resource ID"));
+ {
+ toosmall (_("resource ID"));
+ return -1;
+ }
id->named = 0;
id->u.id = windres_get_16 (wrbfd, data + 2, 2);
return 4;
@@ -174,6 +183,8 @@ get_resid (windres_bfd *wrbfd, rc_res_id *id, const bfd_byte *data,
{
id->named = 1;
id->u.n.name = get_unicode (wrbfd, data, length, &id->u.n.length);
+ if (id->u.n.name == NULL)
+ return -1;
return id->u.n.length * 2 + 2;
}
}
@@ -187,7 +198,7 @@ bin_to_res_generic (windres_bfd *wrbfd ATTRIBUTE_UNUSED, enum rc_res_type type,
{
rc_res_resource *r;
- r = (rc_res_resource *) res_alloc (sizeof (rc_res_resource));
+ r = res_alloc (sizeof (rc_res_resource));
r->type = type;
r->u.data.data = data;
r->u.data.length = length;
@@ -204,15 +215,18 @@ bin_to_res_cursor (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
rc_res_resource *r;
if (length < 4)
- toosmall (_("cursor"));
+ {
+ toosmall (_("cursor"));
+ return NULL;
+ }
- c = (rc_cursor *) res_alloc (sizeof (rc_cursor));
+ c = res_alloc (sizeof (rc_cursor));
c->xhotspot = windres_get_16 (wrbfd, data, 2);
c->yhotspot = windres_get_16 (wrbfd, data + 2, 2);
c->length = length - 4;
c->data = data + 4;
- r = (rc_res_resource *) res_alloc (sizeof *r);
+ r = res_alloc (sizeof *r);
r->type = RES_TYPE_CURSOR;
r->u.cursor = c;
@@ -228,39 +242,58 @@ bin_to_res_menu (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
rc_menu *m;
rc_uint_type version, got;
- r = (rc_res_resource *) res_alloc (sizeof *r);
+ r = res_alloc (sizeof *r);
r->type = RES_TYPE_MENU;
- m = (rc_menu *) res_alloc (sizeof (rc_menu));
+ m = res_alloc (sizeof (rc_menu));
r->u.menu = m;
if (length < 2)
- toosmall (_("menu header"));
+ {
+ toosmall (_("menu header"));
+ return NULL;
+ }
version = windres_get_16 (wrbfd, data, 2);
if (version == 0)
{
if (length < 4)
- toosmall (_("menu header"));
+ {
+ toosmall (_("menu header"));
+ return NULL;
+ }
m->help = 0;
m->items = bin_to_res_menuitems (wrbfd, data + 4, length - 4, &got);
+ if (m->items == NULL)
+ return NULL;
}
else if (version == 1)
{
rc_uint_type offset;
if (length < 8)
- toosmall (_("menuex header"));
+ {
+ toosmall (_("menuex header"));
+ return NULL;
+ }
m->help = windres_get_32 (wrbfd, data + 4, 4);
offset = windres_get_16 (wrbfd, data + 2, 2);
if (offset + 4 >= length)
- toosmall (_("menuex offset"));
+ {
+ toosmall (_("menuex offset"));
+ return NULL;
+ }
m->items = bin_to_res_menuexitems (wrbfd, data + 4 + offset,
length - (4 + offset), &got);
+ if (m->items == NULL)
+ return NULL;
}
else
- fatal (_("unsupported menu version %d"), (int) version);
+ {
+ non_fatal (_("unsupported menu version %d"), (int) version);
+ return NULL;
+ }
return r;
}
@@ -268,8 +301,8 @@ bin_to_res_menu (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
/* Convert menu items from binary. */
static rc_menuitem *
-bin_to_res_menuitems (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length,
- rc_uint_type *got)
+bin_to_res_menuitems (windres_bfd *wrbfd, const bfd_byte *data,
+ rc_uint_type length, rc_uint_type *got)
{
rc_menuitem *first, **pp;
@@ -285,9 +318,12 @@ bin_to_res_menuitems (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type len
rc_menuitem *mi;
if (length < 4)
- toosmall (_("menuitem header"));
+ {
+ toosmall (_("menuitem header"));
+ return NULL;
+ }
- mi = (rc_menuitem *) res_alloc (sizeof *mi);
+ mi = res_alloc (sizeof *mi);
mi->state = 0;
mi->help = 0;
@@ -300,7 +336,10 @@ bin_to_res_menuitems (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type len
stroff = 2;
if (length < stroff + 2)
- toosmall (_("menuitem header"));
+ {
+ toosmall (_("menuitem header"));
+ return NULL;
+ }
if (windres_get_16 (wrbfd, data + stroff, 2) == 0)
{
@@ -308,7 +347,11 @@ bin_to_res_menuitems (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type len
mi->text = NULL;
}
else
- mi->text = get_unicode (wrbfd, data + stroff, length - stroff, &slen);
+ {
+ mi->text = get_unicode (wrbfd, data + stroff, length - stroff, &slen);
+ if (mi->text == NULL)
+ return NULL;
+ }
itemlen = stroff + slen * 2 + 2;
@@ -322,8 +365,10 @@ bin_to_res_menuitems (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type len
rc_uint_type subread;
mi->id = 0;
- mi->popup = bin_to_res_menuitems (wrbfd, data + itemlen, length - itemlen,
- &subread);
+ mi->popup = bin_to_res_menuitems (wrbfd, data + itemlen,
+ length - itemlen, &subread);
+ if (mi->popup == NULL)
+ return NULL;
itemlen += subread;
}
@@ -345,8 +390,8 @@ bin_to_res_menuitems (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type len
/* Convert menuex items from binary. */
static rc_menuitem *
-bin_to_res_menuexitems (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length,
- rc_uint_type *got)
+bin_to_res_menuexitems (windres_bfd *wrbfd, const bfd_byte *data,
+ rc_uint_type length, rc_uint_type *got)
{
rc_menuitem *first, **pp;
@@ -362,9 +407,12 @@ bin_to_res_menuexitems (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type l
rc_menuitem *mi;
if (length < 16)
- toosmall (_("menuitem header"));
+ {
+ toosmall (_("menuitem header"));
+ return NULL;
+ }
- mi = (rc_menuitem *) res_alloc (sizeof (rc_menuitem));
+ mi = res_alloc (sizeof (rc_menuitem));
mi->type = windres_get_32 (wrbfd, data, 4);
mi->state = windres_get_32 (wrbfd, data + 4, 4);
mi->id = windres_get_32 (wrbfd, data + 8, 4);
@@ -377,7 +425,11 @@ bin_to_res_menuexitems (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type l
mi->text = NULL;
}
else
- mi->text = get_unicode (wrbfd, data + 14, length - 14, &slen);
+ {
+ mi->text = get_unicode (wrbfd, data + 14, length - 14, &slen);
+ if (mi->text == NULL)
+ return NULL;
+ }
itemlen = 14 + slen * 2 + 2;
itemlen = (itemlen + 3) &~ 3;
@@ -392,12 +444,17 @@ bin_to_res_menuexitems (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type l
rc_uint_type subread;
if (length < itemlen + 4)
- toosmall (_("menuitem"));
+ {
+ toosmall (_("menuitem"));
+ return NULL;
+ }
mi->help = windres_get_32 (wrbfd, data + itemlen, 4);
itemlen += 4;
mi->popup = bin_to_res_menuexitems (wrbfd, data + itemlen,
length - itemlen, &subread);
+ if (mi->popup == NULL)
+ return NULL;
itemlen += subread;
}
@@ -424,14 +481,18 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
rc_uint_type signature;
rc_dialog *d;
rc_uint_type c, sublen, i;
+ int ilen;
rc_uint_type off;
rc_dialog_control **pp;
rc_res_resource *r;
if (length < 18)
- toosmall (_("dialog header"));
+ {
+ toosmall (_("dialog header"));
+ return NULL;
+ }
- d = (rc_dialog *) res_alloc (sizeof (rc_dialog));
+ d = res_alloc (sizeof (rc_dialog));
signature = windres_get_16 (wrbfd, data + 2, 2);
if (signature != 0xffff)
@@ -447,9 +508,12 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
version = windres_get_16 (wrbfd, data, 2);
if (version != 1)
- fatal (_("unexpected DIALOGEX version %d"), version);
+ {
+ non_fatal (_("unexpected DIALOGEX version %d"), version);
+ return NULL;
+ }
- d->ex = (rc_dialog_ex *) res_alloc (sizeof (rc_dialog_ex));
+ d->ex = res_alloc (sizeof (rc_dialog_ex));
d->ex->help = windres_get_32 (wrbfd, data + 4, 4);
d->exstyle = windres_get_32 (wrbfd, data + 8, 4);
d->style = windres_get_32 (wrbfd, data + 12, 4);
@@ -457,7 +521,10 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
}
if (length < off + 10)
- toosmall (_("dialog header"));
+ {
+ toosmall (_("dialog header"));
+ return NULL;
+ }
c = windres_get_16 (wrbfd, data + off, 2);
d->x = windres_get_16 (wrbfd, data + off + 2, 2);
@@ -467,13 +534,19 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
off += 10;
- sublen = get_resid (wrbfd, &d->menu, data + off, length - off);
- off += sublen;
+ ilen = get_resid (wrbfd, &d->menu, data + off, length - off);
+ if (ilen == -1)
+ return NULL;
+ off += ilen;
- sublen = get_resid (wrbfd, &d->class, data + off, length - off);
- off += sublen;
+ ilen = get_resid (wrbfd, &d->class, data + off, length - off);
+ if (ilen == -1)
+ return NULL;
+ off += ilen;
d->caption = get_unicode (wrbfd, data + off, length - off, &sublen);
+ if (d->caption == NULL)
+ return NULL;
off += sublen * 2 + 2;
if (sublen == 0)
d->caption = NULL;
@@ -492,7 +565,10 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
else
{
if (length < off + 2)
- toosmall (_("dialog font point size"));
+ {
+ toosmall (_("dialog font point size"));
+ return NULL;
+ }
d->pointsize = windres_get_16 (wrbfd, data + off, 2);
off += 2;
@@ -500,7 +576,10 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
if (d->ex != NULL)
{
if (length < off + 4)
- toosmall (_("dialogex font information"));
+ {
+ toosmall (_("dialogex font information"));
+ return NULL;
+ }
d->ex->weight = windres_get_16 (wrbfd, data + off, 2);
d->ex->italic = windres_get_8 (wrbfd, data + off + 2, 1);
d->ex->charset = windres_get_8 (wrbfd, data + off + 3, 1);
@@ -508,6 +587,8 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
}
d->font = get_unicode (wrbfd, data + off, length - off, &sublen);
+ if (d->font == NULL)
+ return NULL;
off += sublen * 2 + 2;
}
@@ -521,12 +602,15 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
off = (off + 3) &~ 3;
- dc = (rc_dialog_control *) res_alloc (sizeof (rc_dialog_control));
+ dc = res_alloc (sizeof (rc_dialog_control));
if (d->ex == NULL)
{
if (length < off + 8)
- toosmall (_("dialog control"));
+ {
+ toosmall (_("dialog control"));
+ return NULL;
+ }
dc->style = windres_get_32 (wrbfd, data + off, 4);
dc->exstyle = windres_get_32 (wrbfd, data + off + 4, 4);
@@ -536,7 +620,10 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
else
{
if (length < off + 12)
- toosmall (_("dialogex control"));
+ {
+ toosmall (_("dialogex control"));
+ return NULL;
+ }
dc->help = windres_get_32 (wrbfd, data + off, 4);
dc->exstyle = windres_get_32 (wrbfd, data + off + 4, 4);
dc->style = windres_get_32 (wrbfd, data + off + 8, 4);
@@ -544,7 +631,10 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
}
if (length < off + (d->ex != NULL ? 2 : 0) + 10)
- toosmall (_("dialog control"));
+ {
+ toosmall (_("dialog control"));
+ return NULL;
+ }
dc->x = windres_get_16 (wrbfd, data + off, 2);
dc->y = windres_get_16 (wrbfd, data + off + 2, 2);
@@ -558,14 +648,21 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
off += 10 + (d->ex != NULL ? 2 : 0);
- sublen = get_resid (wrbfd, &dc->class, data + off, length - off);
- off += sublen;
+ ilen = get_resid (wrbfd, &dc->class, data + off, length - off);
+ if (ilen == -1)
+ return NULL;
+ off += ilen;
- sublen = get_resid (wrbfd, &dc->text, data + off, length - off);
- off += sublen;
+ ilen = get_resid (wrbfd, &dc->text, data + off, length - off);
+ if (ilen == -1)
+ return NULL;
+ off += ilen;
if (length < off + 2)
- toosmall (_("dialog control end"));
+ {
+ toosmall (_("dialog control end"));
+ return NULL;
+ }
datalen = windres_get_16 (wrbfd, data + off, 2);
off += 2;
@@ -575,10 +672,12 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
else
{
if (length < off + datalen)
- toosmall (_("dialog control data"));
+ {
+ toosmall (_("dialog control data"));
+ return NULL;
+ }
- dc->data = ((rc_rcdata_item *)
- res_alloc (sizeof (rc_rcdata_item)));
+ dc->data = res_alloc (sizeof (rc_rcdata_item));
dc->data->next = NULL;
dc->data->type = RCDATA_BUFFER;
dc->data->u.buffer.length = datalen;
@@ -592,7 +691,7 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
pp = &dc->next;
}
- r = (rc_res_resource *) res_alloc (sizeof *r);
+ r = res_alloc (sizeof *r);
r->type = RES_TYPE_DIALOG;
r->u.dialog = d;
@@ -608,14 +707,17 @@ bin_to_res_string (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
int i;
rc_res_resource *r;
- st = (rc_stringtable *) res_alloc (sizeof (rc_stringtable));
+ st = res_alloc (sizeof (rc_stringtable));
for (i = 0; i < 16; i++)
{
unsigned int slen;
if (length < 2)
- toosmall (_("stringtable string length"));
+ {
+ toosmall (_("stringtable string length"));
+ return NULL;
+ }
slen = windres_get_16 (wrbfd, data, 2);
st->strings[i].length = slen;
@@ -625,9 +727,12 @@ bin_to_res_string (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
unsigned int j;
if (length < 2 + 2 * slen)
- toosmall (_("stringtable string"));
+ {
+ toosmall (_("stringtable string"));
+ return NULL;
+ }
- s = (unichar *) res_alloc (slen * sizeof (unichar));
+ s = res_alloc (slen * sizeof (unichar));
st->strings[i].string = s;
for (j = 0; j < slen; j++)
@@ -638,7 +743,7 @@ bin_to_res_string (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
length -= 2 + 2 * slen;
}
- r = (rc_res_resource *) res_alloc (sizeof *r);
+ r = res_alloc (sizeof *r);
r->type = RES_TYPE_STRINGTABLE;
r->u.stringtable = st;
@@ -648,14 +753,18 @@ bin_to_res_string (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
/* Convert a fontdir resource from binary. */
static rc_res_resource *
-bin_to_res_fontdir (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
+bin_to_res_fontdir (windres_bfd *wrbfd, const bfd_byte *data,
+ rc_uint_type length)
{
rc_uint_type c, i;
rc_fontdir *first, **pp;
rc_res_resource *r;
if (length < 2)
- toosmall (_("fontdir header"));
+ {
+ toosmall (_("fontdir header"));
+ return NULL;
+ }
c = windres_get_16 (wrbfd, data, 2);
@@ -669,10 +778,13 @@ bin_to_res_fontdir (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
unsigned int off;
if (length < 56)
- toosmall (_("fontdir"));
+ {
+ toosmall (_("fontdir"));
+ return NULL;
+ }
bfi = (const struct bin_fontdir_item *) data;
- fd = (rc_fontdir *) res_alloc (sizeof *fd);
+ fd = res_alloc (sizeof *fd);
fd->index = windres_get_16 (wrbfd, bfi->index, 2);
/* To work out the length of the fontdir data, we must get the
@@ -686,13 +798,19 @@ bin_to_res_fontdir (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
while (off < length && data[off] != '\0')
++off;
if (off >= length)
- toosmall (_("fontdir device name"));
+ {
+ toosmall (_("fontdir device name"));
+ return NULL;
+ }
++off;
while (off < length && data[off] != '\0')
++off;
if (off >= length)
- toosmall (_("fontdir face name"));
+ {
+ toosmall (_("fontdir face name"));
+ return NULL;
+ }
++off;
fd->length = off;
@@ -709,7 +827,7 @@ bin_to_res_fontdir (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
length -= off;
}
- r = (rc_res_resource *) res_alloc (sizeof *r);
+ r = res_alloc (sizeof *r);
r->type = RES_TYPE_FONTDIR;
r->u.fontdir = first;
@@ -719,7 +837,8 @@ bin_to_res_fontdir (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
/* Convert an accelerators resource from binary. */
static rc_res_resource *
-bin_to_res_accelerators (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
+bin_to_res_accelerators (windres_bfd *wrbfd, const bfd_byte *data,
+ rc_uint_type length)
{
rc_accelerator *first, **pp;
rc_res_resource *r;
@@ -732,9 +851,12 @@ bin_to_res_accelerators (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type
rc_accelerator *a;
if (length < 8)
- toosmall (_("accelerator"));
+ {
+ toosmall (_("accelerator"));
+ return NULL;
+ }
- a = (rc_accelerator *) res_alloc (sizeof (rc_accelerator));
+ a = res_alloc (sizeof (rc_accelerator));
a->flags = windres_get_16 (wrbfd, data, 2);
a->key = windres_get_16 (wrbfd, data + 2, 2);
@@ -751,7 +873,7 @@ bin_to_res_accelerators (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type
length -= 8;
}
- r = (rc_res_resource *) res_alloc (sizeof (rc_res_resource));
+ r = res_alloc (sizeof (rc_res_resource));
r->type = RES_TYPE_ACCELERATOR;
r->u.acc = first;
@@ -767,14 +889,14 @@ bin_to_res_rcdata (windres_bfd *wrbfd ATTRIBUTE_UNUSED, const bfd_byte *data,
rc_rcdata_item *ri;
rc_res_resource *r;
- ri = (rc_rcdata_item *) res_alloc (sizeof (rc_rcdata_item));
+ ri = res_alloc (sizeof (rc_rcdata_item));
ri->next = NULL;
ri->type = RCDATA_BUFFER;
ri->u.buffer.length = length;
ri->u.buffer.data = data;
- r = (rc_res_resource *) res_alloc (sizeof *r);
+ r = res_alloc (sizeof *r);
r->type = rctyp;
r->u.rcdata = ri;
@@ -784,18 +906,25 @@ bin_to_res_rcdata (windres_bfd *wrbfd ATTRIBUTE_UNUSED, const bfd_byte *data,
/* Convert a group cursor resource from binary. */
static rc_res_resource *
-bin_to_res_group_cursor (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
+bin_to_res_group_cursor (windres_bfd *wrbfd, const bfd_byte *data,
+ rc_uint_type length)
{
int type, c, i;
rc_group_cursor *first, **pp;
rc_res_resource *r;
if (length < 6)
- toosmall (_("group cursor header"));
+ {
+ toosmall (_("group cursor header"));
+ return NULL;
+ }
type = windres_get_16 (wrbfd, data + 2, 2);
if (type != 2)
- fatal (_("unexpected group cursor type %d"), type);
+ {
+ non_fatal (_("unexpected group cursor type %d"), type);
+ return NULL;
+ }
c = windres_get_16 (wrbfd, data + 4, 2);
@@ -810,9 +939,12 @@ bin_to_res_group_cursor (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type
rc_group_cursor *gc;
if (length < 14)
- toosmall (_("group cursor"));
+ {
+ toosmall (_("group cursor"));
+ return NULL;
+ }
- gc = (rc_group_cursor *) res_alloc (sizeof *gc);
+ gc = res_alloc (sizeof *gc);
gc->width = windres_get_16 (wrbfd, data, 2);
gc->height = windres_get_16 (wrbfd, data + 2, 2);
@@ -829,7 +961,7 @@ bin_to_res_group_cursor (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type
length -= 14;
}
- r = (rc_res_resource *) res_alloc (sizeof (rc_res_resource));
+ r = res_alloc (sizeof (rc_res_resource));
r->type = RES_TYPE_GROUP_CURSOR;
r->u.group_cursor = first;
@@ -839,18 +971,25 @@ bin_to_res_group_cursor (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type
/* Convert a group icon resource from binary. */
static rc_res_resource *
-bin_to_res_group_icon (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
+bin_to_res_group_icon (windres_bfd *wrbfd, const bfd_byte *data,
+ rc_uint_type length)
{
int type, c, i;
rc_group_icon *first, **pp;
rc_res_resource *r;
if (length < 6)
- toosmall (_("group icon header"));
+ {
+ toosmall (_("group icon header"));
+ return NULL;
+ }
type = windres_get_16 (wrbfd, data + 2, 2);
if (type != 1)
- fatal (_("unexpected group icon type %d"), type);
+ {
+ non_fatal (_("unexpected group icon type %d"), type);
+ return NULL;
+ }
c = windres_get_16 (wrbfd, data + 4, 2);
@@ -865,9 +1004,12 @@ bin_to_res_group_icon (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type le
rc_group_icon *gi;
if (length < 14)
- toosmall (_("group icon"));
+ {
+ toosmall (_("group icon"));
+ return NULL;
+ }
- gi = (rc_group_icon *) res_alloc (sizeof (rc_group_icon));
+ gi = res_alloc (sizeof (rc_group_icon));
gi->width = windres_get_8 (wrbfd, data, 1);
gi->height = windres_get_8 (wrbfd, data + 1, 1);
@@ -885,7 +1027,7 @@ bin_to_res_group_icon (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type le
length -= 14;
}
- r = (rc_res_resource *) res_alloc (sizeof *r);
+ r = res_alloc (sizeof *r);
r->type = RES_TYPE_GROUP_ICON;
r->u.group_icon = first;
@@ -897,14 +1039,17 @@ bin_to_res_group_icon (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type le
sets *LEN to the total length, *VALLEN to the value length, *TYPE
to the type, and *OFF to the offset to the children. */
-static void
-get_version_header (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length,
- const char *key, unichar **pkey,
+static bool
+get_version_header (windres_bfd *wrbfd, const bfd_byte *data,
+ rc_uint_type length, const char *key, unichar **pkey,
rc_uint_type *len, rc_uint_type *vallen, rc_uint_type *type,
rc_uint_type *off)
{
if (length < 8)
- toosmall (key);
+ {
+ toosmall (key);
+ return false;
+ }
*len = (windres_get_16 (wrbfd, data, 2) + 3) & ~3;
*vallen = windres_get_16 (wrbfd, data + 2, 2);
@@ -920,6 +1065,8 @@ get_version_header (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
rc_uint_type sublen;
*pkey = get_unicode (wrbfd, data, length, &sublen);
+ if (*pkey == NULL)
+ return false;
*off += (sublen + 1) * sizeof (unichar);
}
else
@@ -927,9 +1074,15 @@ get_version_header (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
while (1)
{
if (length < 2)
- toosmall (key);
+ {
+ toosmall (key);
+ return false;
+ }
if (windres_get_16 (wrbfd, data, 2) != (bfd_byte) *key)
- fatal (_("unexpected version string"));
+ {
+ non_fatal (_("unexpected version string"));
+ return false;
+ }
*off += 2;
length -= 2;
@@ -943,12 +1096,14 @@ get_version_header (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
}
*off = (*off + 3) &~ 3;
+ return true;
}
/* Convert a version resource from binary. */
static rc_res_resource *
-bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
+bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data,
+ rc_uint_type length)
{
rc_uint_type verlen, vallen, type, off;
rc_fixed_versioninfo *fi;
@@ -956,18 +1111,26 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
rc_versioninfo *v;
rc_res_resource *r;
- get_version_header (wrbfd, data, length, "VS_VERSION_INFO",
- (unichar **) NULL, &verlen, &vallen, &type, &off);
+ if (!get_version_header (wrbfd, data, length, "VS_VERSION_INFO",
+ (unichar **) NULL, &verlen, &vallen, &type, &off))
+ return NULL;
/* PR 17512: The verlen field does not include padding length. */
if (verlen > length)
- fatal (_("version length %lu greater than resource length %lu"),
- (unsigned long) verlen, (unsigned long) length);
+ {
+ non_fatal (_("version length %lu greater than resource length %lu"),
+ (unsigned long) verlen, (unsigned long) length);
+ return NULL;
+ }
if (type != 0)
- fatal (_("unexpected version type %d"), (int) type);
+ {
+ non_fatal (_("unexpected version type %d"), (int) type);
+ return NULL;
+ }
- /* PR 27686: Ignore any padding bytes after the end of the version structure. */
+ /* PR 27686: Ignore any padding bytes after the end of the version
+ structure. */
length = verlen;
data += off;
@@ -980,20 +1143,33 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
unsigned long signature, fiv;
if (vallen != 52)
- fatal (_("unexpected fixed version information length %ld"), (long) vallen);
+ {
+ non_fatal (_("unexpected fixed version information length %ld"),
+ (long) vallen);
+ return NULL;
+ }
if (length < 52)
- toosmall (_("fixed version info"));
+ {
+ toosmall (_("fixed version info"));
+ return NULL;
+ }
signature = windres_get_32 (wrbfd, data, 4);
if (signature != 0xfeef04bd)
- fatal (_("unexpected fixed version signature %lu"), signature);
+ {
+ non_fatal (_("unexpected fixed version signature %lu"), signature);
+ return NULL;
+ }
fiv = windres_get_32 (wrbfd, data + 4, 4);
if (fiv != 0 && fiv != 0x10000)
- fatal (_("unexpected fixed version info version %lu"), fiv);
+ {
+ non_fatal (_("unexpected fixed version info version %lu"), fiv);
+ return NULL;
+ }
- fi = (rc_fixed_versioninfo *) res_alloc (sizeof (rc_fixed_versioninfo));
+ fi = res_alloc (sizeof (rc_fixed_versioninfo));
fi->file_version_ms = windres_get_32 (wrbfd, data + 8, 4);
fi->file_version_ls = windres_get_32 (wrbfd, data + 12, 4);
@@ -1020,9 +1196,12 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
int ch;
if (length < 8)
- toosmall (_("version var info"));
+ {
+ toosmall (_("version var info"));
+ return NULL;
+ }
- vi = (rc_ver_info *) res_alloc (sizeof (rc_ver_info));
+ vi = res_alloc (sizeof (rc_ver_info));
ch = windres_get_16 (wrbfd, data + 6, 2);
@@ -1032,12 +1211,17 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
vi->type = VERINFO_STRING;
- get_version_header (wrbfd, data, length, "StringFileInfo",
- (unichar **) NULL, &verlen, &vallen, &type,
- &off);
+ if (!get_version_header (wrbfd, data, length, "StringFileInfo",
+ (unichar **) NULL, &verlen, &vallen, &type,
+ &off))
+ return NULL;
if (vallen != 0)
- fatal (_("unexpected stringfileinfo value length %ld"), (long) vallen);
+ {
+ non_fatal (_("unexpected stringfileinfo value length %ld"),
+ (long) vallen);
+ return NULL;
+ }
data += off;
length -= off;
@@ -1054,66 +1238,88 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
rc_ver_stringinfo **ppvs;
if (length < 8)
- toosmall (_("version stringtable"));
+ {
+ toosmall (_("version stringtable"));
+ return NULL;
+ }
- vst = (rc_ver_stringtable *) res_alloc (sizeof (rc_ver_stringtable));
+ vst = res_alloc (sizeof (rc_ver_stringtable));
- get_version_header (wrbfd, data, length, (const char *) NULL,
- &vst->language, &stverlen, &vallen, &type, &off);
+ if (!get_version_header (wrbfd, data, length, (const char *) NULL,
+ &vst->language, &stverlen, &vallen,
+ &type, &off))
+ return NULL;
if (vallen != 0)
- fatal (_("unexpected version stringtable value length %ld"), (long) vallen);
+ {
+ non_fatal (_("unexpected version stringtable value length %ld"),
+ (long) vallen);
+ return NULL;
+ }
data += off;
length -= off;
verlen -= off;
- stverlen -= off;
-
- vst->strings = NULL;
- ppvs = &vst->strings;
-
- while (stverlen > 0)
- {
- rc_ver_stringinfo *vs;
- rc_uint_type sverlen, vslen, valoff;
-
- if (length < 8)
- toosmall (_("version string"));
-
- vs = (rc_ver_stringinfo *) res_alloc (sizeof (rc_ver_stringinfo));
-
- get_version_header (wrbfd, data, length, (const char *) NULL,
- &vs->key, &sverlen, &vallen, &type, &off);
-
- data += off;
- length -= off;
-
- vs->value = get_unicode (wrbfd, data, length, &vslen);
- valoff = vslen * 2 + 2;
- valoff = (valoff + 3) & ~3;
-
- if (off + valoff != sverlen)
- fatal (_("unexpected version string length %ld != %ld + %ld"),
- (long) sverlen, (long) off, (long) valoff);
-
- data += valoff;
- length -= valoff;
-
- if (stverlen < sverlen)
- fatal (_("unexpected version string length %ld < %ld"),
- (long) verlen, (long) sverlen);
- stverlen -= sverlen;
- verlen -= sverlen;
-
- vs->next = NULL;
- *ppvs = vs;
- ppvs = &vs->next;
- }
-
- vst->next = NULL;
- *ppvst = vst;
- ppvst = &vst->next;
+ stverlen -= off;
+
+ vst->strings = NULL;
+ ppvs = &vst->strings;
+
+ while (stverlen > 0)
+ {
+ rc_ver_stringinfo *vs;
+ rc_uint_type sverlen, vslen, valoff;
+
+ if (length < 8)
+ {
+ toosmall (_("version string"));
+ return NULL;
+ }
+
+ vs = res_alloc (sizeof (rc_ver_stringinfo));
+
+ if (!get_version_header (wrbfd, data, length,
+ (const char *) NULL, &vs->key,
+ &sverlen, &vallen, &type, &off))
+ return NULL;
+
+ data += off;
+ length -= off;
+
+ vs->value = get_unicode (wrbfd, data, length, &vslen);
+ if (vs->value == NULL)
+ return NULL;
+ valoff = vslen * 2 + 2;
+ valoff = (valoff + 3) & ~3;
+
+ if (off + valoff != sverlen)
+ {
+ non_fatal (_("unexpected version string length %ld != %ld + %ld"),
+ (long) sverlen, (long) off, (long) valoff);
+ return NULL;
+ }
+
+ data += valoff;
+ length -= valoff;
+
+ if (stverlen < sverlen)
+ {
+ non_fatal (_("unexpected version string length %ld < %ld"),
+ (long) verlen, (long) sverlen);
+ return NULL;
+ }
+ stverlen -= sverlen;
+ verlen -= sverlen;
+
+ vs->next = NULL;
+ *ppvs = vs;
+ ppvs = &vs->next;
+ }
+
+ vst->next = NULL;
+ *ppvst = vst;
+ ppvst = &vst->next;
}
}
else if (ch == 'V')
@@ -1122,18 +1328,25 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
vi->type = VERINFO_VAR;
- get_version_header (wrbfd, data, length, "VarFileInfo",
- (unichar **) NULL, &verlen, &vallen, &type,
- &off);
+ if (!get_version_header (wrbfd, data, length, "VarFileInfo",
+ (unichar **) NULL, &verlen, &vallen,
+ &type, &off))
+ return NULL;
if (vallen != 0)
- fatal (_("unexpected varfileinfo value length %ld"), (long) vallen);
+ {
+ non_fatal (_("unexpected varfileinfo value length %ld"),
+ (long) vallen);
+ return NULL;
+ }
data += off;
length -= off;
- get_version_header (wrbfd, data, length, (const char *) NULL,
- &vi->u.var.key, &verlen, &vallen, &type, &off);
+ if (!get_version_header (wrbfd, data, length, (const char *) NULL,
+ &vi->u.var.key, &verlen, &vallen,
+ &type, &off))
+ return NULL;
data += off;
length -= off;
@@ -1146,9 +1359,12 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
rc_ver_varinfo *vv;
if (length < 4)
- toosmall (_("version varfileinfo"));
+ {
+ toosmall (_("version varfileinfo"));
+ return NULL;
+ }
- vv = (rc_ver_varinfo *) res_alloc (sizeof (rc_ver_varinfo));
+ vv = res_alloc (sizeof (rc_ver_varinfo));
vv->language = windres_get_16 (wrbfd, data, 2);
vv->charset = windres_get_16 (wrbfd, data + 2, 2);
@@ -1161,7 +1377,11 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
length -= 4;
if (vallen < 4)
- fatal (_("unexpected version value length %ld"), (long) vallen);
+ {
+ non_fatal (_("unexpected version value length %ld"),
+ (long) vallen);
+ return NULL;
+ }
vallen -= 4;
}
@@ -1171,21 +1391,25 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
if (length == 8)
/* Padding - skip. */
break;
- fatal (_("nul bytes found in version string"));
+ non_fatal (_("nul bytes found in version string"));
+ return NULL;
}
else
- fatal (_("unexpected version string character: %x"), ch);
+ {
+ non_fatal (_("unexpected version string character: %x"), ch);
+ return NULL;
+ }
vi->next = NULL;
*pp = vi;
pp = &vi->next;
}
- v = (rc_versioninfo *) res_alloc (sizeof (rc_versioninfo));
+ v = res_alloc (sizeof (rc_versioninfo));
v->fixed = fi;
v->var = first;
- r = (rc_res_resource *) res_alloc (sizeof *r);
+ r = res_alloc (sizeof *r);
r->type = RES_TYPE_VERSIONINFO;
r->u.versioninfo = v;
@@ -1201,14 +1425,14 @@ bin_to_res_userdata (windres_bfd *wrbfd ATTRIBUTE_UNUSED, const bfd_byte *data,
rc_rcdata_item *ri;
rc_res_resource *r;
- ri = (rc_rcdata_item *) res_alloc (sizeof (rc_rcdata_item));
+ ri = res_alloc (sizeof (rc_rcdata_item));
ri->next = NULL;
ri->type = RCDATA_BUFFER;
ri->u.buffer.length = length;
ri->u.buffer.data = data;
- r = (rc_res_resource *) res_alloc (sizeof *r);
+ r = res_alloc (sizeof *r);
r->type = RES_TYPE_USERDATA;
r->u.rcdata = ri;
@@ -1216,38 +1440,51 @@ bin_to_res_userdata (windres_bfd *wrbfd ATTRIBUTE_UNUSED, const bfd_byte *data,
}
static rc_res_resource *
-bin_to_res_toolbar (windres_bfd *wrbfd, const bfd_byte *data)
+bin_to_res_toolbar (windres_bfd *wrbfd, const bfd_byte *data,
+ rc_uint_type length)
{
rc_toolbar *ri;
rc_res_resource *r;
rc_uint_type i;
- ri = (rc_toolbar *) res_alloc (sizeof (rc_toolbar));
+ if (length < 12)
+ {
+ toosmall (_("toolbar"));
+ return NULL;
+ }
+ ri = res_alloc (sizeof (rc_toolbar));
ri->button_width = windres_get_32 (wrbfd, data, 4);
ri->button_height = windres_get_32 (wrbfd, data + 4, 4);
ri->nitems = windres_get_32 (wrbfd, data + 8, 4);
ri->items = NULL;
data += 12;
- for (i=0 ; i < ri->nitems; i++)
- {
- rc_toolbar_item *it;
- it = (rc_toolbar_item *) res_alloc (sizeof (rc_toolbar_item));
- it->id.named = 0;
- it->id.u.id = (int) windres_get_32 (wrbfd, data, 4);
- it->prev = it->next = NULL;
- data += 4;
- if(ri->items) {
- rc_toolbar_item *ii = ri->items;
- while (ii->next != NULL)
- ii = ii->next;
- it->prev = ii;
- ii->next = it;
- }
- else
- ri->items = it;
- }
- r = (rc_res_resource *) res_alloc (sizeof *r);
+ length -= 12;
+ for (i = 0; i < ri->nitems; i++)
+ {
+ rc_toolbar_item *it;
+ it = res_alloc (sizeof (rc_toolbar_item));
+ it->id.named = 0;
+ if (length < 4)
+ {
+ toosmall (_("toolbar item"));
+ return NULL;
+ }
+ it->id.u.id = (int) windres_get_32 (wrbfd, data, 4);
+ it->prev = it->next = NULL;
+ data += 4;
+ length -= 4;
+ if(ri->items) {
+ rc_toolbar_item *ii = ri->items;
+ while (ii->next != NULL)
+ ii = ii->next;
+ it->prev = ii;
+ ii->next = it;
+ }
+ else
+ ri->items = it;
+ }
+ r = res_alloc (sizeof *r);
r->type = RES_TYPE_TOOLBAR;
r->u.toolbar = ri;
return r;
@@ -1286,7 +1523,8 @@ res_to_bin (windres_bfd *wrbfd, rc_uint_type off, const rc_res_resource *res)
case RES_TYPE_FONT:
case RES_TYPE_ICON:
case RES_TYPE_MESSAGETABLE:
- return res_to_bin_generic (wrbfd, off, res->u.data.length, res->u.data.data);
+ return res_to_bin_generic (wrbfd, off, res->u.data.length,
+ res->u.data.data);
case RES_TYPE_ACCELERATOR:
return res_to_bin_accelerator (wrbfd, off, res->u.acc);
case RES_TYPE_CURSOR:
@@ -1337,13 +1575,13 @@ resid_to_bin (windres_bfd *wrbfd, rc_uint_type off, rc_res_id id)
rc_uint_type len = (id.u.n.name ? unichar_len (id.u.n.name) : 0);
if (wrbfd)
{
- bfd_byte *d = (bfd_byte *) reswr_alloc ((len + 1) * sizeof (unichar));
+ bfd_byte *d = reswr_alloc ((len + 1) * sizeof (unichar));
rc_uint_type i;
for (i = 0; i < len; i++)
windres_put_16 (wrbfd, d + (i * sizeof (unichar)), id.u.n.name[i]);
windres_put_16 (wrbfd, d + (len * sizeof (unichar)), 0);
set_windres_bfd_content (wrbfd, d, off, (len + 1) * sizeof (unichar));
- }
+ }
off += (rc_uint_type) ((len + 1) * sizeof (unichar));
}
return off;
@@ -1364,7 +1602,7 @@ unicode_to_bin (windres_bfd *wrbfd, rc_uint_type off, const unichar *str)
{
bfd_byte *d;
rc_uint_type i;
- d = (bfd_byte *) reswr_alloc ( (len + 1) * sizeof (unichar));
+ d = reswr_alloc ((len + 1) * sizeof (unichar));
for (i = 0; i < len; i++)
windres_put_16 (wrbfd, d + (i * sizeof (unichar)), str[i]);
windres_put_16 (wrbfd, d + (len * sizeof (unichar)), 0);
@@ -1389,12 +1627,13 @@ res_to_bin_accelerator (windres_bfd *wrbfd, rc_uint_type off,
{
struct bin_accelerator ba;
- windres_put_16 (wrbfd, ba.flags, a->flags | (a->next != NULL ? 0 : ACC_LAST));
+ windres_put_16 (wrbfd, ba.flags,
+ a->flags | (a->next != NULL ? 0 : ACC_LAST));
windres_put_16 (wrbfd, ba.key, a->key);
windres_put_16 (wrbfd, ba.id, a->id);
windres_put_16 (wrbfd, ba.pad, 0);
set_windres_bfd_content (wrbfd, &ba, off, BIN_ACCELERATOR_SIZE);
- }
+ }
off += BIN_ACCELERATOR_SIZE;
}
return off;
@@ -1413,7 +1652,8 @@ res_to_bin_cursor (windres_bfd *wrbfd, rc_uint_type off, const rc_cursor *c)
windres_put_16 (wrbfd, bc.yhotspot, c->yhotspot);
set_windres_bfd_content (wrbfd, &bc, off, BIN_CURSOR_SIZE);
if (c->length)
- set_windres_bfd_content (wrbfd, c->data, off + BIN_CURSOR_SIZE, c->length);
+ set_windres_bfd_content (wrbfd, c->data, off + BIN_CURSOR_SIZE,
+ c->length);
}
off = (off + BIN_CURSOR_SIZE + (rc_uint_type) c->length);
return off;
@@ -1443,8 +1683,9 @@ res_to_bin_group_cursor (windres_bfd *wrbfd, rc_uint_type off,
windres_put_16 (wrbfd, bgci.bits, gc->bits);
windres_put_32 (wrbfd, bgci.bytes, gc->bytes);
windres_put_16 (wrbfd, bgci.index, gc->index);
- set_windres_bfd_content (wrbfd, &bgci, off, BIN_GROUP_CURSOR_ITEM_SIZE);
- }
+ set_windres_bfd_content (wrbfd, &bgci, off,
+ BIN_GROUP_CURSOR_ITEM_SIZE);
+ }
off += BIN_GROUP_CURSOR_ITEM_SIZE;
}
@@ -1477,17 +1718,17 @@ res_to_bin_dialog (windres_bfd *wrbfd, rc_uint_type off, const rc_dialog *dialog
if (wrbfd)
{
- if (! dialogex)
- {
+ if (! dialogex)
+ {
windres_put_32 (wrbfd, bd.style, dialog->style);
windres_put_32 (wrbfd, bd.exstyle, dialog->exstyle);
windres_put_16 (wrbfd, bd.x, dialog->x);
windres_put_16 (wrbfd, bd.y, dialog->y);
windres_put_16 (wrbfd, bd.width, dialog->width);
windres_put_16 (wrbfd, bd.height, dialog->height);
- }
- else
- {
+ }
+ else
+ {
windres_put_16 (wrbfd, bdx.sig1, 1);
windres_put_16 (wrbfd, bdx.sig2, 0xffff);
windres_put_32 (wrbfd, bdx.help, (dialog->ex ? dialog->ex->help : 0));
@@ -1520,9 +1761,12 @@ res_to_bin_dialog (windres_bfd *wrbfd, rc_uint_type off, const rc_dialog *dialog
{
struct bin_dialogexfont bdxf;
windres_put_16 (wrbfd, bdxf.pointsize, dialog->pointsize);
- windres_put_16 (wrbfd, bdxf.weight, (dialog->ex == NULL ? 0 : dialog->ex->weight));
- windres_put_8 (wrbfd, bdxf.italic, (dialog->ex == NULL ? 0 : dialog->ex->italic));
- windres_put_8 (wrbfd, bdxf.charset, (dialog->ex == NULL ? 1 : dialog->ex->charset));
+ windres_put_16 (wrbfd, bdxf.weight,
+ dialog->ex == NULL ? 0 : dialog->ex->weight);
+ windres_put_8 (wrbfd, bdxf.italic,
+ dialog->ex == NULL ? 0 : dialog->ex->italic);
+ windres_put_8 (wrbfd, bdxf.charset,
+ dialog->ex == NULL ? 1 : dialog->ex->charset);
set_windres_bfd_content (wrbfd, &bdxf, off, BIN_DIALOGEXFONT_SIZE);
}
}
@@ -1536,8 +1780,8 @@ res_to_bin_dialog (windres_bfd *wrbfd, rc_uint_type off, const rc_dialog *dialog
off += (4 - ((off - off_delta) & 3)) & 3;
if (wrbfd)
{
- if (! dialogex)
- {
+ if (! dialogex)
+ {
struct bin_dialog_control bdc;
windres_put_32 (wrbfd, bdc.style, dc->style);
@@ -1547,10 +1791,11 @@ res_to_bin_dialog (windres_bfd *wrbfd, rc_uint_type off, const rc_dialog *dialog
windres_put_16 (wrbfd, bdc.width, dc->width);
windres_put_16 (wrbfd, bdc.height, dc->height);
windres_put_16 (wrbfd, bdc.id, dc->id);
- set_windres_bfd_content (wrbfd, &bdc, off, BIN_DIALOG_CONTROL_SIZE);
- }
- else
- {
+ set_windres_bfd_content (wrbfd, &bdc, off,
+ BIN_DIALOG_CONTROL_SIZE);
+ }
+ else
+ {
struct bin_dialogex_control bdc;
windres_put_32 (wrbfd, bdc.help, dc->help);
@@ -1561,11 +1806,11 @@ res_to_bin_dialog (windres_bfd *wrbfd, rc_uint_type off, const rc_dialog *dialog
windres_put_16 (wrbfd, bdc.width, dc->width);
windres_put_16 (wrbfd, bdc.height, dc->height);
windres_put_32 (wrbfd, bdc.id, dc->id);
- set_windres_bfd_content (wrbfd, &bdc, off, BIN_DIALOGEX_CONTROL_SIZE);
+ set_windres_bfd_content (wrbfd, &bdc, off,
+ BIN_DIALOGEX_CONTROL_SIZE);
}
}
- off += (dialogex != 0 ? BIN_DIALOGEX_CONTROL_SIZE : BIN_DIALOG_CONTROL_SIZE);
-
+ off += dialogex != 0 ? BIN_DIALOGEX_CONTROL_SIZE : BIN_DIALOG_CONTROL_SIZE;
off = resid_to_bin (wrbfd, off, dc->class);
off = resid_to_bin (wrbfd, off, dc->text);
@@ -1607,7 +1852,8 @@ res_to_bin_dialog (windres_bfd *wrbfd, rc_uint_type off, const rc_dialog *dialog
/* Convert a fontdir resource to binary. */
static rc_uint_type
-res_to_bin_fontdir (windres_bfd *wrbfd, rc_uint_type off, const rc_fontdir *fontdirs)
+res_to_bin_fontdir (windres_bfd *wrbfd, rc_uint_type off,
+ const rc_fontdir *fontdirs)
{
rc_uint_type start;
int c;
@@ -1641,7 +1887,8 @@ res_to_bin_fontdir (windres_bfd *wrbfd, rc_uint_type off, const rc_fontdir *font
/* Convert a group icon resource to binary. */
static rc_uint_type
-res_to_bin_group_icon (windres_bfd *wrbfd, rc_uint_type off, const rc_group_icon *group_icons)
+res_to_bin_group_icon (windres_bfd *wrbfd, rc_uint_type off,
+ const rc_group_icon *group_icons)
{
rc_uint_type start;
struct bin_group_icon bgi;
@@ -1691,21 +1938,21 @@ res_to_bin_menu (windres_bfd *wrbfd, rc_uint_type off, const rc_menu *menu)
if (wrbfd)
{
- if (! menuex)
- {
+ if (! menuex)
+ {
struct bin_menu bm;
windres_put_16 (wrbfd, bm.sig1, 0);
windres_put_16 (wrbfd, bm.sig2, 0);
set_windres_bfd_content (wrbfd, &bm, off, BIN_MENU_SIZE);
- }
- else
- {
+ }
+ else
+ {
struct bin_menuex bm;
windres_put_16 (wrbfd, bm.sig1, 1);
windres_put_16 (wrbfd, bm.sig2, 4);
windres_put_32 (wrbfd, bm.help, menu->help);
set_windres_bfd_content (wrbfd, &bm, off, BIN_MENUEX_SIZE);
- }
+ }
}
off += (menuex != 0 ? BIN_MENUEX_SIZE : BIN_MENU_SIZE);
if (! menuex)
@@ -1722,7 +1969,8 @@ res_to_bin_menu (windres_bfd *wrbfd, rc_uint_type off, const rc_menu *menu)
/* Convert menu items to binary. */
static rc_uint_type
-res_to_bin_menuitems (windres_bfd *wrbfd, rc_uint_type off, const rc_menuitem *items)
+res_to_bin_menuitems (windres_bfd *wrbfd, rc_uint_type off,
+ const rc_menuitem *items)
{
const rc_menuitem *mi;
@@ -1740,11 +1988,12 @@ res_to_bin_menuitems (windres_bfd *wrbfd, rc_uint_type off, const rc_menuitem *i
if (wrbfd)
{
windres_put_16 (wrbfd, bmi.flags, flags);
- if (mi->popup == NULL)
+ if (mi->popup == NULL)
windres_put_16 (wrbfd, bmi.id, mi->id);
set_windres_bfd_content (wrbfd, &bmi, off,
- mi->popup == NULL ? BIN_MENUITEM_SIZE
- : BIN_MENUITEM_POPUP_SIZE);
+ (mi->popup == NULL
+ ? BIN_MENUITEM_SIZE
+ : BIN_MENUITEM_POPUP_SIZE));
}
off += (mi->popup == NULL ? BIN_MENUITEM_SIZE : BIN_MENUITEM_POPUP_SIZE);
@@ -1761,7 +2010,8 @@ res_to_bin_menuitems (windres_bfd *wrbfd, rc_uint_type off, const rc_menuitem *i
/* Convert menuex items to binary. */
static rc_uint_type
-res_to_bin_menuexitems (windres_bfd *wrbfd, rc_uint_type off, const rc_menuitem *items)
+res_to_bin_menuexitems (windres_bfd *wrbfd, rc_uint_type off,
+ const rc_menuitem *items)
{
rc_uint_type off_delta = off;
const rc_menuitem *mi;
@@ -1814,7 +2064,8 @@ res_to_bin_menuexitems (windres_bfd *wrbfd, rc_uint_type off, const rc_menuitem
to binary. */
static rc_uint_type
-res_to_bin_rcdata (windres_bfd *wrbfd, rc_uint_type off, const rc_rcdata_item *items)
+res_to_bin_rcdata (windres_bfd *wrbfd, rc_uint_type off,
+ const rc_rcdata_item *items)
{
const rc_rcdata_item *ri;
@@ -1855,22 +2106,23 @@ res_to_bin_rcdata (windres_bfd *wrbfd, rc_uint_type off, const rc_rcdata_item *i
break;
case RCDATA_STRING:
hp = (bfd_byte *) ri->u.string.s;
- break;
- case RCDATA_WSTRING:
- {
+ break;
+ case RCDATA_WSTRING:
+ {
rc_uint_type i;
- hp = (bfd_byte *) reswr_alloc (len);
- for (i = 0; i < ri->u.wstring.length; i++)
- windres_put_16 (wrbfd, hp + i * sizeof (unichar), ri->u.wstring.w[i]);
- }
+ hp = reswr_alloc (len);
+ for (i = 0; i < ri->u.wstring.length; i++)
+ windres_put_16 (wrbfd, hp + i * sizeof (unichar),
+ ri->u.wstring.w[i]);
+ }
break;
- case RCDATA_BUFFER:
+ case RCDATA_BUFFER:
hp = (bfd_byte *) ri->u.buffer.data;
- break;
- }
+ break;
+ }
set_windres_bfd_content (wrbfd, hp, off, len);
- }
+ }
off += len;
}
return off;
@@ -1899,13 +2151,13 @@ res_to_bin_stringtable (windres_bfd *wrbfd, rc_uint_type off,
bfd_byte *hp;
rc_uint_type j;
- hp = (bfd_byte *) reswr_alloc (length);
+ hp = reswr_alloc (length);
windres_put_16 (wrbfd, hp, slen);
- for (j = 0; j < slen; j++)
+ for (j = 0; j < slen; j++)
windres_put_16 (wrbfd, hp + 2 + j * 2, s[j]);
set_windres_bfd_content (wrbfd, hp, off, length);
- }
+ }
off += length;
}
return off;
@@ -1926,7 +2178,7 @@ string_to_unicode_bin (windres_bfd *wrbfd, rc_uint_type off, const char *s)
rc_uint_type i;
bfd_byte *hp;
- hp = (bfd_byte *) reswr_alloc ((len + 1) * sizeof (unichar));
+ hp = reswr_alloc ((len + 1) * sizeof (unichar));
for (i = 0; i < len; i++)
windres_put_16 (wrbfd, hp + i * 2, s[i]);
@@ -1953,7 +2205,7 @@ res_to_bin_toolbar (windres_bfd *wrbfd, rc_uint_type off, rc_toolbar *tb)
bfd_byte *ids;
rc_uint_type i = 0;
- ids = (bfd_byte *) reswr_alloc (tb->nitems * 4);
+ ids = reswr_alloc (tb->nitems * 4);
it=tb->items;
while(it != NULL)
{
@@ -1992,7 +2244,7 @@ res_to_bin_versioninfo (windres_bfd *wrbfd, rc_uint_type off,
struct bin_fixed_versioninfo bfv;
const rc_fixed_versioninfo *fi;
- fi = versioninfo->fixed;
+ fi = versioninfo->fixed;
windres_put_32 (wrbfd, bfv.sig1, 0xfeef04bd);
windres_put_32 (wrbfd, bfv.sig2, 0x10000);
windres_put_32 (wrbfd, bfv.file_version, fi->file_version_ms);
@@ -2119,13 +2371,13 @@ res_to_bin_versioninfo (windres_bfd *wrbfd, rc_uint_type off,
off += 4;
}
if (wrbfd)
- {
+ {
windres_put_16 (wrbfd, bvvd.size, off - vvd_off);
windres_put_16 (wrbfd, bvvd.sig1, off - vvvd_off);
windres_put_16 (wrbfd, bvvd.sig2, 0);
set_windres_bfd_content (wrbfd, &bvvd, vvd_off,
BIN_VER_INFO_SIZE);
- }
+ }
break;
}
@@ -2146,7 +2398,7 @@ res_to_bin_versioninfo (windres_bfd *wrbfd, rc_uint_type off,
windres_put_16 (wrbfd, bvi.size, off - start);
windres_put_16 (wrbfd, bvi.fixed_size,
versioninfo->fixed == NULL ? 0
- : BIN_FIXED_VERSIONINFO_SIZE);
+ : BIN_FIXED_VERSIONINFO_SIZE);
windres_put_16 (wrbfd, bvi.sig2, 0);
set_windres_bfd_content (wrbfd, &bvi, start, BIN_VER_INFO_SIZE);
}
diff --git a/binutils/rescoff.c b/binutils/rescoff.c
index f9a1e70..6031602 100644
--- a/binutils/rescoff.c
+++ b/binutils/rescoff.c
@@ -120,27 +120,41 @@ read_coff_rsrc (const char *filename, const char *target)
struct coff_file_info flaginfo;
if (filename == NULL)
- fatal (_("filename required for COFF input"));
+ {
+ non_fatal (_("filename required for COFF input"));
+ return NULL;
+ }
abfd = bfd_openr (filename, target);
if (abfd == NULL)
- bfd_fatal (filename);
+ {
+ bfd_nonfatal (filename);
+ return NULL;
+ }
if (! bfd_check_format_matches (abfd, bfd_object, &matching))
{
bfd_nonfatal (bfd_get_filename (abfd));
if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
list_matching_formats (matching);
- xexit (1);
+ free (matching);
+ bfd_close (abfd);
+ return NULL;
}
if (bfd_get_flavour (abfd) != bfd_target_coff_flavour
|| !obj_pe (abfd))
- fatal (_("%s: not a PE file"), filename);
+ {
+ non_fatal (_("%s: not a PE file"), filename);
+ bfd_close (abfd);
+ return NULL;
+ }
sec = bfd_get_section_by_name (abfd, ".rsrc");
if (sec == NULL)
{
- fatal (_("%s: no resource section"), filename);
+ non_fatal (_("%s: no resource section"), filename);
+ bfd_close (abfd);
+ return NULL;
}
set_windres_bfd (&wrbfd, abfd, sec, WR_KIND_BFD);
@@ -150,7 +164,11 @@ read_coff_rsrc (const char *filename, const char *target)
but there is no other way to determine if the section size
is reasonable. */
if (size > (bfd_size_type) get_file_size (filename))
- fatal (_("%s: .rsrc section is bigger than the file!"), filename);
+ {
+ non_fatal (_("%s: .rsrc section is bigger than the file!"), filename);
+ bfd_close (abfd);
+ return NULL;
+ }
data = (bfd_byte *) res_alloc (size);
get_windres_bfd_content (&wrbfd, data, 0, size);
@@ -178,7 +196,7 @@ read_coff_rsrc (const char *filename, const char *target)
static void
overrun (const struct coff_file_info *flaginfo, const char *msg)
{
- fatal (_("%s: %s: address out of bounds"), flaginfo->filename, msg);
+ non_fatal (_("%s: %s: address out of bounds"), flaginfo->filename, msg);
}
/* Read a resource directory. */
@@ -199,10 +217,17 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
Microsoft only defines 3 levels. Corrupt files however might
claim to use more. */
if (level > 4)
- fatal (_("%s: resources nest too deep"), flaginfo->filename);
+ {
+ non_fatal (_("%s: resources nest too deep"), flaginfo->filename);
+ return NULL;
+ }
- if ((size_t) (flaginfo->data_end - data) < sizeof (struct extern_res_directory))
- overrun (flaginfo, _("directory"));
+ size_t data_len = flaginfo->data_end - data;
+ if (data_len < sizeof (struct extern_res_directory))
+ {
+ overrun (flaginfo, _("directory"));
+ return NULL;
+ }
erd = (const struct extern_res_directory *) data;
@@ -229,8 +254,12 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
const bfd_byte *ers;
int length, j;
- if ((const bfd_byte *) ere >= flaginfo->data_end)
- overrun (flaginfo, _("named directory entry"));
+ if ((const bfd_byte *) ere > flaginfo->data_end
+ || flaginfo->data_end - (const bfd_byte *) ere < 8)
+ {
+ overrun (flaginfo, _("named directory entry"));
+ return NULL;
+ }
name = windres_get_32 (wrbfd, ere->name, 4);
rva = windres_get_32 (wrbfd, ere->rva, 4);
@@ -238,24 +267,32 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
/* For some reason the high bit in NAME is set. */
name &=~ 0x80000000;
- if (name > (rc_uint_type) (flaginfo->data_end - flaginfo->data))
- overrun (flaginfo, _("directory entry name"));
+ if (name > data_len)
+ {
+ overrun (flaginfo, _("directory entry name"));
+ return NULL;
+ }
ers = flaginfo->data + name;
-
+ if (flaginfo->data_end - ers < 2)
+ {
+ overrun (flaginfo, _("resource name"));
+ return NULL;
+ }
+ length = windres_get_16 (wrbfd, ers, 2);
+ /* PR 17512: file: 05dc4a16. */
+ if (length * 2 + 4 > flaginfo->data_end - ers)
+ {
+ overrun (flaginfo, _("resource name"));
+ return NULL;
+ }
re = (rc_res_entry *) res_alloc (sizeof *re);
re->next = NULL;
re->id.named = 1;
- length = windres_get_16 (wrbfd, ers, 2);
re->id.u.n.length = length;
re->id.u.n.name = (unichar *) res_alloc (length * sizeof (unichar));
for (j = 0; j < length; j++)
- {
- /* PR 17512: file: 05dc4a16. */
- if (length < 0 || ers >= flaginfo->data_end || ers + j * 2 + 4 >= flaginfo->data_end)
- overrun (flaginfo, _("resource name"));
- re->id.u.n.name[j] = windres_get_16 (wrbfd, ers + j * 2 + 2, 2);
- }
+ re->id.u.n.name[j] = windres_get_16 (wrbfd, ers + j * 2 + 2, 2);
if (level == 0)
type = &re->id;
@@ -263,18 +300,25 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
if ((rva & 0x80000000) != 0)
{
rva &=~ 0x80000000;
- if (rva >= (rc_uint_type) (flaginfo->data_end - flaginfo->data))
- overrun (flaginfo, _("named subdirectory"));
+ if (rva >= data_len)
+ {
+ overrun (flaginfo, _("named subdirectory"));
+ return NULL;
+ }
re->subdir = 1;
- re->u.dir = read_coff_res_dir (wrbfd, flaginfo->data + rva, flaginfo, type,
- level + 1);
+ re->u.dir = read_coff_res_dir (wrbfd, flaginfo->data + rva, flaginfo,
+ type, level + 1);
}
else
{
- if (rva >= (rc_uint_type) (flaginfo->data_end - flaginfo->data))
- overrun (flaginfo, _("named resource"));
+ if (rva >= data_len)
+ {
+ overrun (flaginfo, _("named resource"));
+ return NULL;
+ }
re->subdir = 0;
- re->u.res = read_coff_data_entry (wrbfd, flaginfo->data + rva, flaginfo, type);
+ re->u.res = read_coff_data_entry (wrbfd, flaginfo->data + rva,
+ flaginfo, type);
}
*pp = re;
@@ -286,8 +330,12 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
unsigned long name, rva;
rc_res_entry *re;
- if ((const bfd_byte *) ere >= flaginfo->data_end)
- overrun (flaginfo, _("ID directory entry"));
+ if ((const bfd_byte *) ere > flaginfo->data_end
+ || flaginfo->data_end - (const bfd_byte *) ere < 8)
+ {
+ overrun (flaginfo, _("ID directory entry"));
+ return NULL;
+ }
name = windres_get_32 (wrbfd, ere->name, 4);
rva = windres_get_32 (wrbfd, ere->rva, 4);
@@ -303,18 +351,25 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
if ((rva & 0x80000000) != 0)
{
rva &=~ 0x80000000;
- if (rva >= (rc_uint_type) (flaginfo->data_end - flaginfo->data))
- overrun (flaginfo, _("ID subdirectory"));
+ if (rva >= data_len)
+ {
+ overrun (flaginfo, _("ID subdirectory"));
+ return NULL;
+ }
re->subdir = 1;
- re->u.dir = read_coff_res_dir (wrbfd, flaginfo->data + rva, flaginfo, type,
- level + 1);
+ re->u.dir = read_coff_res_dir (wrbfd, flaginfo->data + rva, flaginfo,
+ type, level + 1);
}
else
{
- if (rva >= (rc_uint_type) (flaginfo->data_end - flaginfo->data))
- overrun (flaginfo, _("ID resource"));
+ if (rva >= data_len)
+ {
+ overrun (flaginfo, _("ID resource"));
+ return NULL;
+ }
re->subdir = 0;
- re->u.res = read_coff_data_entry (wrbfd, flaginfo->data + rva, flaginfo, type);
+ re->u.res = read_coff_data_entry (wrbfd, flaginfo->data + rva,
+ flaginfo, type);
}
*pp = re;
@@ -337,10 +392,16 @@ read_coff_data_entry (windres_bfd *wrbfd, const bfd_byte *data,
const bfd_byte *resdata;
if (type == NULL)
- fatal (_("resource type unknown"));
+ {
+ non_fatal (_("resource type unknown"));
+ return NULL;
+ }
if ((size_t) (flaginfo->data_end - data) < sizeof (struct extern_res_data))
- overrun (flaginfo, _("data entry"));
+ {
+ overrun (flaginfo, _("data entry"));
+ return NULL;
+ }
erd = (const struct extern_res_data *) data;
@@ -348,18 +409,26 @@ read_coff_data_entry (windres_bfd *wrbfd, const bfd_byte *data,
rva = windres_get_32 (wrbfd, erd->rva, 4);
if (rva < flaginfo->secaddr
|| rva - flaginfo->secaddr >= (rc_uint_type) (flaginfo->data_end - flaginfo->data))
- overrun (flaginfo, _("resource data"));
+ {
+ overrun (flaginfo, _("resource data"));
+ return NULL;
+ }
resdata = flaginfo->data + (rva - flaginfo->secaddr);
if (size > (rc_uint_type) (flaginfo->data_end - resdata))
- overrun (flaginfo, _("resource data size"));
+ {
+ overrun (flaginfo, _("resource data size"));
+ return NULL;
+ }
r = bin_to_res (wrbfd, *type, resdata, size);
-
- memset (&r->res_info, 0, sizeof (rc_res_res_info));
- r->coff_info.codepage = windres_get_32 (wrbfd, erd->codepage, 4);
- r->coff_info.reserved = windres_get_32 (wrbfd, erd->reserved, 4);
+ if (r != NULL)
+ {
+ memset (&r->res_info, 0, sizeof (rc_res_res_info));
+ r->coff_info.codepage = windres_get_32 (wrbfd, erd->codepage, 4);
+ r->coff_info.reserved = windres_get_32 (wrbfd, erd->reserved, 4);
+ }
return r;
}
@@ -422,9 +491,9 @@ struct coff_write_info
static void coff_bin_sizes (const rc_res_directory *, struct coff_write_info *);
static bfd_byte *coff_alloc (struct bindata_build *, rc_uint_type);
-static void coff_to_bin
+static bool coff_to_bin
(const rc_res_directory *, struct coff_write_info *);
-static void coff_res_to_bin
+static bool coff_res_to_bin
(const rc_res_resource *, struct coff_write_info *);
/* Write resources to a COFF file. RESOURCES should already be
@@ -435,7 +504,7 @@ static void coff_res_to_bin
would require doing the basic work of objcopy, just modifying or
adding the .rsrc section. */
-void
+bool
write_coff_file (const char *filename, const char *target,
const rc_res_directory *resources)
{
@@ -448,44 +517,86 @@ write_coff_file (const char *filename, const char *target,
unsigned long length, offset;
if (filename == NULL)
- fatal (_("filename required for COFF output"));
+ {
+ non_fatal (_("filename required for COFF output"));
+ return false;
+ }
abfd = bfd_openw (filename, target);
if (abfd == NULL)
- bfd_fatal (filename);
+ {
+ bfd_nonfatal (filename);
+ return false;
+ }
if (! bfd_set_format (abfd, bfd_object))
- bfd_fatal ("bfd_set_format");
+ {
+ bfd_nonfatal ("bfd_set_format");
+ bfd_close_all_done (abfd);
+ return false;
+ }
#if defined DLLTOOL_SH
if (! bfd_set_arch_mach (abfd, bfd_arch_sh, 0))
- bfd_fatal ("bfd_set_arch_mach(sh)");
+ {
+ bfd_nonfatal ("bfd_set_arch_mach(sh)");
+ bfd_close_all_done (abfd);
+ return false;
+ }
#elif defined DLLTOOL_MIPS
if (! bfd_set_arch_mach (abfd, bfd_arch_mips, 0))
- bfd_fatal ("bfd_set_arch_mach(mips)");
+ {
+ bfd_nonfatal ("bfd_set_arch_mach(mips)");
+ bfd_close_all_done (abfd);
+ return false;
+ }
#elif defined DLLTOOL_ARM
if (! bfd_set_arch_mach (abfd, bfd_arch_arm, 0))
- bfd_fatal ("bfd_set_arch_mach(arm)");
+ {
+ bfd_nonfatal ("bfd_set_arch_mach(arm)");
+ bfd_close_all_done (abfd);
+ return false;
+ }
#elif defined DLLTOOL_AARCH64
if (! bfd_set_arch_mach (abfd, bfd_arch_aarch64, 0))
- bfd_fatal ("bfd_set_arch_mach(aarch64)");
+ {
+ bfd_nonfatal ("bfd_set_arch_mach(aarch64)");
+ bfd_close_all_done (abfd);
+ return false;
+ }
#else
/* FIXME: This is obviously i386 specific. */
if (! bfd_set_arch_mach (abfd, bfd_arch_i386, 0))
- bfd_fatal ("bfd_set_arch_mach(i386)");
+ {
+ bfd_nonfatal ("bfd_set_arch_mach(i386)");
+ bfd_close_all_done (abfd);
+ return false;
+ }
#endif
if (! bfd_set_file_flags (abfd, HAS_SYMS | HAS_RELOC))
- bfd_fatal ("bfd_set_file_flags");
+ {
+ bfd_nonfatal ("bfd_set_file_flags");
+ bfd_close_all_done (abfd);
+ return false;
+ }
sec = bfd_make_section_with_flags (abfd, ".rsrc",
(SEC_HAS_CONTENTS | SEC_ALLOC
| SEC_LOAD | SEC_DATA | SEC_READONLY));
if (sec == NULL)
- bfd_fatal ("bfd_make_section");
+ {
+ bfd_nonfatal ("bfd_make_section");
+ bfd_close_all_done (abfd);
+ return false;
+ }
if (! bfd_set_symtab (abfd, &sec->symbol, 1))
- bfd_fatal ("bfd_set_symtab");
+ {
+ bfd_nonfatal ("bfd_set_symtab");
+ bfd_close_all_done (abfd);
+ return false;
+ }
/* Requiring this is probably a bug in BFD. */
sec->output_section = sec;
@@ -529,7 +640,12 @@ write_coff_file (const char *filename, const char *target,
cwi.dirstrsize = (cwi.dirstrsize + 7) & ~7;
/* Actually convert the resources to binary. */
- coff_to_bin (resources, &cwi);
+ if (!coff_to_bin (resources, &cwi))
+ {
+ bfd_close_all_done (abfd);
+ free (cwi.relocs);
+ return false;
+ }
/* Add another few bytes to the directory strings if needed for
alignment. */
@@ -554,7 +670,12 @@ write_coff_file (const char *filename, const char *target,
+ cwi.resources.length);
if (!bfd_set_section_size (sec, length))
- bfd_fatal ("bfd_set_section_size");
+ {
+ bfd_nonfatal ("bfd_set_section_size");
+ bfd_close_all_done (abfd);
+ free (cwi.relocs);
+ return false;
+ }
bfd_set_reloc (abfd, sec, cwi.relocs, cwi.reloc_count);
@@ -562,7 +683,12 @@ write_coff_file (const char *filename, const char *target,
for (d = cwi.dirs.d; d != NULL; d = d->next)
{
if (! bfd_set_section_contents (abfd, sec, d->data, offset, d->length))
- bfd_fatal ("bfd_set_section_contents");
+ {
+ bfd_nonfatal ("bfd_set_section_contents");
+ bfd_close_all_done (abfd);
+ free (cwi.relocs);
+ return false;
+ }
offset += d->length;
}
for (d = cwi.dirstrs.d; d != NULL; d = d->next)
@@ -577,17 +703,28 @@ write_coff_file (const char *filename, const char *target,
}
for (rd = cwi.resources.d; rd != NULL; rd = rd->next)
{
- res_to_bin (cwi.wrbfd, (rc_uint_type) offset, rd->res);
+ if (res_to_bin (cwi.wrbfd, (rc_uint_type) offset, rd->res)
+ == (rc_uint_type) -1)
+ {
+ bfd_close_all_done (abfd);
+ free (cwi.relocs);
+ return false;
+ }
offset += rd->length;
}
assert (offset == length);
if (! bfd_close (abfd))
- bfd_fatal ("bfd_close");
+ {
+ bfd_nonfatal ("bfd_close");
+ free (cwi.relocs);
+ return false;
+ }
/* We allocated the relocs array using malloc. */
free (cwi.relocs);
+ return true;
}
/* Work out the sizes of the various fixed size resource directory
@@ -640,7 +777,7 @@ coff_alloc (struct bindata_build *bb, rc_uint_type size)
/* Convert the resource directory RESDIR to binary. */
-static void
+static bool
coff_to_bin (const rc_res_directory *resdir, struct coff_write_info *cwi)
{
struct extern_res_directory *erd;
@@ -701,21 +838,24 @@ coff_to_bin (const rc_res_directory *resdir, struct coff_write_info *cwi)
if (e->subdir)
{
windres_put_32 (cwi->wrbfd, ere->rva, 0x80000000 | cwi->dirs.length);
- coff_to_bin (e->u.dir, cwi);
+ if (!coff_to_bin (e->u.dir, cwi))
+ return false;
}
else
{
windres_put_32 (cwi->wrbfd, ere->rva,
- cwi->dirsize + cwi->dirstrsize + cwi->dataents.length);
+ cwi->dirsize + cwi->dirstrsize + cwi->dataents.length);
- coff_res_to_bin (e->u.res, cwi);
+ if (!coff_res_to_bin (e->u.res, cwi))
+ return false;
}
}
+ return true;
}
/* Convert the resource RES to binary. */
-static void
+static bool
coff_res_to_bin (const rc_res_resource *res, struct coff_write_info *cwi)
{
arelent *r;
@@ -735,7 +875,10 @@ coff_res_to_bin (const rc_res_resource *res, struct coff_write_info *cwi)
r->addend = 0;
r->howto = bfd_reloc_type_lookup (WR_BFD (cwi->wrbfd), BFD_RELOC_RVA);
if (r->howto == NULL)
- bfd_fatal (_("can't get BFD_RELOC_RVA relocation type"));
+ {
+ bfd_nonfatal (_("can't get BFD_RELOC_RVA relocation type"));
+ return false;
+ }
cwi->relocs = xrealloc (cwi->relocs,
(cwi->reloc_count + 2) * sizeof (arelent *));
@@ -755,6 +898,8 @@ coff_res_to_bin (const rc_res_resource *res, struct coff_write_info *cwi)
d = (coff_res_data *) reswr_alloc (sizeof (coff_res_data));
d->length = res_to_bin (NULL, (rc_uint_type) 0, res);
+ if (d->length == (rc_uint_type) -1)
+ return false;
d->res = res;
d->next = NULL;
@@ -770,4 +915,5 @@ coff_res_to_bin (const rc_res_resource *res, struct coff_write_info *cwi)
/* Force the next resource to have 64 bit alignment. */
d->length = (d->length + 7) & ~7;
+ return true;
}
diff --git a/binutils/resrc.c b/binutils/resrc.c
index d265818..8f9451b 100644
--- a/binutils/resrc.c
+++ b/binutils/resrc.c
@@ -1938,7 +1938,7 @@ indent (FILE *e, int c)
refer to that file, we use the user-data model for that to express it binary
without the need to store it somewhere externally. */
-void
+bool
write_rc_file (const char *filename, const rc_res_directory *res_dir)
{
FILE *e;
@@ -1950,12 +1950,17 @@ write_rc_file (const char *filename, const rc_res_directory *res_dir)
{
e = fopen (filename, FOPEN_WT);
if (e == NULL)
- fatal (_("can't open `%s' for output: %s"), filename, strerror (errno));
+ {
+ non_fatal (_("can't open `%s' for output: %s"),
+ filename, strerror (errno));
+ return false;
+ }
}
language = (rc_uint_type) ((bfd_signed_vma) -1);
write_rc_directory (e, res_dir, (const rc_res_id *) NULL,
(const rc_res_id *) NULL, &language, 1);
+ return true;
}
/* Write out a directory. E is the file to write to. RD is the
diff --git a/binutils/resres.c b/binutils/resres.c
index ab5aa66..d96fb14 100644
--- a/binutils/resres.c
+++ b/binutils/resres.c
@@ -109,14 +109,14 @@ read_res_file (const char *fn)
}
/* Write resource file */
-void
+bool
write_res_file (const char *fn,const rc_res_directory *resdir)
{
asection *sec;
rc_uint_type language;
bfd *abfd;
windres_bfd wrbfd;
- unsigned long sec_length = 0,sec_length_wrote;
+ rc_uint_type sec_length = 0, sec_length_wrote;
static const bfd_byte sign[] =
{0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
@@ -130,7 +130,10 @@ write_res_file (const char *fn,const rc_res_directory *resdir)
(SEC_HAS_CONTENTS | SEC_ALLOC
| SEC_LOAD | SEC_DATA));
if (sec == NULL)
- bfd_fatal ("bfd_make_section");
+ {
+ bfd_nonfatal ("bfd_make_section");
+ return false;
+ }
/* Requiring this is probably a bug in BFD. */
sec->output_section = sec;
@@ -142,8 +145,13 @@ write_res_file (const char *fn,const rc_res_directory *resdir)
sec_length = write_res_directory ((windres_bfd *) NULL, 0x20UL, resdir,
(const rc_res_id *) NULL,
(const rc_res_id *) NULL, &language, 1);
+ if (sec_length == (rc_uint_type) -1)
+ return false;
if (!bfd_set_section_size (sec, (sec_length + 3) & ~3))
- bfd_fatal ("bfd_set_section_size");
+ {
+ bfd_nonfatal ("bfd_set_section_size");
+ return false;
+ }
if ((sec_length & 3) != 0)
set_windres_bfd_content (&wrbfd, sign, sec_length, 4-(sec_length & 3));
set_windres_bfd_content (&wrbfd, sign, 0, sizeof (sign));
@@ -152,12 +160,16 @@ write_res_file (const char *fn,const rc_res_directory *resdir)
(const rc_res_id *) NULL,
(const rc_res_id *) NULL,
&language, 1);
+ if (sec_length_wrote == (rc_uint_type) -1)
+ return false;
if (sec_length != sec_length_wrote)
- fatal ("res write failed with different sizes (%lu/%lu).",
- (unsigned long) sec_length, (unsigned long) sec_length_wrote);
+ {
+ non_fatal ("res write failed with different sizes (%lu/%lu).",
+ (unsigned long) sec_length, (unsigned long) sec_length_wrote);
+ return false;
+ }
- bfd_close (abfd);
- return;
+ return bfd_close (abfd);
}
/* Read a resource entry, returns 0 when all resources are read */
@@ -252,8 +264,12 @@ write_res_directory (windres_bfd *wrbfd, rc_uint_type off, const rc_res_director
}
if (re->subdir)
- off = write_res_directory (wrbfd, off, re->u.dir, type, name, language,
- level + 1);
+ {
+ off = write_res_directory (wrbfd, off, re->u.dir, type, name, language,
+ level + 1);
+ if (off == (rc_uint_type) -1)
+ return off;
+ }
else
{
if (level == 3)
@@ -265,12 +281,16 @@ write_res_directory (windres_bfd *wrbfd, rc_uint_type off, const rc_res_director
resource itself records if anything. */
off = write_res_resource (wrbfd, off, type, name, re->u.res,
language);
+ if (off == (rc_uint_type) -1)
+ return off;
}
else
{
fprintf (stderr, "// Resource at unexpected level %d\n", level);
off = write_res_resource (wrbfd, off, type, (rc_res_id *) NULL,
re->u.res, language);
+ if (off == (rc_uint_type) -1)
+ return off;
}
}
}
@@ -378,6 +398,8 @@ write_res_bin (windres_bfd *wrbfd, rc_uint_type off, const rc_res_resource *res,
rc_uint_type datasize = 0;
noff = res_to_bin ((windres_bfd *) NULL, off, res);
+ if (noff == (rc_uint_type) -1)
+ return noff;
datasize = noff - off;
off = write_res_header (wrbfd, off, datasize, type, name, resinfo);
diff --git a/binutils/windres.c b/binutils/windres.c
index 18062f5..b41353b 100644
--- a/binutils/windres.c
+++ b/binutils/windres.c
@@ -1056,23 +1056,24 @@ main (int argc, char **argv)
/* Write the output file. */
reswr_init ();
+ bool ok;
switch (output_format)
{
default:
abort ();
case RES_FORMAT_RC:
- write_rc_file (output_filename, resources);
+ ok = write_rc_file (output_filename, resources);
break;
case RES_FORMAT_RES:
- write_res_file (output_filename, resources);
+ ok = write_res_file (output_filename, resources);
break;
case RES_FORMAT_COFF:
- write_coff_file (output_filename, target, resources);
+ ok = write_coff_file (output_filename, target, resources);
break;
}
- xexit (0);
- return 0;
+ xexit (ok ? 0 : 1);
+ return ok ? 0 : 1;
}
static void
@@ -1094,13 +1095,18 @@ windres_open_as_binary (const char *filename, int rdmode)
{
bfd *abfd;
- abfd = (rdmode ? bfd_openr (filename, "binary") : bfd_openw (filename, "binary"));
- if (! abfd)
- fatal ("can't open `%s' for %s", filename, (rdmode ? "input" : "output"));
-
- if (rdmode && ! bfd_check_format (abfd, bfd_object))
- fatal ("can't open `%s' for input.", filename);
-
+ if (rdmode)
+ {
+ abfd = bfd_openr (filename, "binary");
+ if (abfd == NULL || !bfd_check_format (abfd, bfd_object))
+ fatal ("can't open `%s' for input", filename);
+ }
+ else
+ {
+ abfd = bfd_openw (filename, "binary");
+ if (abfd == NULL || !bfd_set_format (abfd, bfd_object))
+ fatal ("can't open `%s' for output", filename);
+ }
return abfd;
}
diff --git a/binutils/windres.h b/binutils/windres.h
index 309564e..15c6ad0 100644
--- a/binutils/windres.h
+++ b/binutils/windres.h
@@ -35,9 +35,9 @@ extern int verbose;
extern rc_res_directory *read_rc_file (const char *, const char *, const char *, int, int);
extern rc_res_directory *read_res_file (const char *);
extern rc_res_directory *read_coff_rsrc (const char *, const char *);
-extern void write_rc_file (const char *, const rc_res_directory *);
-extern void write_res_file (const char *, const rc_res_directory *);
-extern void write_coff_file (const char *, const char *, const rc_res_directory *);
+extern bool write_rc_file (const char *, const rc_res_directory *);
+extern bool write_res_file (const char *, const rc_res_directory *);
+extern bool write_coff_file (const char *, const char *, const rc_res_directory *);
extern rc_res_resource *bin_to_res (windres_bfd *, rc_res_id, const bfd_byte *,
rc_uint_type);
diff --git a/gas/config/loongarch-parse.y b/gas/config/loongarch-parse.y
index 97055fe..b75040c 100644
--- a/gas/config/loongarch-parse.y
+++ b/gas/config/loongarch-parse.y
@@ -207,29 +207,41 @@ emit_bin (int op)
switch (op)
{
case '*':
- opr1 = opr1 * opr2;
+ opr1 = (valueT) opr1 * (valueT) opr2;
break;
case '/':
- opr1 = opr1 / opr2;
+ if (opr2 == 0)
+ {
+ as_warn (_("Divide by zero!"));
+ opr1 = 0;
+ }
+ else
+ opr1 = opr1 / opr2;
break;
case '%':
- opr1 = opr1 % opr2;
+ if (opr2 == 0)
+ {
+ as_warn (_("Divide by zero!"));
+ opr1 = 0;
+ }
+ else
+ opr1 = opr1 % opr2;
break;
case '+':
- opr1 = opr1 + opr2;
+ opr1 = (valueT) opr1 + (valueT) opr2;
break;
case '-':
- opr1 = opr1 - opr2;
+ opr1 = (valueT) opr1 - (valueT) opr2;
break;
case LEFT_OP:
- opr1 = opr1 << opr2;
+ opr1 = (valueT) opr1 << opr2;
break;
case RIGHT_OP:
if (opr1 < 0)
- as_warn(_("Right shift of negative numbers may be changed "
- "from arithmetic right shift to logical right shift!"));
- /* Algorithm right shift. */
- opr1 = (offsetT)opr1 >> (offsetT)opr2;
+ as_warn (_("Right shift of negative numbers may be changed "
+ "from arithmetic right shift to logical right shift!"));
+ /* Arithmetic right shift. */
+ opr1 = opr1 >> opr2;
break;
case '<':
opr1 = opr1 < opr2;
diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c
index 0f36741..46b26d4 100644
--- a/gas/config/tc-m68k.c
+++ b/gas/config/tc-m68k.c
@@ -6754,7 +6754,6 @@ s_mri_for (int qual)
struct mri_control_info *n;
char *buf;
char *s;
- char ex[2];
/* The syntax is
FOR.q var = init { TO | DOWNTO } end [ BY by ] DO.e
@@ -6935,12 +6934,14 @@ s_mri_for (int qual)
mri_assemble (buf);
/* bcc bottom. */
- ex[0] = TOLOWER (extent);
- ex[1] = '\0';
- if (up)
- sprintf (buf, "blt%s %s", ex, n->bottom);
- else
- sprintf (buf, "bgt%s %s", ex, n->bottom);
+ s = buf;
+ *s++ = 'b';
+ *s++ = up ? 'l' : 'g';
+ *s++ = 't';
+ if (extent != '\0')
+ *s++ = TOLOWER (extent);
+ *s++ = ' ';
+ strcpy (s, n->bottom);
mri_assemble (buf);
/* Put together the add or sub instruction used by ENDF. */
diff --git a/gas/testsuite/gas/loongarch/fix_op.d b/gas/testsuite/gas/loongarch/fix_op.d
index 7125f2e..05e7403 100644
--- a/gas/testsuite/gas/loongarch/fix_op.d
+++ b/gas/testsuite/gas/loongarch/fix_op.d
@@ -132,3 +132,6 @@ Disassembly of section .text:
[ ]+1e8:[ ]+00df04a4 [ ]+bstrpick.d[ ]+[ ]+\$a0, \$a1, 0x1f, 0x1
[ ]+1ec:[ ]+00e000a4 [ ]+bstrpick.d[ ]+[ ]+\$a0, \$a1, 0x20, 0x0
[ ]+1f0:[ ]+00ff00a4 [ ]+bstrpick.d[ ]+[ ]+\$a0, \$a1, 0x3f, 0x0
+[ ]+1f4:[ ]+00006004 [ ]+rdcntvl.w[ ]+[ ]+\$a0
+[ ]+1f8:[ ]+000060a0 [ ]+rdcntid.w[ ]+[ ]+\$a1
+[ ]+1fc:[ ]+00006404 [ ]+rdcntvh.w[ ]+[ ]+\$a0
diff --git a/gas/testsuite/gas/loongarch/fix_op.s b/gas/testsuite/gas/loongarch/fix_op.s
index d0523f9..876913b 100644
--- a/gas/testsuite/gas/loongarch/fix_op.s
+++ b/gas/testsuite/gas/loongarch/fix_op.s
@@ -123,3 +123,8 @@ bstrpick.d $r4,$r5,0,0
bstrpick.d $r4,$r5,31,1
bstrpick.d $r4,$r5,32,0
bstrpick.d $r4,$r5,63,0
+
+# LA32R aliases
+rdcntvl.w $r4
+rdcntid.w $r5
+rdcntvh.w $r4
diff --git a/gas/testsuite/gas/loongarch/insn_alias_32.d b/gas/testsuite/gas/loongarch/insn_alias_32.d
index 753eae7..3aa716f 100644
--- a/gas/testsuite/gas/loongarch/insn_alias_32.d
+++ b/gas/testsuite/gas/loongarch/insn_alias_32.d
@@ -17,3 +17,6 @@ Disassembly of section .text:
18: 60000080 blt \$a0, \$zero, 0 # 18 <L1\+0x18>
1c: 64000080 bge \$a0, \$zero, 0 # 1c <L1\+0x1c>
20: 64000004 bge \$zero, \$a0, 0 # 20 <L1\+0x20>
+ 24: 00006004 rdtimel.w \$a0, \$zero
+ 28: 000060a0 rdtimel.w \$zero, \$a1
+ 2c: 00006406 rdtimeh.w \$a2, \$zero
diff --git a/gas/testsuite/gas/loongarch/insn_alias_32.s b/gas/testsuite/gas/loongarch/insn_alias_32.s
index 8027e32..492e52a 100644
--- a/gas/testsuite/gas/loongarch/insn_alias_32.s
+++ b/gas/testsuite/gas/loongarch/insn_alias_32.s
@@ -8,3 +8,8 @@ L1:
bltz $a0,.L1
bgez $a0,.L1
blez $a0,.L1
+
+ # LA32R aliases
+ rdcntvl.w $a0
+ rdcntid.w $a1
+ rdcntvh.w $a2
diff --git a/gdb/MAINTAINERS b/gdb/MAINTAINERS
index 187a1f6..5e1aada 100644
--- a/gdb/MAINTAINERS
+++ b/gdb/MAINTAINERS
@@ -724,6 +724,7 @@ Theodore A. Roth troth@openavr.org
Yvan Roux yvan.roux@foss.st.com
Ian Roxborough irox@redhat.com
Maciej W. Rozycki macro@orcam.me.uk
+Piotr Rudnicki piotr.rudnicki@intel.com
Kamil Rytarowski n54@gmx.com
Grace Sainsbury graces@redhat.com
Kei Sakamoto sakamoto.kei@renesas.com
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 9d35440..3f5e707 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -36,7 +36,7 @@
#include "objfiles.h"
#include "breakpoint.h"
#include "gdbcore.h"
-#include "hashtab.h"
+#include "gdbsupport/unordered_set.h"
#include "gdbsupport/gdb_obstack.h"
#include "ada-lang.h"
#include "completer.h"
@@ -52,6 +52,7 @@
#include "namespace.h"
#include "cli/cli-style.h"
#include "cli/cli-decode.h"
+#include "gdbsupport/string-set.h"
#include "value.h"
#include "mi/mi-common.h"
@@ -349,56 +350,58 @@ struct cache_entry_search
{
const char *name;
domain_search_flags domain;
+};
+
+/* Hash function for cache entry. */
+
+struct cache_entry_hash
+{
+ using is_transparent = void;
+ using is_avalanching = void;
- hashval_t hash () const
+ /* This implementation works for both cache_entry and
+ cache_entry_search. */
+ template<typename T>
+ uint64_t operator() (const T &entry) const noexcept
{
- /* This must agree with hash_cache_entry, below. */
- return htab_hash_string (name);
+ return ankerl::unordered_dense::hash<std::string_view> () (entry.name);
}
};
-/* Hash function for cache_entry. */
+/* Equality function for cache entry. */
-static hashval_t
-hash_cache_entry (const void *v)
+struct cache_entry_eq
{
- const cache_entry *entry = (const cache_entry *) v;
- return htab_hash_string (entry->name.c_str ());
-}
-
-/* Equality function for cache_entry. */
+ using is_transparent = void;
-static int
-eq_cache_entry (const void *a, const void *b)
-{
- const cache_entry *entrya = (const cache_entry *) a;
- const cache_entry_search *entryb = (const cache_entry_search *) b;
+ /* This implementation works for both cache_entry and
+ cache_entry_search. */
+ template<typename T>
+ bool operator() (const T &lhs, const cache_entry &rhs) const noexcept
+ {
+ return lhs.domain == rhs.domain && lhs.name == rhs.name;
+ }
+};
- return entrya->domain == entryb->domain && entrya->name == entryb->name;
-}
+using cache_entry_set
+ = gdb::unordered_set<cache_entry, cache_entry_hash, cache_entry_eq>;
/* Key to our per-program-space data. */
-static const registry<program_space>::key<htab, htab_deleter>
+static const registry<program_space>::key<cache_entry_set>
ada_pspace_data_handle;
-/* Return this module's data for the given program space (PSPACE).
- If not is found, add a zero'ed one now.
-
- This function always returns a valid object. */
+/* Return this module's data for the given program space (PSPACE). If
+ not is found, one is created. This function always returns a valid
+ object. */
-static htab_t
+static cache_entry_set &
get_ada_pspace_data (struct program_space *pspace)
{
- htab_t data = ada_pspace_data_handle.get (pspace);
+ cache_entry_set *data = ada_pspace_data_handle.get (pspace);
if (data == nullptr)
- {
- data = htab_create_alloc (10, hash_cache_entry, eq_cache_entry,
- htab_delete_entry<cache_entry>,
- xcalloc, xfree);
- ada_pspace_data_handle.set (pspace, data);
- }
+ data = ada_pspace_data_handle.emplace (pspace);
- return data;
+ return *data;
}
/* Utilities */
@@ -1603,7 +1606,7 @@ ada_decode_tests ()
storage leak, it should not be significant unless there are massive
changes in the set of decoded names in successive versions of a
symbol table loaded during a single session. */
-static struct htab *decoded_names_store;
+static gdb::string_set decoded_names_store;
/* Returns the decoded name of GSYMBOL, as for ada_decode, caching it
in the language-specific part of GSYMBOL, if it has not been
@@ -1637,13 +1640,7 @@ ada_decode_symbol (const struct general_symbol_info *arg)
which case, we put the result on the heap. Since we only
decode when needed, we hope this usually does not cause a
significant memory leak (FIXME). */
-
- char **slot = (char **) htab_find_slot (decoded_names_store,
- decoded.c_str (), INSERT);
-
- if (*slot == NULL)
- *slot = xstrdup (decoded.c_str ());
- *resultp = *slot;
+ *resultp = decoded_names_store.insert (decoded);
}
}
@@ -3950,9 +3947,9 @@ ada_type_match (struct type *ftype, struct type *atype)
atype = ada_check_typedef (atype);
if (ftype->code () == TYPE_CODE_REF)
- ftype = ftype->target_type ();
+ ftype = ada_check_typedef (ftype->target_type ());
if (atype->code () == TYPE_CODE_REF)
- atype = atype->target_type ();
+ atype = ada_check_typedef (atype->target_type ());
switch (ftype->code ())
{
@@ -4695,19 +4692,18 @@ static int
lookup_cached_symbol (const char *name, domain_search_flags domain,
struct symbol **sym, const struct block **block)
{
- htab_t tab = get_ada_pspace_data (current_program_space);
+ cache_entry_set &htab = get_ada_pspace_data (current_program_space);
cache_entry_search search;
search.name = name;
search.domain = domain;
- cache_entry *e = (cache_entry *) htab_find_with_hash (tab, &search,
- search.hash ());
- if (e == nullptr)
+ auto iter = htab.find (search);
+ if (iter == htab.end ())
return 0;
if (sym != nullptr)
- *sym = e->sym;
+ *sym = iter->sym;
if (block != nullptr)
- *block = e->block;
+ *block = iter->block;
return 1;
}
@@ -4735,21 +4731,8 @@ cache_symbol (const char *name, domain_search_flags domain,
return;
}
- htab_t tab = get_ada_pspace_data (current_program_space);
- cache_entry_search search;
- search.name = name;
- search.domain = domain;
-
- void **slot = htab_find_slot_with_hash (tab, &search,
- search.hash (), INSERT);
-
- cache_entry *e = new cache_entry;
- e->name = name;
- e->domain = domain;
- e->sym = sym;
- e->block = block;
-
- *slot = e;
+ cache_entry_set &tab = get_ada_pspace_data (current_program_space);
+ tab.insert (cache_entry {name, domain, sym, block});
}
/* Symbol Lookup */
@@ -14049,10 +14032,6 @@ When enabled, the debugger will stop using the DW_AT_GNAT_descriptive_type\n\
DWARF attribute."),
NULL, NULL, &maint_set_ada_cmdlist, &maint_show_ada_cmdlist);
- decoded_names_store = htab_create_alloc (256, htab_hash_string,
- htab_eq_string,
- NULL, xcalloc, xfree);
-
/* The ada-lang observers. */
gdb::observers::new_objfile.attach (ada_new_objfile_observer, "ada-lang");
gdb::observers::all_objfiles_removed.attach (ada_clear_symbol_cache,
diff --git a/gdb/ada-varobj.c b/gdb/ada-varobj.c
index 140fc71..c87e7be 100644
--- a/gdb/ada-varobj.c
+++ b/gdb/ada-varobj.c
@@ -379,16 +379,14 @@ ada_varobj_get_number_of_children (struct value *parent_value,
whose index is CHILD_INDEX:
- If CHILD_NAME is not NULL, then a copy of the child's name
- is saved in *CHILD_NAME. This copy must be deallocated
- with xfree after use.
+ is saved in *CHILD_NAME.
- If CHILD_VALUE is not NULL, then save the child's value
in *CHILD_VALUE. Same thing for the child's type with
CHILD_TYPE if not NULL.
- If CHILD_PATH_EXPR is not NULL, then compute the child's
- path expression. The resulting string must be deallocated
- after use with xfree.
+ path expression.
Computing the child's path expression requires the PARENT_PATH_EXPR
to be non-NULL. Otherwise, PARENT_PATH_EXPR may be null if
@@ -805,9 +803,7 @@ ada_varobj_get_type_of_child (struct value *parent_value,
}
/* Return a string that contains the image of the given VALUE, using
- the print options OPTS as the options for formatting the result.
-
- The resulting string must be deallocated after use with xfree. */
+ the print options OPTS as the options for formatting the result. */
static std::string
ada_varobj_get_value_image (struct value *value,
@@ -825,9 +821,7 @@ ada_varobj_get_value_image (struct value *value,
in the array inside square brackets, but there are situations where
it's useful to add more info.
- OPTS are the print options used when formatting the result.
-
- The result should be deallocated after use using xfree. */
+ OPTS are the print options used when formatting the result. */
static std::string
ada_varobj_get_value_of_array_variable (struct value *value,
diff --git a/gdb/cli/cli-decode.h b/gdb/cli/cli-decode.h
index 217afbc..9be446f 100644
--- a/gdb/cli/cli-decode.h
+++ b/gdb/cli/cli-decode.h
@@ -62,6 +62,8 @@ struct cmd_list_element
type (not_set_cmd),
doc (doc_)
{
+ gdb_assert (name != nullptr);
+ gdb_assert (doc != nullptr);
memset (&function, 0, sizeof (function));
}
diff --git a/gdb/cli/cli-dump.c b/gdb/cli/cli-dump.c
index 0ecc7b0..3055734 100644
--- a/gdb/cli/cli-dump.c
+++ b/gdb/cli/cli-dump.c
@@ -397,7 +397,7 @@ restore_one_section (bfd *ibfd, asection *isec,
if (sec_end <= load_start
|| (load_end > 0 && sec_start >= load_end))
{
- /* No, no useable data in this section. */
+ /* No, no usable data in this section. */
gdb_printf (_("skipping section %s...\n"),
bfd_section_name (isec));
return;
diff --git a/gdb/config/djgpp/README b/gdb/config/djgpp/README
index 2ae6535..cecc9d0 100644
--- a/gdb/config/djgpp/README
+++ b/gdb/config/djgpp/README
@@ -175,7 +175,7 @@ SOMETHING.tst (where SOMETHING is the name of the failed test). You
should compare each of the *.tst files with the corresponding *.out
file and convince yourself that the differences do not indicate a real
problem. Examples of differences you can disregard are changes in the
-copyright blurb printed by GDB, values of unitialized variables,
+copyright blurb printed by GDB, values of uninitialized variables,
addresses of global variables like argv[] and envp[] (which depend on
the size of your environment), etc.
diff --git a/gdb/config/djgpp/djconfig.sh b/gdb/config/djgpp/djconfig.sh
index 4952a11..05b3bbe 100644
--- a/gdb/config/djgpp/djconfig.sh
+++ b/gdb/config/djgpp/djconfig.sh
@@ -123,7 +123,7 @@ do
done
# Now set the config shell. It is really needed, that the shell
-# points to a shell with full path and also it must conatain the
+# points to a shell with full path and also it must contain the
# .exe suffix. I assume here, that bash is installed. If not,
# install it. Additionally, the pathname must not contain a
# drive letter, so use the /dev/x/foo format supported by versions
diff --git a/gdb/copyright.py b/gdb/copyright.py
index 5ec9944..bd854dc 100755
--- a/gdb/copyright.py
+++ b/gdb/copyright.py
@@ -30,13 +30,16 @@
#
# This removes the bulk of the changes which are most likely to be correct.
+# pyright: strict
+
import argparse
import locale
import os
import os.path
+import pathlib
import subprocess
import sys
-from typing import List, Optional
+from typing import Iterable
def get_update_list():
@@ -66,24 +69,20 @@ def get_update_list():
.split("\0")
)
- def include_file(filename):
- (dirname, basename) = os.path.split(filename)
- dirbasename = os.path.basename(dirname)
- return not (
- basename in EXCLUDE_ALL_LIST
- or dirbasename in EXCLUDE_ALL_LIST
- or dirname in EXCLUDE_LIST
- or dirname in NOT_FSF_LIST
- or dirname in BY_HAND
- or filename in EXCLUDE_LIST
- or filename in NOT_FSF_LIST
- or filename in BY_HAND
- )
+ full_exclude_list = EXCLUDE_LIST + BY_HAND
+
+ def include_file(filename: str):
+ path = pathlib.Path(filename)
+ for pattern in full_exclude_list:
+ if path.full_match(pattern):
+ return False
+
+ return True
return filter(include_file, result)
-def update_files(update_list):
+def update_files(update_list: Iterable[str]):
"""Update the copyright header of the files in the given list.
We use gnulib's update-copyright script for that.
@@ -128,7 +127,7 @@ def update_files(update_list):
print("*** " + line)
-def may_have_copyright_notice(filename):
+def may_have_copyright_notice(filename: str):
"""Check that the given file does not seem to have a copyright notice.
The filename is relative to the root directory.
@@ -166,7 +165,7 @@ def get_parser() -> argparse.ArgumentParser:
return parser
-def main(argv: List[str]) -> Optional[int]:
+def main(argv: list[str]) -> int | None:
"""The main subprogram."""
parser = get_parser()
_ = parser.parse_args(argv)
@@ -210,8 +209,14 @@ def main(argv: List[str]) -> Optional[int]:
# generated, non-FSF, or otherwise special (e.g. license text,
# or test cases which must be sensitive to line numbering).
#
-# Filenames are relative to the root directory.
+# Entries are treated as glob patterns.
EXCLUDE_LIST = (
+ "**/aclocal.m4",
+ "**/configure",
+ "**/COPYING.LIB",
+ "**/COPYING",
+ "**/fdl.texi",
+ "**/gpl.texi",
"gdb/copying.c",
"gdb/nat/glibc_thread_db.h",
"gdb/CONTRIBUTE",
@@ -219,45 +224,11 @@ EXCLUDE_LIST = (
"gdbsupport/unordered_dense.h",
"gnulib/doc/gendocs_template",
"gnulib/doc/gendocs_template_min",
- "gnulib/import",
+ "gnulib/import/**",
"gnulib/config.in",
"gnulib/Makefile.in",
-)
-
-# Files which should not be modified, either because they are
-# generated, non-FSF, or otherwise special (e.g. license text,
-# or test cases which must be sensitive to line numbering).
-#
-# Matches any file or directory name anywhere. Use with caution.
-# This is mostly for files that can be found in multiple directories.
-# Eg: We want all files named COPYING to be left untouched.
-
-EXCLUDE_ALL_LIST = (
- "COPYING",
- "COPYING.LIB",
- "configure",
- "fdl.texi",
- "gpl.texi",
- "aclocal.m4",
-)
-
-# The list of files to update by hand.
-BY_HAND = (
- # Nothing at the moment :-).
-)
-
-# Files containing multiple copyright headers. This script is only
-# fixing the first one it finds, so we need to finish the update
-# by hand.
-MULTIPLE_COPYRIGHT_HEADERS = (
- "gdb/doc/gdb.texinfo",
- "gdb/doc/refcard.tex",
- "gdb/syscalls/update-netbsd.sh",
-)
-
-# The list of file which have a copyright, but not held by the FSF.
-# Filenames are relative to the root directory.
-NOT_FSF_LIST = (
+ "sim/Makefile.in",
+ # The files below have a copyright, but not held by the FSF.
"gdb/exc_request.defs",
"gdb/gdbtk",
"gdb/testsuite/gdb.gdbtk/",
@@ -294,9 +265,27 @@ NOT_FSF_LIST = (
"sim/mips/sim-main.c",
"sim/moxie/moxie-gdb.dts",
# Not a single file in sim/ppc/ appears to be copyright FSF :-(.
- "sim/ppc",
+ "sim/ppc/**",
"sim/testsuite/mips/mips32-dsp2.s",
)
+# The list of files to update by hand.
+#
+# Entries are treated as glob patterns.
+BY_HAND: tuple[str, ...] = (
+ # Nothing at the moment :-).
+)
+
+# Files containing multiple copyright headers. This script is only
+# fixing the first one it finds, so we need to finish the update
+# by hand.
+#
+# Entries are treated as glob patterns.
+MULTIPLE_COPYRIGHT_HEADERS = (
+ "gdb/doc/gdb.texinfo",
+ "gdb/doc/refcard.tex",
+ "gdb/syscalls/update-netbsd.sh",
+)
+
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))
diff --git a/gdb/corelow.c b/gdb/corelow.c
index fc0df25..4518781 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -540,11 +540,41 @@ core_target::build_file_mappings ()
/* If ABFD was opened, but the wrong format, close it now. */
abfd = nullptr;
+ /* When true, this indicates that the mapped contents of this
+ file are available within the core file. When false, some of
+ the mapped contents are not available. If the contents are
+ entirely available within the core file, then we don't need to
+ warn the user if GDB cannot find the file. */
+ bool content_is_in_core_file_p = true;
+
/* Record all regions for this file as unavailable. */
for (const mapped_file::region &region : file_data.regions)
- m_core_unavailable_mappings.emplace_back (region.start,
- region.end
- - region.start);
+ {
+ /* Check to see if the region is available within the core
+ file. */
+ bool found_region_in_core_file = false;
+ for (const target_section &ts : m_core_section_table)
+ {
+ if (ts.addr <= region.start && ts.endaddr >= region.end
+ && (ts.the_bfd_section->flags & SEC_HAS_CONTENTS) != 0)
+ {
+ found_region_in_core_file = true;
+ break;
+ }
+ }
+
+ /* This region is not available within the core file.
+ Without the file available to read from it is not possible
+ for GDB to read this mapping within the inferior. Warn
+ the user about this case. */
+ if (!found_region_in_core_file)
+ content_is_in_core_file_p = false;
+
+ /* Record the unavailable region. */
+ m_core_unavailable_mappings.emplace_back (region.start,
+ region.end
+ - region.start);
+ }
/* And give the user an appropriate warning. */
if (build_id_mismatch)
@@ -564,7 +594,7 @@ core_target::build_file_mappings ()
styled_string (file_name_style.style (),
expanded_fname.get ()));
}
- else
+ else if (!content_is_in_core_file_p)
{
if (expanded_fname == nullptr
|| filename == expanded_fname.get ())
diff --git a/gdb/dwarf2/comp-unit-head.c b/gdb/dwarf2/comp-unit-head.c
index 8ec8897..a35d664 100644
--- a/gdb/dwarf2/comp-unit-head.c
+++ b/gdb/dwarf2/comp-unit-head.c
@@ -26,7 +26,6 @@
#include "dwarf2/comp-unit-head.h"
#include "dwarf2/leb.h"
-#include "dwarf2/read.h"
#include "dwarf2/section.h"
#include "dwarf2/stringify.h"
#include "dwarf2/error.h"
@@ -149,15 +148,13 @@ read_comp_unit_head (struct comp_unit_head *cu_header,
Perform various error checking on the header. */
static void
-error_check_comp_unit_head (dwarf2_per_objfile *per_objfile,
- struct comp_unit_head *header,
- struct dwarf2_section_info *section,
- struct dwarf2_section_info *abbrev_section)
+error_check_comp_unit_head (comp_unit_head *header,
+ dwarf2_section_info *section,
+ dwarf2_section_info *abbrev_section)
{
const char *filename = section->get_file_name ();
- if (to_underlying (header->abbrev_sect_off)
- >= abbrev_section->get_size (per_objfile->objfile))
+ if (to_underlying (header->abbrev_sect_off) >= abbrev_section->size)
error (_(DWARF_ERROR_PREFIX
"bad offset (%s) in compilation unit header "
"(offset %s + 6) [in module %s]"),
@@ -179,12 +176,10 @@ error_check_comp_unit_head (dwarf2_per_objfile *per_objfile,
/* See comp-unit-head.h. */
const gdb_byte *
-read_and_check_comp_unit_head (dwarf2_per_objfile *per_objfile,
- struct comp_unit_head *header,
- struct dwarf2_section_info *section,
- struct dwarf2_section_info *abbrev_section,
- const gdb_byte *info_ptr,
- rcuh_kind section_kind)
+read_and_check_comp_unit_head (comp_unit_head *header,
+ dwarf2_section_info *section,
+ dwarf2_section_info *abbrev_section,
+ const gdb_byte *info_ptr, rcuh_kind section_kind)
{
const gdb_byte *beg_of_comp_unit = info_ptr;
@@ -194,7 +189,7 @@ read_and_check_comp_unit_head (dwarf2_per_objfile *per_objfile,
header->first_die_cu_offset = (cu_offset) (info_ptr - beg_of_comp_unit);
- error_check_comp_unit_head (per_objfile, header, section, abbrev_section);
+ error_check_comp_unit_head (header, section, abbrev_section);
return info_ptr;
}
diff --git a/gdb/dwarf2/comp-unit-head.h b/gdb/dwarf2/comp-unit-head.h
index 5134893..ea09153 100644
--- a/gdb/dwarf2/comp-unit-head.h
+++ b/gdb/dwarf2/comp-unit-head.h
@@ -129,11 +129,8 @@ extern const gdb_byte *read_comp_unit_head
The contents of the header are stored in HEADER.
The result is a pointer to the start of the first DIE. */
extern const gdb_byte *read_and_check_comp_unit_head
- (dwarf2_per_objfile *per_objfile,
- struct comp_unit_head *header,
- struct dwarf2_section_info *section,
- struct dwarf2_section_info *abbrev_section,
- const gdb_byte *info_ptr,
+ (comp_unit_head *header, dwarf2_section_info *section,
+ dwarf2_section_info *abbrev_section, const gdb_byte *info_ptr,
rcuh_kind section_kind);
#endif /* GDB_DWARF2_COMP_UNIT_HEAD_H */
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 6e96afe..55cf02f 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1039,14 +1039,7 @@ static struct dwo_unit *lookup_dwo_unit_in_dwp
(dwarf2_per_bfd *per_bfd, struct dwp_file *dwp_file,
const char *comp_dir, ULONGEST signature, int is_debug_types);
-static struct dwp_file *get_dwp_file (dwarf2_per_objfile *per_objfile);
-
-static struct dwo_unit *lookup_dwo_comp_unit
- (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
- ULONGEST signature);
-
-static struct dwo_unit *lookup_dwo_type_unit
- (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir);
+static void open_and_init_dwp_file (dwarf2_per_objfile *per_objfile);
static void queue_and_load_all_dwo_tus (dwarf2_cu *cu);
@@ -1295,6 +1288,15 @@ dwarf2_has_info (struct objfile *objfile,
{
warning (_("%s"), err.what ());
}
+
+ try
+ {
+ open_and_init_dwp_file (per_objfile);
+ }
+ catch (const gdb_exception_error &err)
+ {
+ warning (_("%s"), err.what ());
+ }
}
return has_info;
@@ -1632,7 +1634,7 @@ dw2_do_instantiate_symtab (dwarf2_per_cu *per_cu,
&& per_objfile->per_bfd->index_table != NULL
&& !per_objfile->per_bfd->index_table->version_check ()
/* DWP files aren't supported yet. */
- && get_dwp_file (per_objfile) == NULL)
+ && per_objfile->per_bfd->dwp_file == nullptr)
queue_and_load_all_dwo_tus (cu);
}
@@ -2383,16 +2385,16 @@ read_abbrev_offset (dwarf2_per_objfile *per_objfile,
return (sect_offset) read_offset (abfd, info_ptr, offset_size);
}
-/* A helper for create_debug_types_hash_table. Read types from SECTION
+/* A helper for create_dwo_debug_types_hash_table. Read types from SECTION
and fill them into DWO_FILE's type unit hash table. It will process only
type units, therefore DW_UT_type. */
-static void
-create_debug_type_hash_table (dwarf2_per_objfile *per_objfile,
- dwo_file *dwo_file, dwarf2_section_info *section,
- rcuh_kind section_kind)
+void
+cutu_reader::create_dwo_debug_type_hash_table (dwarf2_per_bfd *per_bfd,
+ dwo_file *dwo_file,
+ dwarf2_section_info *section,
+ rcuh_kind section_kind)
{
- struct objfile *objfile = per_objfile->objfile;
struct dwarf2_section_info *abbrev_section;
bfd *abfd;
const gdb_byte *info_ptr, *end_ptr;
@@ -2403,7 +2405,6 @@ create_debug_type_hash_table (dwarf2_per_objfile *per_objfile,
section->get_name (),
abbrev_section->get_file_name ());
- section->read (objfile);
info_ptr = section->buffer;
if (info_ptr == NULL)
@@ -2432,8 +2433,8 @@ create_debug_type_hash_table (dwarf2_per_objfile *per_objfile,
/* We need to read the type's signature in order to build the hash
table, but we don't need anything else just yet. */
- ptr = read_and_check_comp_unit_head (per_objfile, &header, section,
- abbrev_section, ptr, section_kind);
+ ptr = read_and_check_comp_unit_head (&header, section, abbrev_section,
+ ptr, section_kind);
length = header.get_length_with_initial ();
@@ -2447,8 +2448,7 @@ create_debug_type_hash_table (dwarf2_per_objfile *per_objfile,
continue;
}
- dwo_unit *dwo_tu
- = OBSTACK_ZALLOC (&per_objfile->per_bfd->obstack, dwo_unit);
+ dwo_unit *dwo_tu = OBSTACK_ZALLOC (&per_bfd->obstack, dwo_unit);
dwo_tu->dwo_file = dwo_file;
dwo_tu->signature = header.signature;
dwo_tu->type_offset_in_tu = header.type_cu_offset_in_tu;
@@ -2478,14 +2478,14 @@ create_debug_type_hash_table (dwarf2_per_objfile *per_objfile,
Note: This function processes DWO files only, not DWP files. */
-static void
-create_debug_types_hash_table
- (dwarf2_per_objfile *per_objfile, dwo_file *dwo_file,
+void
+cutu_reader::create_dwo_debug_types_hash_table
+ (dwarf2_per_bfd *per_bfd, dwo_file *dwo_file,
gdb::array_view<dwarf2_section_info> type_sections)
{
for (dwarf2_section_info &section : type_sections)
- create_debug_type_hash_table (per_objfile, dwo_file, &section,
- rcuh_kind::TYPE);
+ create_dwo_debug_type_hash_table (per_bfd, dwo_file, &section,
+ rcuh_kind::TYPE);
}
/* Add an entry for signature SIG to per_bfd->signatured_types. */
@@ -2610,7 +2610,7 @@ lookup_dwp_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
- struct dwp_file *dwp_file = get_dwp_file (per_objfile);
+ dwp_file *dwp_file = per_objfile->per_bfd->dwp_file.get ();
gdb_assert (cu->dwo_unit);
gdb_assert (dwp_file != NULL);
@@ -2652,7 +2652,7 @@ lookup_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
{
/* We're in a DWO/DWP file, and we're using .gdb_index.
These cases require special processing. */
- if (get_dwp_file (per_objfile) == NULL)
+ if (per_objfile->per_bfd->dwp_file == nullptr)
return lookup_dwo_signatured_type (cu, sig);
else
return lookup_dwp_signatured_type (cu, sig);
@@ -2712,9 +2712,8 @@ cutu_reader::read_cutu_die_from_dwo (dwarf2_cu *cu, dwo_unit *dwo_unit,
die_info *stub_comp_unit_die,
const char *stub_comp_dir)
{
- dwarf2_per_objfile *per_objfile = cu->per_objfile;
dwarf2_per_cu *per_cu = cu->per_cu;
- struct objfile *objfile = per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
bfd *abfd;
struct dwarf2_section_info *dwo_abbrev_section;
@@ -2790,9 +2789,10 @@ cutu_reader::read_cutu_die_from_dwo (dwarf2_cu *cu, dwo_unit *dwo_unit,
{
signatured_type *sig_type = (struct signatured_type *) per_cu;
- m_info_ptr = read_and_check_comp_unit_head (per_objfile, &cu->header,
- section, dwo_abbrev_section,
+ m_info_ptr = read_and_check_comp_unit_head (&cu->header, section,
+ dwo_abbrev_section,
m_info_ptr, rcuh_kind::TYPE);
+
/* This is not an assert because it can be caused by bad debug info. */
if (sig_type->signature != cu->header.signature)
{
@@ -2818,7 +2818,7 @@ cutu_reader::read_cutu_die_from_dwo (dwarf2_cu *cu, dwo_unit *dwo_unit,
else
{
m_info_ptr
- = read_and_check_comp_unit_head (per_objfile, &cu->header, section,
+ = read_and_check_comp_unit_head (&cu->header, section,
dwo_abbrev_section, m_info_ptr,
rcuh_kind::COMPILE);
gdb_assert (dwo_unit->sect_off == cu->header.sect_off);
@@ -2873,8 +2873,9 @@ lookup_dwo_id (struct dwarf2_cu *cu, struct die_info* comp_unit_die)
Returns nullptr if the specified DWO unit cannot be found. */
-static struct dwo_unit *
-lookup_dwo_unit (dwarf2_cu *cu, die_info *comp_unit_die, const char *dwo_name)
+dwo_unit *
+cutu_reader::lookup_dwo_unit (dwarf2_cu *cu, die_info *comp_unit_die,
+ const char *dwo_name)
{
#if CXX_STD_THREAD
/* We need a lock here to handle the DWO hash table. */
@@ -3047,7 +3048,7 @@ cutu_reader::cutu_reader (dwarf2_per_cu &this_cu,
if (this_cu.is_debug_types)
{
m_info_ptr
- = read_and_check_comp_unit_head (&per_objfile, &cu->header, section,
+ = read_and_check_comp_unit_head (&cu->header, section,
abbrev_section, m_info_ptr,
rcuh_kind::TYPE);
@@ -3070,7 +3071,7 @@ cutu_reader::cutu_reader (dwarf2_per_cu &this_cu,
else
{
m_info_ptr
- = read_and_check_comp_unit_head (&per_objfile, &cu->header, section,
+ = read_and_check_comp_unit_head (&cu->header, section,
abbrev_section, m_info_ptr,
rcuh_kind::COMPILE);
@@ -3204,12 +3205,11 @@ cutu_reader::cutu_reader (dwarf2_per_cu &this_cu,
m_info_ptr = section->buffer + to_underlying (this_cu.sect_off);
const gdb_byte *begin_info_ptr = m_info_ptr;
- m_info_ptr
- = read_and_check_comp_unit_head (&per_objfile, &m_new_cu->header, section,
- abbrev_section, m_info_ptr,
- (this_cu.is_debug_types
- ? rcuh_kind::TYPE
- : rcuh_kind::COMPILE));
+ m_info_ptr = read_and_check_comp_unit_head (&m_new_cu->header, section,
+ abbrev_section, m_info_ptr,
+ (this_cu.is_debug_types
+ ? rcuh_kind::TYPE
+ : rcuh_kind::COMPILE));
m_new_cu->str_offsets_base = parent_cu.str_offsets_base;
m_new_cu->addr_base = parent_cu.addr_base;
@@ -3510,7 +3510,7 @@ process_skeletonless_type_units (dwarf2_per_objfile *per_objfile,
cooked_index_worker_result *storage)
{
/* Skeletonless TUs in DWP files without .gdb_index is not supported yet. */
- if (get_dwp_file (per_objfile) == nullptr)
+ if (per_objfile->per_bfd->dwp_file == nullptr)
for (const dwo_file_up &file : per_objfile->per_bfd->dwo_files)
for (dwo_unit *unit : file->tus)
process_skeletonless_type_unit (unit, per_objfile, storage);
@@ -3692,6 +3692,7 @@ read_comp_units_from_section (dwarf2_per_objfile *per_objfile,
{
const gdb_byte *info_ptr;
struct objfile *objfile = per_objfile->objfile;
+ dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
dwarf_read_debug_printf ("Reading %s for %s",
section->get_name (),
@@ -3708,20 +3709,19 @@ read_comp_units_from_section (dwarf2_per_objfile *per_objfile,
sect_offset sect_off = (sect_offset) (info_ptr - section->buffer);
comp_unit_head cu_header;
- read_and_check_comp_unit_head (per_objfile, &cu_header, section,
- abbrev_section, info_ptr,
- section_kind);
+ read_and_check_comp_unit_head (&cu_header, section, abbrev_section,
+ info_ptr, section_kind);
unsigned int length = cu_header.get_length_with_initial ();
/* Save the compilation unit for later lookup. */
if (cu_header.unit_type != DW_UT_type)
- this_cu
- = per_objfile->per_bfd->allocate_per_cu (section, sect_off, length, is_dwz);
+ this_cu = per_bfd->allocate_per_cu (section, sect_off, length, is_dwz);
else
{
- auto sig_type = per_objfile->per_bfd->allocate_signatured_type
- (section, sect_off, length, is_dwz, cu_header.signature);
+ auto sig_type
+ = per_bfd->allocate_signatured_type (section, sect_off, length,
+ is_dwz, cu_header.signature);
signatured_type *sig_ptr = sig_type.get ();
sig_type->type_offset_in_tu = cu_header.type_cu_offset_in_tu;
this_cu.reset (sig_type.release ());
@@ -3737,7 +3737,7 @@ read_comp_units_from_section (dwarf2_per_objfile *per_objfile,
}
info_ptr = info_ptr + this_cu->length ();
- per_objfile->per_bfd->all_units.push_back (std::move (this_cu));
+ per_bfd->all_units.push_back (std::move (this_cu));
}
}
@@ -6307,16 +6307,14 @@ lookup_dwo_file (dwarf2_per_bfd *per_bfd, const char *dwo_name,
/* Create the dwo_units for the CUs in a DWO_FILE.
Note: This function processes DWO files only, not DWP files. */
-static void
-create_cus_hash_table (dwarf2_cu *cu, dwo_file &dwo_file)
+void
+cutu_reader::create_dwo_cus_hash_table (dwarf2_cu *cu, dwo_file &dwo_file)
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
- struct objfile *objfile = per_objfile->objfile;
dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
const gdb_byte *info_ptr, *end_ptr;
auto &section = dwo_file.sections.info;
- section.read (objfile);
info_ptr = section.buffer;
if (info_ptr == NULL)
@@ -6342,6 +6340,12 @@ create_cus_hash_table (dwarf2_cu *cu, dwo_file &dwo_file)
if (reader.is_dummy())
continue;
+ /* DWARF 5 .debug_info.dwo sections may contain some type units. Skip
+ everything that is not a compile unit. */
+ if (const auto ut = reader.cu ()->header.unit_type;
+ ut != DW_UT_compile && ut != DW_UT_split_compile)
+ continue;
+
std::optional<ULONGEST> signature
= lookup_dwo_id (reader.cu (), reader.top_level_die ());
if (!signature.has_value ())
@@ -6530,27 +6534,18 @@ create_cus_hash_table (dwarf2_cu *cu, dwo_file &dwo_file)
Note: This function processes DWP files only, not DWO files. */
static struct dwp_hash_table *
-create_dwp_hash_table (dwarf2_per_objfile *per_objfile,
- struct dwp_file *dwp_file, int is_debug_types)
+create_dwp_hash_table (dwarf2_per_bfd *per_bfd, struct dwp_file *dwp_file,
+ dwarf2_section_info &index)
{
- struct objfile *objfile = per_objfile->objfile;
bfd *dbfd = dwp_file->dbfd.get ();
- const gdb_byte *index_ptr, *index_end;
- struct dwarf2_section_info *index;
uint32_t version, nr_columns, nr_units, nr_slots;
struct dwp_hash_table *htab;
- if (is_debug_types)
- index = &dwp_file->sections.tu_index;
- else
- index = &dwp_file->sections.cu_index;
-
- if (index->empty ())
+ if (index.empty ())
return NULL;
- index->read (objfile);
- index_ptr = index->buffer;
- index_end = index_ptr + index->size;
+ const gdb_byte *index_ptr = index.buffer;
+ const gdb_byte *index_end = index_ptr + index.size;
/* For Version 5, the version is really 2 bytes of data & 2 bytes of padding.
For now it's safe to just read 4 bytes (particularly as it's difficult to
@@ -6581,7 +6576,7 @@ create_dwp_hash_table (dwarf2_per_objfile *per_objfile,
pulongest (nr_slots), dwp_file->name);
}
- htab = OBSTACK_ZALLOC (&per_objfile->per_bfd->obstack, struct dwp_hash_table);
+ htab = OBSTACK_ZALLOC (&per_bfd->obstack, struct dwp_hash_table);
htab->version = version;
htab->nr_columns = nr_columns;
htab->nr_units = nr_units;
@@ -7520,9 +7515,9 @@ try_open_dwop_file (dwarf2_per_bfd *per_bfd, const char *file_name, int is_dwp,
Upon success, the canonicalized path of the file is stored in the bfd,
same as symfile_bfd_open. */
-static gdb_bfd_ref_ptr
-open_dwo_file (dwarf2_per_bfd *per_bfd, const char *file_name,
- const char *comp_dir)
+gdb_bfd_ref_ptr
+cutu_reader::open_dwo_file (dwarf2_per_bfd *per_bfd, const char *file_name,
+ const char *comp_dir)
{
if (IS_ABSOLUTE_PATH (file_name))
return try_open_dwop_file (per_bfd, file_name,
@@ -7557,9 +7552,9 @@ open_dwo_file (dwarf2_per_bfd *per_bfd, const char *file_name,
/* This function is mapped across the sections and remembers the offset and
size of each of the DWO debugging sections we are interested in. */
-static void
-dwarf2_locate_dwo_sections (struct objfile *objfile, bfd *abfd,
- asection *sectp, dwo_sections *dwo_sections)
+void
+cutu_reader::locate_dwo_sections (struct objfile *objfile, bfd *abfd,
+ asection *sectp, dwo_sections *dwo_sections)
{
const struct dwop_section_names *names = &dwop_section_names;
@@ -7606,11 +7601,12 @@ dwarf2_locate_dwo_sections (struct objfile *objfile, bfd *abfd,
by PER_CU. This is for the non-DWP case.
The result is NULL if DWO_NAME can't be found. */
-static dwo_file_up
-open_and_init_dwo_file (dwarf2_cu *cu, const char *dwo_name,
- const char *comp_dir)
+dwo_file_up
+cutu_reader::open_and_init_dwo_file (dwarf2_cu *cu, const char *dwo_name,
+ const char *comp_dir)
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
+ dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
gdb_bfd_ref_ptr dbfd
= open_dwo_file (per_objfile->per_bfd, dwo_name, comp_dir);
@@ -7627,17 +7623,18 @@ open_and_init_dwo_file (dwarf2_cu *cu, const char *dwo_name,
dwo_file->dbfd = std::move (dbfd);
for (asection *sec : gdb_bfd_sections (dwo_file->dbfd))
- dwarf2_locate_dwo_sections (per_objfile->objfile, dwo_file->dbfd.get (),
- sec, &dwo_file->sections);
+ this->locate_dwo_sections (per_objfile->objfile, dwo_file->dbfd.get (), sec,
+ &dwo_file->sections);
- create_cus_hash_table (cu, *dwo_file);
+ create_dwo_cus_hash_table (cu, *dwo_file);
if (cu->header.version < 5)
- create_debug_types_hash_table (per_objfile, dwo_file.get (),
- dwo_file->sections.types);
+ create_dwo_debug_types_hash_table (per_bfd, dwo_file.get (),
+ dwo_file->sections.types);
else
- create_debug_type_hash_table (per_objfile, dwo_file.get (),
- &dwo_file->sections.info, rcuh_kind::COMPILE);
+ create_dwo_debug_type_hash_table (per_bfd, dwo_file.get (),
+ &dwo_file->sections.info,
+ rcuh_kind::COMPILE);
dwarf_read_debug_printf ("DWO file found: %s", dwo_name);
@@ -7803,10 +7800,9 @@ open_dwp_file (dwarf2_per_bfd *per_bfd, const char *file_name)
}
/* Initialize the use of the DWP file for the current objfile.
- By convention the name of the DWP file is ${objfile}.dwp.
- The result is NULL if it can't be found. */
+ By convention the name of the DWP file is ${objfile}.dwp. */
-static dwp_file_up
+static void
open_and_init_dwp_file (dwarf2_per_objfile *per_objfile)
{
struct objfile *objfile = per_objfile->objfile;
@@ -7844,7 +7840,7 @@ open_and_init_dwp_file (dwarf2_per_objfile *per_objfile)
{
dwarf_read_debug_printf ("DWP file not found: %s", dwp_name.c_str ());
- return dwp_file_up ();
+ return;
}
const char *name = bfd_get_filename (dbfd.get ());
@@ -7858,9 +7854,10 @@ open_and_init_dwp_file (dwarf2_per_objfile *per_objfile)
dwarf2_locate_common_dwp_sections (objfile, dwp_file->dbfd.get (), sec,
dwp_file.get ());
- dwp_file->cus = create_dwp_hash_table (per_objfile, dwp_file.get (), 0);
-
- dwp_file->tus = create_dwp_hash_table (per_objfile, dwp_file.get (), 1);
+ dwp_file->cus = create_dwp_hash_table (per_bfd, dwp_file.get (),
+ dwp_file->sections.cu_index);
+ dwp_file->tus = create_dwp_hash_table (per_bfd, dwp_file.get (),
+ dwp_file->sections.tu_index);
/* The DWP file version is stored in the hash table. Oh well. */
if (dwp_file->cus && dwp_file->tus
@@ -7900,20 +7897,8 @@ open_and_init_dwp_file (dwarf2_per_objfile *per_objfile)
bfd_cache_close (dwp_file->dbfd.get ());
- return dwp_file;
-}
-
-/* Wrapper around open_and_init_dwp_file, only open it once. */
-
-static struct dwp_file *
-get_dwp_file (dwarf2_per_objfile *per_objfile)
-{
- if (!per_objfile->per_bfd->dwp_checked)
- {
- per_objfile->per_bfd->dwp_file = open_and_init_dwp_file (per_objfile);
- per_objfile->per_bfd->dwp_checked = 1;
- }
- return per_objfile->per_bfd->dwp_file.get ();
+ /* Everything worked, install this dwp_file in the per_bfd. */
+ per_objfile->per_bfd->dwp_file = std::move (dwp_file);
}
/* Subroutine of lookup_dwo_comp_unit, lookup_dwo_type_unit.
@@ -7932,22 +7917,23 @@ get_dwp_file (dwarf2_per_objfile *per_objfile)
The result is a pointer to the dwo_unit object or NULL if we didn't find it
(dwo_id mismatch or couldn't find the DWO/DWP file). */
-static struct dwo_unit *
-lookup_dwo_cutu (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
- ULONGEST signature, int is_debug_types)
+dwo_unit *
+cutu_reader::lookup_dwo_cutu (dwarf2_cu *cu, const char *dwo_name,
+ const char *comp_dir, ULONGEST signature,
+ int is_debug_types)
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
struct objfile *objfile = per_objfile->objfile;
const char *kind = is_debug_types ? "TU" : "CU";
- struct dwp_file *dwp_file;
/* First see if there's a DWP file.
If we have a DWP file but didn't find the DWO inside it, don't
look for the original DWO file. It makes gdb behave differently
depending on whether one is debugging in the build tree. */
- dwp_file = get_dwp_file (per_objfile);
+ dwp_file *dwp_file = per_objfile->per_bfd->dwp_file.get ();
+
if (dwp_file != NULL)
{
const struct dwp_hash_table *dwp_htab =
@@ -8048,9 +8034,9 @@ lookup_dwo_cutu (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
/* Lookup the DWO CU DWO_NAME/SIGNATURE referenced from THIS_CU.
See lookup_dwo_cutu_unit for details. */
-static struct dwo_unit *
-lookup_dwo_comp_unit (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
- ULONGEST signature)
+dwo_unit *
+cutu_reader::lookup_dwo_comp_unit (dwarf2_cu *cu, const char *dwo_name,
+ const char *comp_dir, ULONGEST signature)
{
gdb_assert (!cu->per_cu->is_debug_types);
@@ -8060,8 +8046,9 @@ lookup_dwo_comp_unit (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
/* Lookup the DWO TU DWO_NAME/SIGNATURE referenced from THIS_TU.
See lookup_dwo_cutu_unit for details. */
-static struct dwo_unit *
-lookup_dwo_type_unit (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir)
+dwo_unit *
+cutu_reader::lookup_dwo_type_unit (dwarf2_cu *cu, const char *dwo_name,
+ const char *comp_dir)
{
gdb_assert (cu->per_cu->is_debug_types);
@@ -8104,7 +8091,7 @@ queue_and_load_all_dwo_tus (dwarf2_cu *cu)
gdb_assert (cu != nullptr);
gdb_assert (!cu->per_cu->is_debug_types);
- gdb_assert (get_dwp_file (cu->per_objfile) == nullptr);
+ gdb_assert (cu->per_objfile->per_bfd->dwp_file == nullptr);
dwo_unit = cu->dwo_unit;
gdb_assert (dwo_unit != NULL);
@@ -19182,7 +19169,7 @@ dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym,
/* .debug_loc{,.dwo} may not exist at all, or the offset may be outside
the section. If so, fall through to the complaint in the
other branch. */
- && attr->as_unsigned () < section->get_size (objfile))
+ && attr->as_unsigned () < section->size)
{
struct dwarf2_loclist_baton *baton;
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index 3177b19..a9a2aa4 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -634,9 +634,6 @@ public:
/* Set of dwo_file objects. */
dwo_file_up_set dwo_files;
- /* True if we've checked for whether there is a DWP file. */
- bool dwp_checked = false;
-
/* The DWP file if there is one, or NULL. */
dwp_file_up dwp_file;
@@ -1028,6 +1025,39 @@ private:
const char *read_dwo_str_index (ULONGEST str_index);
+ gdb_bfd_ref_ptr open_dwo_file (dwarf2_per_bfd *per_bfd, const char *file_name,
+ const char *comp_dir);
+
+ dwo_file_up open_and_init_dwo_file (dwarf2_cu *cu, const char *dwo_name,
+ const char *comp_dir);
+
+ void locate_dwo_sections (struct objfile *objfile, bfd *abfd, asection *sectp,
+ struct dwo_sections *dwo_sections);
+
+ void create_dwo_cus_hash_table (dwarf2_cu *cu, dwo_file &dwo_file);
+
+ void create_dwo_debug_types_hash_table
+ (dwarf2_per_bfd *per_bfd, dwo_file *dwo_file,
+ gdb::array_view<dwarf2_section_info> type_sections);
+
+ void create_dwo_debug_type_hash_table (dwarf2_per_bfd *per_bfd,
+ dwo_file *dwo_file,
+ dwarf2_section_info *section,
+ rcuh_kind section_kind);
+
+ dwo_unit *lookup_dwo_cutu (dwarf2_cu *cu, const char *dwo_name,
+ const char *comp_dir, ULONGEST signature,
+ int is_debug_types);
+
+ dwo_unit *lookup_dwo_comp_unit (dwarf2_cu *cu, const char *dwo_name,
+ const char *comp_dir, ULONGEST signature);
+
+ dwo_unit *lookup_dwo_type_unit (dwarf2_cu *cu, const char *dwo_name,
+ const char *comp_dir);
+
+ dwo_unit *lookup_dwo_unit (dwarf2_cu *cu, die_info *comp_unit_die,
+ const char *dwo_name);
+
/* The bfd of die_section. */
bfd *m_abfd;
diff --git a/gdb/dwarf2/section.h b/gdb/dwarf2/section.h
index 85da485..b9d3c31 100644
--- a/gdb/dwarf2/section.h
+++ b/gdb/dwarf2/section.h
@@ -81,19 +81,6 @@ struct dwarf2_section_info
If the section is compressed, uncompress it before returning. */
void read (struct objfile *objfile);
- /* A helper function that returns the size of a section in a safe way.
- If you are positive that the section has been read before using the
- size, then it is safe to refer to the dwarf2_section_info object's
- "size" field directly. In other cases, you must call this
- function, because for compressed sections the size field is not set
- correctly until the section has been read. */
- bfd_size_type get_size (struct objfile *objfile)
- {
- if (!readin)
- read (objfile);
- return size;
- }
-
/* Issue a complaint that something was outside the bounds of this
buffer. */
void overflow_complaint () const;
diff --git a/gdb/maint.h b/gdb/maint.h
index 434d2a9..0ddc62b 100644
--- a/gdb/maint.h
+++ b/gdb/maint.h
@@ -22,6 +22,9 @@
#include "gdbsupport/run-time-clock.h"
#include <chrono>
+struct obj_section;
+struct objfile;
+
extern void set_per_command_time (int);
extern void set_per_command_space (int);
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 3855bde..8a2e263 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -1096,8 +1096,7 @@ valpy_getitem (PyObject *self, PyObject *key)
res_val = value_struct_elt (&tmp, {}, field.get (), NULL,
"struct/class/union");
else if (bitpos >= 0)
- res_val = value_struct_elt_bitpos (&tmp, bitpos, field_type,
- "struct/class/union");
+ res_val = value_struct_elt_bitpos (tmp, bitpos, field_type);
else if (base_class_type != NULL)
{
struct type *val_type;
diff --git a/gdb/testsuite/gdb.ada/scalar_storage.exp b/gdb/testsuite/gdb.ada/scalar_storage.exp
index 6b29226..52a85cd 100644
--- a/gdb/testsuite/gdb.ada/scalar_storage.exp
+++ b/gdb/testsuite/gdb.ada/scalar_storage.exp
@@ -45,10 +45,30 @@ if {![runto "storage.adb:$bp_location"]} {
return
}
-gdb_test "print V_LE" "= \\(value => 126, another_value => 12, color => green\\)"
+set re "value => 126, another_value => 12, color => green"
# This requires a compiler fix that is in GCC 14.
-if { ![gnat_version_compare >= 14] } {
- setup_kfail "DW_AT_endianity on enum types" *-*-*
+set have_xfail [expr ![gnat_version_compare >= 14]]
+set re_color "(red|green|blue|$decimal)"
+set re_xfail \
+ "value => $decimal, another_value => $decimal, color => $re_color"
+
+set re_pre [string_to_regexp " = ("]
+set re_post [string_to_regexp ")"]
+set re $re_pre$re$re_post
+set re_xfail $re_pre$re_xfail$re_post
+
+foreach var { V_LE V_BE } {
+ gdb_test_multiple "print $var" "" {
+ -re -wrap $re {
+ pass $gdb_test_name
+ }
+ -re -wrap $re_xfail {
+ if { $have_xfail } {
+ xfail $gdb_test_name
+ } else {
+ fail $gdb_test_name
+ }
+ }
+ }
}
-gdb_test "print V_BE" "= \\(value => 126, another_value => 12, color => green\\)"
diff --git a/gdb/testsuite/gdb.arch/aarch64-sve-sigunwind.c b/gdb/testsuite/gdb.arch/aarch64-sve-sigunwind.c
new file mode 100644
index 0000000..c86beaf
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/aarch64-sve-sigunwind.c
@@ -0,0 +1,205 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2025 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Exercise unwinding AArch64's SVE registers from a signal frame. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/prctl.h>
+#include <unistd.h>
+
+static int second_vl = 0;
+
+static void
+initialize_sve_state_main ()
+{
+ __asm __volatile ("dup z0.b, -1");
+ __asm __volatile ("dup z1.b, -1");
+ __asm __volatile ("dup z2.b, -1");
+ __asm __volatile ("dup z3.b, -1");
+ __asm __volatile ("dup z4.b, -1");
+ __asm __volatile ("dup z5.b, -1");
+ __asm __volatile ("dup z6.b, -1");
+ __asm __volatile ("dup z7.b, -1");
+ __asm __volatile ("dup z8.b, -1");
+ __asm __volatile ("dup z9.b, -1");
+ __asm __volatile ("dup z10.b, -1");
+ __asm __volatile ("dup z11.b, -1");
+ __asm __volatile ("dup z12.b, -1");
+ __asm __volatile ("dup z13.b, -1");
+ __asm __volatile ("dup z14.b, -1");
+ __asm __volatile ("dup z15.b, -1");
+ __asm __volatile ("dup z16.b, -1");
+ __asm __volatile ("dup z17.b, -1");
+ __asm __volatile ("dup z18.b, -1");
+ __asm __volatile ("dup z19.b, -1");
+ __asm __volatile ("dup z20.b, -1");
+ __asm __volatile ("dup z21.b, -1");
+ __asm __volatile ("dup z22.b, -1");
+ __asm __volatile ("dup z23.b, -1");
+ __asm __volatile ("dup z24.b, -1");
+ __asm __volatile ("dup z25.b, -1");
+ __asm __volatile ("dup z26.b, -1");
+ __asm __volatile ("dup z27.b, -1");
+ __asm __volatile ("dup z28.b, -1");
+ __asm __volatile ("dup z29.b, -1");
+ __asm __volatile ("dup z30.b, -1");
+ __asm __volatile ("dup z31.b, -1");
+ __asm __volatile ("ptrue p0.d");
+ __asm __volatile ("ptrue p1.d");
+ __asm __volatile ("ptrue p2.d");
+ __asm __volatile ("ptrue p3.d");
+ __asm __volatile ("ptrue p4.d");
+ __asm __volatile ("ptrue p5.d");
+ __asm __volatile ("ptrue p6.d");
+ __asm __volatile ("ptrue p7.d");
+ __asm __volatile ("ptrue p8.d");
+ __asm __volatile ("ptrue p9.d");
+ __asm __volatile ("ptrue p10.d");
+ __asm __volatile ("ptrue p11.d");
+ __asm __volatile ("ptrue p12.d");
+ __asm __volatile ("ptrue p13.d");
+ __asm __volatile ("ptrue p14.d");
+ __asm __volatile ("ptrue p15.d");
+ __asm __volatile ("setffr");
+}
+
+static void
+initialize_sve_state_sighandler ()
+{
+ __asm __volatile ("dup z0.b, -2");
+ __asm __volatile ("dup z1.b, -2");
+ __asm __volatile ("dup z2.b, -2");
+ __asm __volatile ("dup z3.b, -2");
+ __asm __volatile ("dup z4.b, -2");
+ __asm __volatile ("dup z5.b, -2");
+ __asm __volatile ("dup z6.b, -2");
+ __asm __volatile ("dup z7.b, -2");
+ __asm __volatile ("dup z8.b, -2");
+ __asm __volatile ("dup z9.b, -2");
+ __asm __volatile ("dup z10.b, -2");
+ __asm __volatile ("dup z11.b, -2");
+ __asm __volatile ("dup z12.b, -2");
+ __asm __volatile ("dup z13.b, -2");
+ __asm __volatile ("dup z14.b, -2");
+ __asm __volatile ("dup z15.b, -2");
+ __asm __volatile ("dup z16.b, -2");
+ __asm __volatile ("dup z17.b, -2");
+ __asm __volatile ("dup z18.b, -2");
+ __asm __volatile ("dup z19.b, -2");
+ __asm __volatile ("dup z20.b, -2");
+ __asm __volatile ("dup z21.b, -2");
+ __asm __volatile ("dup z22.b, -2");
+ __asm __volatile ("dup z23.b, -2");
+ __asm __volatile ("dup z24.b, -2");
+ __asm __volatile ("dup z25.b, -2");
+ __asm __volatile ("dup z26.b, -2");
+ __asm __volatile ("dup z27.b, -2");
+ __asm __volatile ("dup z28.b, -2");
+ __asm __volatile ("dup z29.b, -2");
+ __asm __volatile ("dup z30.b, -2");
+ __asm __volatile ("dup z31.b, -2");
+ __asm __volatile ("pfalse p0.b");
+ __asm __volatile ("pfalse p1.b");
+ __asm __volatile ("pfalse p2.b");
+ __asm __volatile ("pfalse p3.b");
+ __asm __volatile ("pfalse p4.b");
+ __asm __volatile ("pfalse p5.b");
+ __asm __volatile ("pfalse p6.b");
+ __asm __volatile ("pfalse p7.b");
+ __asm __volatile ("pfalse p8.b");
+ __asm __volatile ("pfalse p9.b");
+ __asm __volatile ("pfalse p10.b");
+ __asm __volatile ("pfalse p11.b");
+ __asm __volatile ("pfalse p12.b");
+ __asm __volatile ("pfalse p13.b");
+ __asm __volatile ("pfalse p14.b");
+ __asm __volatile ("pfalse p15.b");
+ __asm __volatile ("setffr");
+}
+
+/* Set new value for the SVE vector length.
+ Return the value that was set. */
+
+static int
+set_vl (int vl)
+{
+ int rc;
+
+ rc = prctl (PR_SVE_SET_VL, vl, 0, 0, 0);
+ if (rc < 0)
+ {
+ perror ("FAILED to PR_SVE_SET_VL");
+ exit (EXIT_FAILURE);
+ }
+
+ return rc & PR_SVE_VL_LEN_MASK;
+}
+
+static void
+sighandler (int sig, siginfo_t *info, void *ucontext)
+{
+ /* Set vector length to the second value. */
+ second_vl = set_vl (second_vl);
+ initialize_sve_state_sighandler ();
+ printf ("sighandler: second_vl = %d\n", second_vl); /* Break here. */
+}
+
+int
+main (int argc, char *argv[])
+{
+ if (argc != 3)
+ {
+ fprintf (stderr, "Usage: %s <first vl> <second vl>\n", argv[0]);
+ return 1;
+ }
+
+ int first_vl = atoi (argv[1]);
+ second_vl = atoi (argv[2]);
+
+ if (first_vl == 0 || second_vl == 0)
+ {
+ fprintf (stderr, "Invalid vector length.\n");
+ return 1;
+ }
+
+ /* Set vector length to the first value. */
+ first_vl = set_vl (first_vl);
+
+ printf ("main: first_vl = %d\n", first_vl);
+
+ unsigned char buf[256];
+
+ /* Use an SVE register to make the kernel start saving the SVE bank. */
+ asm volatile ("mov z0.b, #255\n\t"
+ "str z0, %0"
+ :
+ : "m" (buf)
+ : "z0", "memory");
+
+ initialize_sve_state_main ();
+
+ struct sigaction sigact;
+ sigact.sa_sigaction = sighandler;
+ sigact.sa_flags = SA_SIGINFO;
+ sigaction (SIGUSR1, &sigact, NULL);
+
+ kill (getpid (), SIGUSR1);
+
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.arch/aarch64-sve-sigunwind.exp b/gdb/testsuite/gdb.arch/aarch64-sve-sigunwind.exp
new file mode 100644
index 0000000..32340bb
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/aarch64-sve-sigunwind.exp
@@ -0,0 +1,106 @@
+# Copyright 2025 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Exercise unwinding AArch64's SVE registers from a signal frame.
+
+require allow_aarch64_sve_tests
+# Remote targets can't communicate vector length changes to GDB via the RSP.
+require !gdb_protocol_is_remote
+
+set first_vl 0
+set second_vl 0
+
+# Find two valid VL values to use in the test.
+# The minimum supported VL is 16 bytes, maximum is 256 bytes, and VL can change
+# in increments of at least 16 bytes.
+for {set i 16} {$i <= 256} {incr i 16} {
+ if {![aarch64_supports_sve_vl $i]} {
+ continue
+ }
+
+ if {$first_vl == 0} {
+ set first_vl $i
+ } elseif {$second_vl == 0} {
+ set second_vl $i
+ break
+ }
+}
+
+if {$first_vl == 0 || $second_vl == 0} {
+ untested "test needs to support at least two vector lengths"
+ return
+}
+
+standard_testfile
+if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \
+ [list debug additional_flags=-march=armv9-a]] } {
+ return
+}
+
+# We want SIGUSR1 to be delivered normally.
+gdb_test "handle SIGUSR1 nostop" \
+ [multi_line {Signal Stop Print Pass to program Description} \
+ {SIGUSR1 No Yes Yes User defined signal 1}] \
+ "don't stop for SIGUSR1"
+
+set linespec ${srcfile}:[gdb_get_line_number "Break here."]
+gdb_test_no_output "set args $first_vl $second_vl"
+
+if ![runto ${linespec}] {
+ return
+}
+
+set first_vg [expr $first_vl/8]
+set second_vg [expr $second_vl/8]
+
+gdb_test "print \$vg" ". = $second_vg" "vg was changed"
+
+for {set row 0} {$row < 32} {incr row} {
+ set register_name "\$z${row}\.b\.u"
+ gdb_test "print sizeof $register_name" " = $second_vl" \
+ "size of $register_name in the signal handler"
+ gdb_test "print $register_name" ". = \\{254 <repeats $second_vl times>\\}" \
+ "$register_name contents in signal handler"
+}
+
+for {set row 0} {$row < 16} {incr row} {
+ set register_name "\$p${row}"
+ gdb_test "print $register_name" ". = \\{(0, ){[expr $second_vl/8 - 1]}0\\}" \
+ "$register_name contents in signal handler"
+}
+gdb_test "print \$ffr" ". = \\{(255, ){[expr $second_vl/8 - 1]}255\\}" \
+ "ffr contents in signal handler"
+
+gdb_test "frame function main" \
+ [multi_line "#$decimal $hex in main \[^\r\n\]+" \
+ "$decimal\[ \t\]+kill \\(getpid \\(\\), SIGUSR1\\);"]
+
+gdb_test "print \$vg" ". = $first_vg" "vg was correctly unwound"
+
+for {set row 0} {$row < 32} {incr row} {
+ set register_name "\$z${row}\.b\.u"
+ gdb_test "print sizeof $register_name" " = $first_vl" \
+ "size of $register_name was correctly unwound"
+ gdb_test "print $register_name" ". = \\{255 <repeats $first_vl times>\\}" \
+ "$register_name contents were correctly unwound"
+}
+
+for {set row 0} {$row < 16} {incr row} {
+ set register_name "\$p${row}"
+ gdb_test "print $register_name" ". = \\{(1, ){[expr $first_vl/8 - 1]}1\\}" \
+ "$register_name contents were correctly unwound"
+}
+gdb_test "print \$ffr" ". = \\{(255, ){[expr $first_vl/8 - 1]}255\\}" \
+ "ffr contents were correctly unwound"
diff --git a/gdb/testsuite/gdb.base/bg-execution-repeat.c b/gdb/testsuite/gdb.base/bg-execution-repeat.c
index 8e9bae4..3c0cc76 100644
--- a/gdb/testsuite/gdb.base/bg-execution-repeat.c
+++ b/gdb/testsuite/gdb.base/bg-execution-repeat.c
@@ -37,9 +37,9 @@ main (void)
{
alarm (60);
+ do_wait = 1;
foo ();
- do_wait = 1;
wait ();
/* do_wait set to 0 externally. */
diff --git a/gdb/testsuite/gdb.base/corefile3.c b/gdb/testsuite/gdb.base/corefile3.c
new file mode 100644
index 0000000..16030dd
--- /dev/null
+++ b/gdb/testsuite/gdb.base/corefile3.c
@@ -0,0 +1,118 @@
+/* Copyright 1992-2025 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* This file is based on coremaker.c. */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#define MAPSIZE (8 * 1024)
+
+/* Global pointers so it's easier to access them from GDB. */
+
+char *rw_mapping = NULL;
+char *malloc_buffer = NULL;
+char *anon_mapping = NULL;
+char *shm_mapping = NULL;
+
+/* Create mappings within this process. */
+
+void
+mmapdata ()
+{
+ /* Allocate and initialize a buffer that will be used to write the file
+ that is later mapped in. */
+
+ malloc_buffer = (char *) malloc (MAPSIZE);
+ for (int j = 0; j < MAPSIZE; ++j)
+ malloc_buffer[j] = j;
+
+ /* Write the file to map in. */
+
+ int fd = open ("coremmap.data", O_CREAT | O_RDWR, 0666);
+ assert (fd != -1);
+ write (fd, malloc_buffer, MAPSIZE);
+
+ /* Now map the file into our address space as RW_MAPPING. */
+
+ rw_mapping
+ = (char *) mmap (0, MAPSIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+ assert (rw_mapping != (char *) MAP_FAILED);
+
+ /* Verify that the original data and the mapped data are identical. If
+ not, we'd rather fail now than when trying to access the mapped data
+ from the core file. */
+
+ for (int j = 0; j < MAPSIZE; ++j)
+ assert (malloc_buffer[j] == rw_mapping[j]);
+
+ /* Touch RW_MAPPING so the kernel writes it out into 'core'. */
+ rw_mapping[0] = malloc_buffer[0];
+
+ /* Create yet another region which is allocated, but not written to. */
+ anon_mapping = mmap (NULL, MAPSIZE, PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ assert (anon_mapping != MAP_FAILED);
+
+ /* Create a shared memory mapping. */
+ int sid = shmget (IPC_PRIVATE, MAPSIZE, IPC_CREAT | IPC_EXCL | 0777);
+ assert (sid != -1);
+ shm_mapping = (char *) shmat (sid, NULL, 0);
+ int res = shmctl (sid, IPC_RMID, NULL);
+ assert (res == 0);
+ assert (shm_mapping != MAP_FAILED);
+}
+
+void
+func2 ()
+{
+#ifdef SA_FULLDUMP
+ /* Force a corefile that includes the data section for AIX. */
+ {
+ struct sigaction sa;
+
+ sigaction (SIGABRT, (struct sigaction *)0, &sa);
+ sa.sa_flags |= SA_FULLDUMP;
+ sigaction (SIGABRT, &sa, (struct sigaction *)0);
+ }
+#endif
+
+ abort ();
+}
+
+void
+func1 ()
+{
+ func2 ();
+}
+
+int
+main (void)
+{
+ mmapdata ();
+ func1 ();
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.base/corefile3.exp b/gdb/testsuite/gdb.base/corefile3.exp
new file mode 100644
index 0000000..57b2300
--- /dev/null
+++ b/gdb/testsuite/gdb.base/corefile3.exp
@@ -0,0 +1,71 @@
+# Copyright 2025 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Create a core file with some mapped file regions, but ensure that
+# the the kernel should write the regions into the core file (e.g. r/w
+# file backed mapping).
+#
+# We then delete the file that backed the mapping and load the core
+# file into GDB.
+#
+# GDB shouldn't warn about the file being missing. It doesn't matter;
+# the file contents can all be found in the core file itself.
+
+require isnative
+require {!is_remote host}
+
+standard_testfile
+
+if {[build_executable $testfile.exp $testfile $srcfile] == -1} {
+ return
+}
+
+set corefile [core_find $binfile {}]
+if {$corefile == ""} {
+ return
+}
+
+# Move the coremap.data file out of the way, so it cannot be found
+# when we later load the core file into GDB. This file was generated
+# by the inferior as it was running.
+set data_filename \
+ [standard_output_file coredir.[getpid]/coremmap.data]
+set backup_filename \
+ [standard_output_file coredir.[getpid]/coremmap.data.backup]
+remote_exec host "mv ${data_filename} ${backup_filename}"
+
+clean_restart $binfile
+
+# Load the core file. The 'coremap.data' file cannot be found by GDB,
+# but all the mappings for that file are r/w and should be present in
+# the core file, so we shouldn't get any warnings from GDB about it.
+set warnings_seen 0
+gdb_test_multiple "core-file $corefile" "core-file command" {
+ -re "^warning: Can't open file \[^\r\n\]+ during file-backed mapping note processing\r\n" {
+ incr warnings_seen
+ exp_continue
+ }
+ -re "^$gdb_prompt $" {
+ gdb_assert { $warnings_seen == 0 } $gdb_test_name
+ }
+ -re "^\[^\r\n\]*\r\n" {
+ exp_continue
+ }
+}
+
+# Check the mappings are all readable.
+foreach label { rw_mapping malloc_buffer anon_mapping shm_mapping } {
+ gdb_test "x/1wd $label" "^$hex:\\s+$decimal"
+}
diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
index 03b7a52..3ddc07e 100644
--- a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
+++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
@@ -24,7 +24,8 @@ require allow_dlmopen_tests
standard_testfile -main.c -lib.c
set srcfile_lib $srcfile2
-set binfile_lib [standard_output_file dlmopen-lib.so]
+set so_name dlmopen-lib.so
+set binfile_lib [standard_output_file $so_name]
if { [build_executable "build shlib" $binfile_lib $srcfile_lib \
[list debug shlib]] == -1 } {
@@ -41,18 +42,19 @@ if { [build_executable "failed to build" $testfile $srcfile \
# for the so
proc get_first_so_ns {} {
set ns -1
- gdb_test_multiple "info sharedlibrary" "get SO namespace" -lbl {
- -re "From\\s+To\\s+\(NS\\s+\)?Syms\\s+Read\\s+Shared Object Library\r\n" {
+ set lib_regexp [string_to_regexp ${::binfile_lib}]
+ gdb_test_multiple "info sharedlibrary $::so_name" "get SO namespace" -lbl {
+ -re "\r\nFrom\\s+To\\s+\(NS\\s+\)?Syms\\s+Read\\s+Shared Object Library(?=\r\n)" {
exp_continue
}
- -re "^$::hex\\s+$::hex\\s+\\\[\\\[($::decimal)\\\]\\\]\\s+\[^\r\n]+$::binfile_lib.*" {
- set ns $expect_out(1,string)
- }
- -re "^$::gdb_prompt $" {
- }
- -re "^\[^\r\n\]+\r\n" {
+ -re "\r\n$::hex\\s+$::hex\\s+\\\[\\\[($::decimal)\\\]\\\]\\s+\[^\r\n]+${lib_regexp}(?=\r\n)" {
+ if {$ns == -1} {
+ set ns $expect_out(1,string)
+ }
exp_continue
}
+ -re -wrap "" {
+ }
}
return $ns
}
diff --git a/gdb/testsuite/gdb.base/printcmds.exp b/gdb/testsuite/gdb.base/printcmds.exp
index e1c996e..8634668 100644
--- a/gdb/testsuite/gdb.base/printcmds.exp
+++ b/gdb/testsuite/gdb.base/printcmds.exp
@@ -744,6 +744,12 @@ proc test_print_char_arrays {} {
gdb_test_no_output "set print address off" "address off char arrays"
}
+proc test_print_arrays_negative {} {
+ # Check whether correct error messages are printed
+ gdb_test "p 1 == { }" "size of the array element must not be zero"
+ gdb_test "p 1 == { 1, 'a' }" "array elements must all be the same size"
+}
+
proc test_print_nibbles {} {
gdb_test_no_output "set print nibbles on"
foreach lang_line {
@@ -1235,6 +1241,7 @@ test_print_int_arrays
test_print_typedef_arrays
test_artificial_arrays
test_print_char_arrays
+test_print_arrays_negative
test_print_nibbles
# We used to do the runto main here.
test_print_string_constants
diff --git a/gdb/testsuite/gdb.cp/cplusfuncs.exp b/gdb/testsuite/gdb.cp/cplusfuncs.exp
index 94d9df3..e785909 100644
--- a/gdb/testsuite/gdb.cp/cplusfuncs.exp
+++ b/gdb/testsuite/gdb.cp/cplusfuncs.exp
@@ -579,7 +579,8 @@ proc do_tests {} {
gdb_test_no_output "set width 0"
- runto_main
+ # Don't run to main, to avoid loading and expanding debug info for
+ # libstdc++.
gdb_test_no_output "set language c++"
probe_demangler
diff --git a/gdb/testsuite/gdb.dwarf2/fission-with-type-unit.exp b/gdb/testsuite/gdb.dwarf2/fission-with-type-unit.exp
index a1b3bb7..0a02f7c 100644
--- a/gdb/testsuite/gdb.dwarf2/fission-with-type-unit.exp
+++ b/gdb/testsuite/gdb.dwarf2/fission-with-type-unit.exp
@@ -91,6 +91,10 @@ if { [gdb_compile_shlib $dwo_asm_file $dwo_file nodebug] != "" } {
return
}
+if { [is_remote host] } {
+ gdb_remote_download host $dwo_file
+}
+
clean_restart ${testfile}
# This would cause an internal error.
diff --git a/gdb/testsuite/gdb.threads/clone-attach-detach.exp b/gdb/testsuite/gdb.threads/clone-attach-detach.exp
index 0ae4281..3da2c3e 100644
--- a/gdb/testsuite/gdb.threads/clone-attach-detach.exp
+++ b/gdb/testsuite/gdb.threads/clone-attach-detach.exp
@@ -74,7 +74,7 @@ set attempts 3
for {set attempt 1} {$attempt <= $attempts} {incr attempt} {
with_test_prefix "bg attach $attempt" {
- gdb_test "attach $testpid &" \
+ gdb_test -no-prompt-anchor "attach $testpid &" \
"Attaching to program.*process $testpid.*" \
"attach"
diff --git a/gdb/unittests/rsp-low-selftests.c b/gdb/unittests/rsp-low-selftests.c
index df849c9..7a1b2de 100644
--- a/gdb/unittests/rsp-low-selftests.c
+++ b/gdb/unittests/rsp-low-selftests.c
@@ -51,7 +51,7 @@ static void test_hex2str ()
{
SELF_CHECK (hex2str ("666f6f") == "foo");
SELF_CHECK (hex2str ("666f6fa") == "foo");
- SELF_CHECK (hex2str ("666f6f", 2) == "fo");
+ SELF_CHECK (hex2str ("666f6f", 2) == "fo"); /* codespell:ignore */
SELF_CHECK (hex2str ("666", 2) == "f");
SELF_CHECK (hex2str ("666", 6) == "f");
SELF_CHECK (hex2str ("") == "");
diff --git a/gdb/valops.c b/gdb/valops.c
index 09af0ae..94f908d 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -1695,6 +1695,9 @@ value_array (int lowbound, gdb::array_view<struct value *> elemvec)
/* Validate that the bounds are reasonable and that each of the
elements have the same size. */
+ if (elemvec.empty ())
+ error (_("size of the array element must not be zero"));
+
typelength = type_length_units (elemvec[0]->enclosing_type ());
for (struct value *other : elemvec.slice (1))
{
@@ -2417,47 +2420,42 @@ value_struct_elt (struct value **argp,
return v;
}
-/* Given *ARGP, a value of type structure or union, or a pointer/reference
+/* Given VAL, a value of type structure or union, or a pointer/reference
to a structure or union, extract and return its component (field) of
type FTYPE at the specified BITPOS.
Throw an exception on error. */
struct value *
-value_struct_elt_bitpos (struct value **argp, int bitpos, struct type *ftype,
- const char *err)
+value_struct_elt_bitpos (struct value *val, int bitpos, struct type *ftype)
{
struct type *t;
int i;
- *argp = coerce_array (*argp);
+ val = coerce_array (val);
- t = check_typedef ((*argp)->type ());
+ t = check_typedef (val->type ());
while (t->is_pointer_or_reference ())
{
- *argp = value_ind (*argp);
- if (check_typedef ((*argp)->type ())->code () != TYPE_CODE_FUNC)
- *argp = coerce_array (*argp);
- t = check_typedef ((*argp)->type ());
+ val = value_ind (val);
+ if (check_typedef (val->type ())->code () != TYPE_CODE_FUNC)
+ val = coerce_array (val);
+ t = check_typedef (val->type ());
}
if (t->code () != TYPE_CODE_STRUCT
&& t->code () != TYPE_CODE_UNION)
- error (_("Attempt to extract a component of a value that is not a %s."),
- err);
+ error (_("Attempt to extract a component of non-aggregate value."));
for (i = TYPE_N_BASECLASSES (t); i < t->num_fields (); i++)
{
if (!t->field (i).is_static ()
&& bitpos == t->field (i).loc_bitpos ()
&& types_equal (ftype, t->field (i).type ()))
- return (*argp)->primitive_field (0, i, t);
+ return val->primitive_field (0, i, t);
}
error (_("No field with matching bitpos and type."));
-
- /* Never hit. */
- return NULL;
}
/* Search through the methods of an object (and its bases) to find a
diff --git a/gdb/value.h b/gdb/value.h
index 0cbcfca..71d0ba1 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -1297,10 +1297,9 @@ extern struct value *value_struct_elt (struct value **argp,
const char *name, int *static_memfuncp,
const char *err);
-extern struct value *value_struct_elt_bitpos (struct value **argp,
+extern struct value *value_struct_elt_bitpos (struct value *val,
int bitpos,
- struct type *field_type,
- const char *err);
+ struct type *field_type);
extern struct value *value_aggregate_elt (struct type *curtype,
const char *name,
diff --git a/gprofng/src/gp-archive.cc b/gprofng/src/gp-archive.cc
index 4e68336..ee9f917 100644
--- a/gprofng/src/gp-archive.cc
+++ b/gprofng/src/gp-archive.cc
@@ -140,7 +140,8 @@ er_archive::usage ()
"See also:\n"
"\n"
"gprofng(1), gprofng-collect-app(1), gprofng-display-html(1), "
- "gprofng-display-src(1), gprofng-display-text(1)\n"));
+ "gprofng-display-src(1), gprofng-display-text(1)\n"
+ "\nReport bugs to <https://sourceware.org/bugzilla/>\n"));
exit (1);
}
diff --git a/gprofng/src/gp-collect-app.cc b/gprofng/src/gp-collect-app.cc
index bf146d9..b94f410 100644
--- a/gprofng/src/gp-collect-app.cc
+++ b/gprofng/src/gp-collect-app.cc
@@ -1481,7 +1481,8 @@ collect::usage ()
"See also:\n"
"\n"
"gprofng(1), gprofng-archive(1), gprofng-display-html(1), "
- "gpgprofng-display-src(1), gprofng-display-text(1)\n"));
+ "gpgprofng-display-src(1), gprofng-display-text(1)\n"
+ "\nReport bugs to <https://sourceware.org/bugzilla/>\n"));
}
void
diff --git a/gprofng/src/gp-display-src.cc b/gprofng/src/gp-display-src.cc
index 7eb6b33..5475f27 100644
--- a/gprofng/src/gp-display-src.cc
+++ b/gprofng/src/gp-display-src.cc
@@ -172,7 +172,8 @@ er_src::usage ()
"See also:\n"
"\n"
"gprofng(1), gprofng-archive(1), gprofng-collect-app(1), "
- "gprofng-display-html(1), gprofng-display-text(1)\n"));
+ "gprofng-display-html(1), gprofng-display-text(1)\n"
+ "\nReport bugs to <https://sourceware.org/bugzilla/>\n"));
/*
printf (GTXT ("Usage: %s [OPTION] a.out/.so/.o/.class\n\n"), whoami);
printf (GTXT (" -func List all the functions from the given object\n"
diff --git a/gprofng/src/gp-display-text.cc b/gprofng/src/gp-display-text.cc
index 4fcd639..32bda49 100644
--- a/gprofng/src/gp-display-text.cc
+++ b/gprofng/src/gp-display-text.cc
@@ -254,7 +254,8 @@ er_print::usage ()
"See also:\n"
"\n"
"gprofng(1), gprofng-archive(1), gprofng-collect-app(1), "
- "gprofng-display-html(1), gprofng-display-src(1)\n"));
+ "gprofng-display-html(1), gprofng-display-src(1)\n"
+ "\nReport bugs to <https://sourceware.org/bugzilla/>\n"));
}
int // returns count of experiments read
diff --git a/gprofng/src/gprofng.cc b/gprofng/src/gprofng.cc
index 99f904a..4364d97 100644
--- a/gprofng/src/gprofng.cc
+++ b/gprofng/src/gprofng.cc
@@ -155,7 +155,8 @@ Gprofng::usage ()
"See also:\n"
"\n"
"gprofng-archive(1), gprofng-collect-app(1), gprofng-display-html(1), "
- "gprofng-display-src(1), gprofng-display-text(1)\n"));
+ "gprofng-display-src(1), gprofng-display-text(1)\n"
+ "\nReport bugs to <https://sourceware.org/bugzilla/>\n"));
/*
printf ( GTXT (
diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
index 9a2b576..50bb082 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -7,11 +7,11 @@ else
fi
case ${target} in
- *-*-cygwin*)
- cygwin_behavior=1
+ *-*-mingw*)
+ mingw_behavior=1
;;
*)
- cygwin_behavior=0;
+ mingw_behavior=0
;;
esac
@@ -126,9 +126,10 @@ fragment <<EOF
#define DEFAULT_PSEUDO_RELOC_VERSION 1
#endif
-#define DEFAULT_DLL_CHARACTERISTICS (${cygwin_behavior} ? 0 : \
- IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE \
- | IMAGE_DLL_CHARACTERISTICS_NX_COMPAT)
+#define DEFAULT_DLL_CHARACTERISTICS (${mingw_behavior} \
+ ? IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE \
+ | IMAGE_DLL_CHARACTERISTICS_NX_COMPAT \
+ : 0)
#if defined(TARGET_IS_i386pe) || ! defined(DLL_SUPPORT)
#define PE_DEF_SUBSYSTEM IMAGE_SUBSYSTEM_WINDOWS_CUI
diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
index 440c0bf..60a8339 100644
--- a/ld/emultempl/pep.em
+++ b/ld/emultempl/pep.em
@@ -9,11 +9,15 @@ fi
case ${target} in
*-*-cygwin*)
move_default_addr_high=1
- cygwin_behavior=1
+ mingw_behavior=0
+ ;;
+ *-*-mingw*)
+ move_default_addr_high=0
+ mingw_behavior=1
;;
*)
- move_default_addr_high=0;
- cygwin_behavior=0;
+ move_default_addr_high=0
+ mingw_behavior=0
;;
esac
@@ -126,10 +130,11 @@ fragment <<EOF
#define DLL_SUPPORT
#endif
-#define DEFAULT_DLL_CHARACTERISTICS (${cygwin_behavior} ? 0 : \
- IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE \
- | IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA \
- | IMAGE_DLL_CHARACTERISTICS_NX_COMPAT)
+#define DEFAULT_DLL_CHARACTERISTICS (${mingw_behavior} \
+ ? IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE \
+ | IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA \
+ | IMAGE_DLL_CHARACTERISTICS_NX_COMPAT \
+ : 0)
#if defined(TARGET_IS_i386pep) || defined(COFF_WITH_peAArch64) || ! defined(DLL_SUPPORT)
#define PE_DEF_SUBSYSTEM IMAGE_SUBSYSTEM_WINDOWS_CUI
diff --git a/ld/ld.texi b/ld/ld.texi
index 29bd0e1..e8e09f8 100644
--- a/ld/ld.texi
+++ b/ld/ld.texi
@@ -3781,7 +3781,8 @@ of the PE file header:
@item --high-entropy-va
@itemx --disable-high-entropy-va
Image is compatible with 64-bit address space layout randomization
-(ASLR). This option is enabled by default for 64-bit PE images.
+(ASLR). This option is enabled by default for 64-bit PE images in
+MinGW targets.
This option also implies @option{--dynamicbase} and
@option{--enable-reloc-section}.
@@ -3791,9 +3792,9 @@ This option also implies @option{--dynamicbase} and
@itemx --disable-dynamicbase
The image base address may be relocated using address space layout
randomization (ASLR). This feature was introduced with MS Windows
-Vista for i386 PE targets. This option is enabled by default but
-can be disabled via the @option{--disable-dynamicbase} option.
-This option also implies @option{--enable-reloc-section}.
+Vista for i386 PE targets. This option is enabled by default for MinGW
+targets but can be disabled via the @option{--disable-dynamicbase}
+option. This option also implies @option{--enable-reloc-section}.
@kindex --forceinteg
@item --forceinteg
@@ -3806,7 +3807,7 @@ default.
@item --disable-nxcompat
The image is compatible with the Data Execution Prevention.
This feature was introduced with MS Windows XP SP2 for i386 PE
-targets. The option is enabled by default.
+targets. The option is enabled by default for MinGW targets.
@kindex --no-isolation
@item --no-isolation
diff --git a/ld/ldmain.c b/ld/ldmain.c
index 91237a4..67c60c3 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -423,8 +423,8 @@ ld_stop_phase (ld_phase phase)
if (pd->begin.ru_maxrss < usage.ru_maxrss)
pd->use.ru_maxrss += usage.ru_maxrss - pd->begin.ru_maxrss;
-#endif
}
+#endif
}
static void
@@ -563,8 +563,8 @@ report_phases (FILE * file, time_t * start, char ** argv)
COLUMN_ENTRY (pd->duration, "ld", 1);
#if defined (HAVE_GETRUSAGE)
COLUMN_ENTRY (pd->use.ru_maxrss, "ld", 2);
- COLUMN_ENTRY (pd->use.ru_utime.tv_sec, "ld", 3);
- COLUMN_ENTRY (pd->use.ru_stime.tv_sec, "ld", 4);
+ COLUMN_ENTRY ((int64_t) pd->use.ru_utime.tv_sec, PRId64, 3);
+ COLUMN_ENTRY ((int64_t) pd->use.ru_stime.tv_sec, PRId64, 4);
#endif
fprintf (file, "\n");
}
diff --git a/ld/testsuite/ld-aarch64/protections/bti-and-memory-seal-plt-1-a.d b/ld/testsuite/ld-aarch64/protections/bti-and-memory-seal-plt-1-a.d
new file mode 100644
index 0000000..f8b1c21
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/protections/bti-and-memory-seal-plt-1-a.d
@@ -0,0 +1,45 @@
+#name: No '-z force-bti' with '-z memory-seal' with feature properties (BTI) forces the generation of BTI PLT (shared)
+#source: bti-plt-1.s
+#source: bti-plt-2.s
+#target: [check_shared_lib_support]
+#as: -mabi=lp64 -defsym __property_bti__=1
+#ld: -shared -z memory-seal -T bti-plt.ld -L./tmpdir -lbti-plt-so
+#objdump: -dr -j .plt
+
+[^:]*: *file format elf64-.*aarch64
+
+Disassembly of section \.plt:
+
+[0-9]+ <\.plt>:
+.*: d503245f bti c
+.*: a9bf7bf0 stp x16, x30, \[sp, #-16\]!
+.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_>
+.*: f9400e11 ldr x17, \[x16, #24\]
+.*: 91006210 add x16, x16, #0x18
+.*: d61f0220 br x17
+.*: d503201f nop
+.*: d503201f nop
+
+[0-9]+ <.*>:
+.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_>
+.*: f9401211 ldr x17, \[x16, #32\]
+.*: 91008210 add x16, x16, #0x20
+.*: d61f0220 br x17
+
+[0-9]+ <.*>:
+.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_>
+.*: f9401611 ldr x17, \[x16, #40\]
+.*: 9100a210 add x16, x16, #0x28
+.*: d61f0220 br x17
+
+[0-9]+ <.*>:
+.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_>
+.*: f9401a11 ldr x17, \[x16, #48\]
+.*: 9100c210 add x16, x16, #0x30
+.*: d61f0220 br x17
+
+[0-9]+ <.*>:
+.*: 90000090 adrp x16, 28000 <_GLOBAL_OFFSET_TABLE_>
+.*: f9401e11 ldr x17, \[x16, #56\]
+.*: 9100e210 add x16, x16, #0x38
+.*: d61f0220 br x17
diff --git a/ld/testsuite/ld-aarch64/protections/bti-and-memory-seal-plt-1-b.d b/ld/testsuite/ld-aarch64/protections/bti-and-memory-seal-plt-1-b.d
new file mode 100644
index 0000000..0dadcc9
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/protections/bti-and-memory-seal-plt-1-b.d
@@ -0,0 +1,14 @@
+#name: No '-z force-bti' with '-z memory-seal' all input objects have BTI emits BTI feature (shared)
+#source: bti-plt-1.s
+#source: bti-plt-2.s
+#target: [check_shared_lib_support]
+#as: -mabi=lp64 -defsym __property_bti__=1
+#ld: -z memory-seal -shared -T bti-plt.ld
+#readelf: -n
+
+Displaying notes found in: .note.gnu.property
+[ ]+Owner[ ]+Data size[ ]+Description
+ GNU 0x00000018 NT_GNU_PROPERTY_TYPE_0
+ Properties: memory seal\s
+\s+AArch64 feature: BTI
+#pass
diff --git a/ld/testsuite/ld-aarch64/protections/bti-plt-1-b.d b/ld/testsuite/ld-aarch64/protections/bti-plt-1-b.d
index 1bf956c..4b0e424 100644
--- a/ld/testsuite/ld-aarch64/protections/bti-plt-1-b.d
+++ b/ld/testsuite/ld-aarch64/protections/bti-plt-1-b.d
@@ -2,7 +2,7 @@
#source: bti-plt-1.s
#target: [check_shared_lib_support]
#as: -mabi=lp64 -defsym __property_bti__=1
-#ld: -shared -z force-bti -T bti-plt.ld -L./tmpdir -lbti-plt-so
+#ld: -shared -T bti-plt.ld -L./tmpdir -lbti-plt-so
#objdump: -dr -j .plt
[^:]*: *file format elf64-.*aarch64
diff --git a/ld/testsuite/ld-plugin/lto.exp b/ld/testsuite/ld-plugin/lto.exp
index 9349190..3a56fb5 100644
--- a/ld/testsuite/ld-plugin/lto.exp
+++ b/ld/testsuite/ld-plugin/lto.exp
@@ -1212,6 +1212,38 @@ if { [is_elf_format] } {
if { [is_elf_format] && [check_lto_shared_available] } {
run_ld_link_exec_tests $lto_run_elf_shared_tests
+ if { [check_lto_fat_available] } {
+ run_cc_link_tests [list \
+ [list \
+ "Build libpr32846a.a" \
+ "$plug_opt" "-fPIC -O2 -flto $lto_no_fat" \
+ {pr32846a.c pr32846b.c} {} "libpr32846a.a" \
+ ] \
+ [list \
+ "Build libpr32846b.a" \
+ "$plug_opt" "-fPIC -O2 -flto $lto_no_fat" \
+ {pr32846a.c pr32846b.c pr32846c.c} {} "libpr32846b.a" \
+ ] \
+ [list \
+ "Build pr32846d.o" \
+ "$plug_opt" "-fPIC -O2 -flto $lto_no_fat" \
+ {pr32846d.c} {} \
+ ] \
+ [list \
+ "Build pr32846e.o" \
+ "$plug_opt" "-fPIC -O2 -flto $lto_no_fat" \
+ {pr32846e.c} {} \
+ ] \
+ [list \
+ "Build pr32846" \
+ "-shared -fPIC -O2 -flto $lto_no_fat -Wl,--no-undefined \
+ tmpdir/pr32846d.o tmpdir/libpr32846a.a \
+ tmpdir/libpr32846b.a tmpdir/pr32846e.o" \
+ "-O2 -fPIC -flto $lto_no_fat" \
+ {dummy.c} {} "pr32846" \
+ ] \
+ ] \
+ }
}
proc pr20103 {cflags libs} {
diff --git a/ld/testsuite/ld-plugin/pr32846a.c b/ld/testsuite/ld-plugin/pr32846a.c
new file mode 100644
index 0000000..8c16171
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr32846a.c
@@ -0,0 +1,6 @@
+extern void mkdir_p (void);
+void
+mkdir_parents (void)
+{
+ mkdir_p ();
+}
diff --git a/ld/testsuite/ld-plugin/pr32846b.c b/ld/testsuite/ld-plugin/pr32846b.c
new file mode 100644
index 0000000..9776a37
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr32846b.c
@@ -0,0 +1,4 @@
+void
+hash_new (void)
+{
+}
diff --git a/ld/testsuite/ld-plugin/pr32846c.c b/ld/testsuite/ld-plugin/pr32846c.c
new file mode 100644
index 0000000..f87cffb
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr32846c.c
@@ -0,0 +1,6 @@
+extern void hash_new (void);
+void
+kmod_new (void)
+{
+ hash_new();
+}
diff --git a/ld/testsuite/ld-plugin/pr32846d.c b/ld/testsuite/ld-plugin/pr32846d.c
new file mode 100644
index 0000000..c6f4102
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr32846d.c
@@ -0,0 +1,12 @@
+extern void kmod_new (void);
+extern void mkdir_parents (void);
+void
+do_lsmod (void)
+{
+ kmod_new ();
+}
+void
+do_static_nodes (void)
+{
+ mkdir_parents();
+}
diff --git a/ld/testsuite/ld-plugin/pr32846e.c b/ld/testsuite/ld-plugin/pr32846e.c
new file mode 100644
index 0000000..c4e5e56
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr32846e.c
@@ -0,0 +1,4 @@
+void
+mkdir_p (void)
+{
+}
diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c
index bd3cd8f..df80130 100644
--- a/opcodes/i386-gen.c
+++ b/opcodes/i386-gen.c
@@ -356,11 +356,11 @@ static bitfield cpu_flags[] =
BITFIELD (3dnow),
BITFIELD (3dnowA),
BITFIELD (PadLock),
- BITFIELD (GMISM2),
- BITFIELD (GMICCS),
BITFIELD (PadLockRNG2),
BITFIELD (PadLockPHE2),
BITFIELD (PadLockXMODX),
+ BITFIELD (GMISM2),
+ BITFIELD (GMICCS),
BITFIELD (SVME),
BITFIELD (VMX),
BITFIELD (SMX),
diff --git a/opcodes/i386-init.h b/opcodes/i386-init.h
index a752b6c..0c9ae65 100644
--- a/opcodes/i386-init.h
+++ b/opcodes/i386-init.h
@@ -208,8 +208,8 @@
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
-#define CPU_GMISM2_FLAGS \
- { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, \
+#define CPU_PADLOCKRNG2_FLAGS \
+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
@@ -218,8 +218,8 @@
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
-#define CPU_GMICCS_FLAGS \
- { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+#define CPU_PADLOCKPHE2_FLAGS \
+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, \
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
@@ -228,7 +228,7 @@
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
-#define CPU_PADLOCKRNG2_FLAGS \
+#define CPU_PADLOCKXMODX_FLAGS \
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, \
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
@@ -238,8 +238,8 @@
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
-#define CPU_PADLOCKPHE2_FLAGS \
- { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, \
+#define CPU_GMISM2_FLAGS \
+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
@@ -248,8 +248,8 @@
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
-#define CPU_PADLOCKXMODX_FLAGS \
- { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, \
+#define CPU_GMICCS_FLAGS \
+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
@@ -1979,8 +1979,8 @@
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
#define CPU_ANY_PADLOCK_FLAGS \
- { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, \
- 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, \
+ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
@@ -1989,8 +1989,8 @@
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
#define CPU_ANY_PADLOCKRNG2_FLAGS \
- { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, \
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
@@ -2000,7 +2000,7 @@
#define CPU_ANY_PADLOCKPHE2_FLAGS \
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
@@ -2010,7 +2010,7 @@
#define CPU_ANY_PADLOCKXMODX_FLAGS \
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
diff --git a/opcodes/i386-opc.h b/opcodes/i386-opc.h
index fac0371..9e3ed63 100644
--- a/opcodes/i386-opc.h
+++ b/opcodes/i386-opc.h
@@ -66,16 +66,16 @@ enum i386_cpu
CpuSSE3,
/* VIA PadLock required */
CpuPadLock,
- /* Zhaoxin GMI SM2 required */
- CpuGMISM2,
- /* Zhaoxin GMI CCS required */
- CpuGMICCS,
/* Zhaoxin PadLock RNG2 required */
CpuPadLockRNG2,
/* Zhaoxin PadLock PHE2 required */
CpuPadLockPHE2,
/* Zhaoxin PadLock XMODX required */
CpuPadLockXMODX,
+ /* Zhaoxin GMI SM2 required */
+ CpuGMISM2,
+ /* Zhaoxin GMI CCS required */
+ CpuGMICCS,
/* AMD Secure Virtual Machine Ext-s required */
CpuSVME,
/* VMX Instructions required */
@@ -428,11 +428,11 @@ typedef union i386_cpu_flags
unsigned int cpusse2:1;
unsigned int cpusse3:1;
unsigned int cpupadlock:1;
- unsigned int cpugmism2:1;
- unsigned int cpugmiccs:1;
unsigned int cpupadlockrng2:1;
unsigned int cpupadlockphe2:1;
unsigned int cpupadlockxmodx:1;
+ unsigned int cpugmism2:1;
+ unsigned int cpugmiccs:1;
unsigned int cpusvme:1;
unsigned int cpuvmx:1;
unsigned int cpusmx:1;
diff --git a/opcodes/i386-tbl.h b/opcodes/i386-tbl.h
index c7d2912..c12c69e 100644
--- a/opcodes/i386-tbl.h
+++ b/opcodes/i386-tbl.h
@@ -35660,7 +35660,7 @@ static const insn_template i386_optab[] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
- { { 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { { 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
{ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0 } } } },
@@ -35668,7 +35668,7 @@ static const insn_template i386_optab[] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
- { { 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { { 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
{ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0 } } } },
@@ -35676,7 +35676,7 @@ static const insn_template i386_optab[] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
- { { 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { { 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
{ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0 } } } },
@@ -35684,7 +35684,7 @@ static const insn_template i386_optab[] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
- { { 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { { 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
{ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0 } } } },
@@ -35692,7 +35692,7 @@ static const insn_template i386_optab[] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
- { { 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { { 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
{ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0 } } } },
@@ -35700,7 +35700,7 @@ static const insn_template i386_optab[] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
- { { 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { { 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
{ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0 } } } },
@@ -35708,7 +35708,7 @@ static const insn_template i386_optab[] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
- { { 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { { 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
{ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0 } } } },
@@ -35716,7 +35716,7 @@ static const insn_template i386_optab[] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0 },
- { { 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
+ { { 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
{ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0 } } } },
diff --git a/opcodes/loongarch-opc.c b/opcodes/loongarch-opc.c
index a172a2a..fa53021 100644
--- a/opcodes/loongarch-opc.c
+++ b/opcodes/loongarch-opc.c
@@ -454,6 +454,9 @@ static struct loongarch_opcode loongarch_macro_opcodes[] =
static struct loongarch_opcode loongarch_alias_opcodes[] =
{
/* match, mask, name, format, macro, include, exclude, pinfo. */
+ { 0x00006000, 0xffffffe0, "rdcntvl.w", "r0:5", 0, 0, 0, INSN_DIS_ALIAS }, /* rdtimel.w rd, zero */
+ { 0x00006000, 0xfffffc1f, "rdcntid.w", "r5:5", 0, 0, 0, INSN_DIS_ALIAS }, /* rdtimel.w zero, rj */
+ { 0x00006400, 0xffffffe0, "rdcntvh.w", "r0:5", 0, 0, 0, INSN_DIS_ALIAS }, /* rdtimeh.w rd, zero */
{ 0x00150000, 0xfffffc00, "move", "r0:5,r5:5", 0, 0, 0, INSN_DIS_ALIAS }, /* or rd, rj, zero */
{ 0x02800000, 0xffc003e0, "li.w", "r0:5,s10:12", 0, 0, 0, INSN_DIS_ALIAS }, /* addi.w rd, zero, simm */
{ 0x02c00000, 0xffc003e0, "li.d", "r0:5,s10:12", 0, 0, 0, INSN_DIS_ALIAS }, /* addi.d rd, zero, simm */
@@ -494,7 +497,10 @@ static struct loongarch_opcode loongarch_fix_opcodes[] =
{ 0x00005400, 0xfffffc00, "bitrev.d", "r0:5,r5:5", 0, 0, 0, 0 },
{ 0x00005800, 0xfffffc00, "ext.w.h", "r0:5,r5:5", 0, 0, 0, 0 },
{ 0x00005c00, 0xfffffc00, "ext.w.b", "r0:5,r5:5", 0, 0, 0, 0 },
+ { 0x0, 0x0, "rdcntvl.w", "r", "rdtimel.w %1,$r0", 0, 0, 0 },
+ { 0x0, 0x0, "rdcntid.w", "r", "rdtimel.w $r0,%1", 0, 0, 0 },
{ 0x00006000, 0xfffffc00, "rdtimel.w", "r0:5,r5:5", 0, 0, 0, 0 },
+ { 0x0, 0x0, "rdcntvh.w", "r", "rdtimeh.w %1,$r0", 0, 0, 0 },
{ 0x00006400, 0xfffffc00, "rdtimeh.w", "r0:5,r5:5", 0, 0, 0, 0 },
{ 0x00006800, 0xfffffc00, "rdtime.d", "r0:5,r5:5", 0, 0, 0, 0 },
{ 0x00006c00, 0xfffffc00, "cpucfg", "r0:5,r5:5", 0, 0, 0, 0 },
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index f862ef2..277b8fd 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -69,7 +69,7 @@ struct riscv_private_data
const char (*riscv_fpr_names)[NRC];
/* If set, disassemble as most general instruction. */
bool no_aliases;
- /* If set, disassemble without checking architectire string, just like what
+ /* If set, disassemble without checking architecture string, just like what
we did at the beginning. */
bool all_ext;
};
@@ -83,6 +83,7 @@ set_default_riscv_dis_options (struct disassemble_info *info)
pd->riscv_gpr_names = riscv_gpr_names_abi;
pd->riscv_fpr_names = riscv_fpr_names_abi;
pd->no_aliases = false;
+ pd->all_ext = false;
}
/* Parse RISC-V disassembler option (without arguments). */
@@ -1580,6 +1581,9 @@ static struct
riscv_option_arg_t arg;
} riscv_options[] =
{
+ { "max",
+ N_("Disassemble without checking architecture string."),
+ RISCV_OPTION_ARG_NONE },
{ "numeric",
N_("Print numeric register names, rather than ABI names."),
RISCV_OPTION_ARG_NONE },