aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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/elfxx-x86.c20
-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/resbin.c439
-rw-r--r--binutils/rescoff.c216
-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/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/cli/cli-decode.h2
-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/printcmds.exp7
-rw-r--r--gdb/valops.c3
-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.c2
-rw-r--r--ld/testsuite/ld-plugin/lto.exp20
-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
34 files changed, 1037 insertions, 294 deletions
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/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/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 f6a6581..532112c 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 20250412
+#define BFD_VERSION_DATE 20250415
#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/resbin.c b/binutils/resbin.c
index 388b016..1698e14 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,7 +132,10 @@ 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;
@@ -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;
}
}
@@ -204,7 +215,10 @@ 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->xhotspot = windres_get_16 (wrbfd, data, 2);
@@ -235,32 +249,51 @@ bin_to_res_menu (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length)
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;
}
@@ -285,7 +318,10 @@ 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->state = 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;
@@ -324,6 +367,8 @@ bin_to_res_menuitems (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type len
mi->id = 0;
mi->popup = bin_to_res_menuitems (wrbfd, data + itemlen, length - itemlen,
&subread);
+ if (mi->popup == NULL)
+ return NULL;
itemlen += subread;
}
@@ -362,7 +407,10 @@ 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->type = windres_get_32 (wrbfd, data, 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,12 +481,16 @@ 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));
@@ -447,7 +508,10 @@ 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->help = windres_get_32 (wrbfd, data + 4, 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;
}
@@ -526,7 +607,10 @@ bin_to_res_dialog (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
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,7 +672,10 @@ 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)));
@@ -615,7 +715,10 @@ bin_to_res_string (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type length
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,7 +728,10 @@ 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));
st->strings[i].string = s;
@@ -655,7 +761,10 @@ bin_to_res_fontdir (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
rc_res_resource *r;
if (length < 2)
- toosmall (_("fontdir header"));
+ {
+ toosmall (_("fontdir header"));
+ return NULL;
+ }
c = windres_get_16 (wrbfd, data, 2);
@@ -669,7 +778,10 @@ 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);
@@ -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;
@@ -732,7 +850,10 @@ 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));
@@ -791,11 +912,17 @@ bin_to_res_group_cursor (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type
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,7 +937,10 @@ 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);
@@ -846,11 +976,17 @@ bin_to_res_group_icon (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type le
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,7 +1001,10 @@ 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));
@@ -897,14 +1036,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
+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 +1062,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 +1071,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,6 +1093,7 @@ 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. */
@@ -956,16 +1107,23 @@ 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. */
length = verlen;
@@ -980,18 +1138,31 @@ 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));
@@ -1020,7 +1191,10 @@ 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));
@@ -1032,12 +1206,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,15 +1233,24 @@ 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));
- 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;
@@ -1079,30 +1267,42 @@ bin_to_res_version (windres_bfd *wrbfd, const bfd_byte *data, rc_uint_type lengt
rc_uint_type sverlen, vslen, valoff;
if (length < 8)
- toosmall (_("version string"));
+ {
+ toosmall (_("version string"));
+ return NULL;
+ }
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);
+ 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)
- fatal (_("unexpected version string length %ld != %ld + %ld"),
- (long) sverlen, (long) off, (long) valoff);
+ {
+ non_fatal (_("unexpected version string length %ld != %ld + %ld"),
+ (long) sverlen, (long) off, (long) valoff);
+ return NULL;
+ }
data += valoff;
length -= valoff;
if (stverlen < sverlen)
- fatal (_("unexpected version string length %ld < %ld"),
- (long) verlen, (long) sverlen);
+ {
+ non_fatal (_("unexpected version string length %ld < %ld"),
+ (long) verlen, (long) sverlen);
+ return NULL;
+ }
stverlen -= sverlen;
verlen -= sverlen;
@@ -1122,18 +1322,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,7 +1353,10 @@ 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));
@@ -1161,7 +1371,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,10 +1385,14 @@ 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;
@@ -1216,12 +1434,18 @@ 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;
+ if (length < 12)
+ {
+ toosmall (_("toolbar"));
+ return NULL;
+ }
ri = (rc_toolbar *) res_alloc (sizeof (rc_toolbar));
ri->button_width = windres_get_32 (wrbfd, data, 4);
ri->button_height = windres_get_32 (wrbfd, data + 4, 4);
@@ -1229,14 +1453,18 @@ bin_to_res_toolbar (windres_bfd *wrbfd, const bfd_byte *data)
ri->items = NULL;
data += 12;
- for (i=0 ; i < ri->nitems; i++)
+ length -= 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;
+ if (length < 4)
+ toosmall (_("toolbar item"));
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)
@@ -1740,11 +1968,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);
@@ -1855,22 +2084,22 @@ 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++)
+ 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;
@@ -1902,10 +2131,10 @@ res_to_bin_stringtable (windres_bfd *wrbfd, rc_uint_type off,
hp = (bfd_byte *) 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;
diff --git a/binutils/rescoff.c b/binutils/rescoff.c
index f9a1e70..98e5eb0 100644
--- a/binutils/rescoff.c
+++ b/binutils/rescoff.c
@@ -120,27 +120,38 @@ 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);
+ 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);
+ 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);
+ return NULL;
}
set_windres_bfd (&wrbfd, abfd, sec, WR_KIND_BFD);
@@ -150,7 +161,10 @@ 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);
+ return NULL;
+ }
data = (bfd_byte *) res_alloc (size);
get_windres_bfd_content (&wrbfd, data, 0, size);
@@ -178,7 +192,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 +213,16 @@ 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"));
+ {
+ overrun (flaginfo, _("directory"));
+ return NULL;
+ }
erd = (const struct extern_res_directory *) data;
@@ -230,7 +250,10 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
int length, j;
if ((const bfd_byte *) ere >= flaginfo->data_end)
- overrun (flaginfo, _("named directory entry"));
+ {
+ overrun (flaginfo, _("named directory entry"));
+ return NULL;
+ }
name = windres_get_32 (wrbfd, ere->name, 4);
rva = windres_get_32 (wrbfd, ere->rva, 4);
@@ -239,7 +262,10 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
name &=~ 0x80000000;
if (name > (rc_uint_type) (flaginfo->data_end - flaginfo->data))
- overrun (flaginfo, _("directory entry name"));
+ {
+ overrun (flaginfo, _("directory entry name"));
+ return NULL;
+ }
ers = flaginfo->data + name;
@@ -252,8 +278,12 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
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"));
+ if (length < 0 || ers >= flaginfo->data_end
+ || ers + j * 2 + 4 >= flaginfo->data_end)
+ {
+ overrun (flaginfo, _("resource name"));
+ return NULL;
+ }
re->id.u.n.name[j] = windres_get_16 (wrbfd, ers + j * 2 + 2, 2);
}
@@ -264,7 +294,10 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
{
rva &=~ 0x80000000;
if (rva >= (rc_uint_type) (flaginfo->data_end - flaginfo->data))
- overrun (flaginfo, _("named subdirectory"));
+ {
+ overrun (flaginfo, _("named subdirectory"));
+ return NULL;
+ }
re->subdir = 1;
re->u.dir = read_coff_res_dir (wrbfd, flaginfo->data + rva, flaginfo, type,
level + 1);
@@ -272,7 +305,10 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
else
{
if (rva >= (rc_uint_type) (flaginfo->data_end - flaginfo->data))
- overrun (flaginfo, _("named resource"));
+ {
+ overrun (flaginfo, _("named resource"));
+ return NULL;
+ }
re->subdir = 0;
re->u.res = read_coff_data_entry (wrbfd, flaginfo->data + rva, flaginfo, type);
}
@@ -287,7 +323,10 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
rc_res_entry *re;
if ((const bfd_byte *) ere >= flaginfo->data_end)
- overrun (flaginfo, _("ID directory entry"));
+ {
+ overrun (flaginfo, _("ID directory entry"));
+ return NULL;
+ }
name = windres_get_32 (wrbfd, ere->name, 4);
rva = windres_get_32 (wrbfd, ere->rva, 4);
@@ -304,7 +343,10 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
{
rva &=~ 0x80000000;
if (rva >= (rc_uint_type) (flaginfo->data_end - flaginfo->data))
- overrun (flaginfo, _("ID subdirectory"));
+ {
+ overrun (flaginfo, _("ID subdirectory"));
+ return NULL;
+ }
re->subdir = 1;
re->u.dir = read_coff_res_dir (wrbfd, flaginfo->data + rva, flaginfo, type,
level + 1);
@@ -312,7 +354,10 @@ read_coff_res_dir (windres_bfd *wrbfd, const bfd_byte *data,
else
{
if (rva >= (rc_uint_type) (flaginfo->data_end - flaginfo->data))
- overrun (flaginfo, _("ID resource"));
+ {
+ overrun (flaginfo, _("ID resource"));
+ return NULL;
+ }
re->subdir = 0;
re->u.res = read_coff_data_entry (wrbfd, flaginfo->data + rva, flaginfo, type);
}
@@ -337,10 +382,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 +399,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 +481,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 +494,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 +507,77 @@ 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");
+ 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)");
+ 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)");
+ 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)");
+ 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)");
+ 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)");
+ 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");
+ 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");
+ return false;
+ }
if (! bfd_set_symtab (abfd, &sec->symbol, 1))
- bfd_fatal ("bfd_set_symtab");
+ {
+ bfd_nonfatal ("bfd_set_symtab");
+ return false;
+ }
/* Requiring this is probably a bug in BFD. */
sec->output_section = sec;
@@ -529,7 +621,8 @@ 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))
+ return false;
/* Add another few bytes to the directory strings if needed for
alignment. */
@@ -554,7 +647,10 @@ 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");
+ return false;
+ }
bfd_set_reloc (abfd, sec, cwi.relocs, cwi.reloc_count);
@@ -562,7 +658,10 @@ 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");
+ return false;
+ }
offset += d->length;
}
for (d = cwi.dirstrs.d; d != NULL; d = d->next)
@@ -577,17 +676,23 @@ 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)
+ return false;
offset += rd->length;
}
assert (offset == length);
if (! bfd_close (abfd))
- bfd_fatal ("bfd_close");
+ {
+ bfd_nonfatal ("bfd_close");
+ 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 +745,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 +806,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 +843,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 +866,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 +883,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/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/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/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/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/valops.c b/gdb/valops.c
index 09af0ae..1b63343 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))
{
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..716272b 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
diff --git a/ld/testsuite/ld-plugin/lto.exp b/ld/testsuite/ld-plugin/lto.exp
index 726dd93..3a56fb5 100644
--- a/ld/testsuite/ld-plugin/lto.exp
+++ b/ld/testsuite/ld-plugin/lto.exp
@@ -1215,24 +1215,24 @@ if { [is_elf_format] && [check_lto_shared_available] } {
if { [check_lto_fat_available] } {
run_cc_link_tests [list \
[list \
- "Build libpr32846a.a" \
- "$plug_opt" "-O2 -flto $lto_no_fat" \
- {pr32846a.c pr32846b.c} {} "libpr32846a.a" \
+ "Build libpr32846a.a" \
+ "$plug_opt" "-fPIC -O2 -flto $lto_no_fat" \
+ {pr32846a.c pr32846b.c} {} "libpr32846a.a" \
] \
[list \
"Build libpr32846b.a" \
- "$plug_opt" "-O2 -flto $lto_no_fat" \
+ "$plug_opt" "-fPIC -O2 -flto $lto_no_fat" \
{pr32846a.c pr32846b.c pr32846c.c} {} "libpr32846b.a" \
] \
[list \
- "Build pr32846d.o" \
- "$plug_opt" "-O2 -flto $lto_no_fat" \
- {pr32846d.c} {} \
+ "Build pr32846d.o" \
+ "$plug_opt" "-fPIC -O2 -flto $lto_no_fat" \
+ {pr32846d.c} {} \
] \
[list \
- "Build pr32846e.o" \
- "$plug_opt" "-O2 -flto $lto_no_fat" \
- {pr32846e.c} {} \
+ "Build pr32846e.o" \
+ "$plug_opt" "-fPIC -O2 -flto $lto_no_fat" \
+ {pr32846e.c} {} \
] \
[list \
"Build pr32846" \
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 },