aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog44
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog7
-rw-r--r--gcc/c-family/ChangeLog6
-rw-r--r--gcc/config.gcc18
-rw-r--r--gcc/config/loongarch/loongarch-opts.cc2
-rw-r--r--gcc/cp/ChangeLog38
-rw-r--r--gcc/doc/install.texi2
-rw-r--r--gcc/doc/invoke.texi3
-rw-r--r--gcc/fortran/ChangeLog22
-rw-r--r--gcc/testsuite/ChangeLog42
-rw-r--r--gcc/testsuite/gcc.target/loongarch/vect-frint-no-inexact.c2
-rw-r--r--gcc/testsuite/gcc.target/loongarch/vect-frint-scalar-no-inexact.c2
-rw-r--r--gcc/testsuite/gcc.target/loongarch/vect-frint-scalar.c2
-rw-r--r--gcc/testsuite/gcc.target/loongarch/vect-frint.c2
-rw-r--r--gcc/testsuite/gcc.target/loongarch/vect-ftint-no-inexact.c2
-rw-r--r--gcc/testsuite/gcc.target/loongarch/vect-ftint.c2
-rw-r--r--libgomp/ChangeLog5
-rw-r--r--libiberty/simple-object-coff.c459
19 files changed, 571 insertions, 91 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index afd76cc..073dd35 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,47 @@
+2025-11-05 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/121574
+ * doc/invoke.texi: Document '-Wexpose-global-module-tu-local'.
+
+2025-11-05 Artemiy Volkov <artemiy.volkov@arm.com>
+
+ * tree-ssa-forwprop.cc (simplify_vector_constructor): Support
+ vector constructor elements.
+ * tree-vect-generic.cc (ssa_uniform_vector_p): Make non-static and
+ move ...
+ * tree.cc (ssa_uniform_vector_p): ... here.
+ * tree.h (ssa_uniform_vector_p): Declare it.
+
+2025-11-05 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-forwprop.cc (forward_propagate_addr_expr):
+ Use gather_imm_use_stmts instead of FOR_EACH_IMM_USE_STMT.
+
+2025-11-05 Richard Biener <rguenther@suse.de>
+
+ * gimple.h (gimple::pad): Rename to ...
+ (gimple::ilf): ... this.
+ * ssa-iterators.h (gather_imm_use_stmts): Declare.
+ * tree-ssa-operands.cc (gather_imm_use_stmts): New function.
+
+2025-11-05 Richard Biener <rguenther@suse.de>
+
+ * gimple-ssa-isolate-paths.cc (check_loadstore): Set
+ the volatile flag on the stmt manually.
+ (find_implicit_erroneous_behavior): Move code transform
+ outside of FOR_EACH_IMM_USE_STMT iteration.
+
+2025-11-05 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-loop-niter.cc (dump_affine_iv): Use file, not
+ dump_file when printing.
+ (debug): New overload for affine_iv.
+
+2025-11-05 Xi Ruoyao <xry111@xry111.site>
+
+ * config/loongarch/loongarch.md (cntmap): Change to uppercase.
+ (popcount<GPR:mode>2): Modify to a post reload split.
+
2025-11-04 Uros Bizjak <ubizjak@gmail.com>
PR target/122390
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 7b0f631..02b442e 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20251105
+20251106
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 1232383..51f57e3 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,10 @@
+2025-11-05 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/35793
+ * sem_res.adb (Check_Discriminant_Use): In a constraint context,
+ check that the discriminant appears alone as a direct name in all
+ cases and give a consistent error message when it does not.
+
2025-11-04 Eric Botcazou <ebotcazou@adacore.com>
* sem_ch3.adb (Analyze_Subtype_Declaration) <Concurrent_Kind>:
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 985b018..423a1aa 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,9 @@
+2025-11-05 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/121574
+ * c.opt: New warning '-Wexpose-global-module-tu-local'.
+ * c.opt.urls: Regenerate.
+
2025-11-04 Alejandro Colomar <alx@kernel.org>
* c-warn.cc (warn_parms_array_mismatch): Fix typos in comment.
diff --git a/gcc/config.gcc b/gcc/config.gcc
index c678b80..b0fa43b 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -5118,7 +5118,7 @@ case "${target}" in
;;
loongarch*-*)
- supported_defaults="abi arch tune fpu simd multilib-default strict-align-lib tls"
+ supported_defaults="abi arch tune fpu simd multilib-default strict-align-lib tls cmodel"
# Local variables
unset \
@@ -5539,6 +5539,22 @@ case "${target}" in
# Remove the excessive appending comma.
loongarch_multilib_list_c=${loongarch_multilib_list_c%,}
loongarch_multilib_list_make=${loongarch_multilib_list_make%,}
+
+ # Handle --with-cmodel.
+ # Make sure --with-cmodel is valid. If it was not specified,
+ # use medium as the default value.
+ case "${with_cmodel}" in
+ "" | medium)
+ tm_defines="${tm_defines} TARGET_DEFAULT_CMODEL=CMODEL_MEDIUM"
+ ;;
+ normal)
+ tm_defines="${tm_defines} TARGET_DEFAULT_CMODEL=CMODEL_NORMAL"
+ ;;
+ *)
+ echo "invalid option for --with-cmodel: '${with_cmodel}', available values are 'medium' and 'normal'" 1>&2
+ exit 1
+ ;;
+ esac
;;
nds32*-*-*)
diff --git a/gcc/config/loongarch/loongarch-opts.cc b/gcc/config/loongarch/loongarch-opts.cc
index 6e72084..cacfe37 100644
--- a/gcc/config/loongarch/loongarch-opts.cc
+++ b/gcc/config/loongarch/loongarch-opts.cc
@@ -540,7 +540,7 @@ fallback:
/* 5. Target code model */
- t.cmodel = constrained.cmodel ? target->cmodel : CMODEL_NORMAL;
+ t.cmodel = constrained.cmodel ? target->cmodel : TARGET_DEFAULT_CMODEL;
switch (t.cmodel)
{
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 36c0b42..95b471d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,41 @@
+2025-11-05 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/121574
+ * cp-tree.h (instantiating_tu_local_entity): Declare.
+ * module.cc (is_tu_local_entity): Extract from depset::hash.
+ (is_tu_local_value): Likewise.
+ (has_tu_local_tmpl_arg): Likewise.
+ (depset::hash::is_tu_local_entity): Remove.
+ (depset::hash::has_tu_local_tmpl_arg): Remove.
+ (depset::hash::is_tu_local_value): Remove.
+ (instantiating_tu_local_entity): New function.
+ (depset::hash::add_binding_entity): No longer go through
+ depset::hash to check is_tu_local_entity.
+ * pt.cc (complain_about_tu_local_entity): Remove.
+ (tsubst): Use instantiating_tu_local_entity.
+ (tsubst_expr): Likewise.
+
+2025-11-05 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/121574
+ * module.cc (depset::disc_bits): Replace 'DB_REFS_TU_LOCAL_BIT'
+ and 'DB_EXPOSURE_BIT' with new four flags
+ 'DB_{REF,EXPOSE}_{GLOBAL,PURVIEW}_BIT'.
+ (depset::is_tu_local): Support checking either for only purview
+ TU-local entities or any entity described TU-local by standard.
+ (depset::refs_tu_local): Likewise.
+ (depset::is_exposure): Likewise.
+ (depset::hash::make_dependency): A constant initialized to a
+ TU-local variable is always considered a purview exposure.
+ (is_exposure_of_member_type): Adjust sanity checks to handle if
+ we ever relax requirements for TU-local types.
+ (depset::hash::add_dependency): Differentiate referencing
+ purview or GMF TU-local entities.
+ (depset::hash::diagnose_bad_internal_ref): New function.
+ (depset::hash::diagnose_template_names_tu_local): New function.
+ (depset::hash::finalize_dependencies): Handle new warnings that
+ might be needed for GMF TU-local entities.
+
2025-11-04 Nathaniel Shead <nathanieloshead@gmail.com>
PR c++/122253
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 50cefa1..d1068dc 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -1615,7 +1615,7 @@ Use little endian by default. Provide a multilib for big endian.
@item --with-cmodel=@var{cmodel}
Specify what code model to use by default.
-Currently only implemented for riscv*-*-*.
+Currently only implemented for loongarch*-*-* and riscv*-*-*.
@item --enable-threads
Specify that the target
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index e4a5952..07a21fd 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -28544,6 +28544,8 @@ be within 2GB addressing space.
@item medium
The text segment and data segment must be within 2GB addressing space.
+This is the default code model unless GCC has been configured with
+@option{--with-cmodel=} specifying a different default code model.
@item large (Not implemented yet)
@@ -28552,7 +28554,6 @@ This mode does not limit the size of the code segment and data segment.
The @option{-mcmodel=extreme} option is incompatible with @option{-fplt}
and/or @option{-mexplicit-relocs=none}.
@end table
-The default code model is @code{normal}.
@item -mexplicit-relocs=@var{style}
Set when to use assembler relocation operators when dealing with symbolic
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index bee1d2b..4547b43 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,25 @@
+2025-11-05 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/122566
+ * decl.cc (gfc_get_pdt_instance): Add non-PDT type exstention.
+
+2025-11-05 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/122501
+ PR fortran/122524
+ * primary.cc (gfc_convert_to_structure_constructor): Correct
+ whitespace issue.
+ (gfc_match_rvalue): Remove the attempt to match specific procs
+ before filling out PDT constructor. Instead, defer this until
+ resolution with the condition that there not be a following
+ arglist and more than one procedure in the generic interface.
+
+2025-11-05 Tobias Burnus <tburnus@baylibre.com>
+
+ PR fortran/122570
+ * openmp.cc (resolve_omp_metadirective): Fix 'skip' of
+ never matchable metadirective variants.
+
2025-11-04 Harald Anlauf <anlauf@gmx.de>
PR fortran/122564
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 25324e6..0800f10 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,45 @@
+2025-11-05 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/121574
+ * g++.dg/modules/internal-17_b.C: Check for diagnostics when
+ instantiating imported TU-local entities.
+
+2025-11-05 Nathaniel Shead <nathanieloshead@gmail.com>
+
+ PR c++/121574
+ * g++.dg/modules/internal-17_a.C: New test.
+ * g++.dg/modules/internal-17_b.C: New test.
+
+2025-11-05 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/specs/discr8.ads: New test.
+
+2025-11-05 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/122566
+ * gfortran.dg/pdt_68.f03: New test.
+
+2025-11-05 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/122501
+ PR fortran/122524
+ * gfortran.dg/pdt_66.f03: New test.
+ * gfortran.dg/pdt_67.f03: New test.
+
+2025-11-05 Tobias Burnus <tburnus@baylibre.com>
+
+ PR fortran/122570
+ * gfortran.dg/gomp/pr122570.f: New test.
+
+2025-11-05 Artemiy Volkov <artemiy.volkov@arm.com>
+
+ * gcc.dg/tree-ssa/forwprop-43.c: New test.
+ * gcc.target/aarch64/simd/combine_ext.c: New test.
+
+2025-11-05 Guo Jie <guojie@loongson.cn>
+
+ * gcc.target/loongarch/widen-mul-rtx-cost-signed.c: Update.
+
2025-11-04 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/protected_subtype1.adb: New test.
diff --git a/gcc/testsuite/gcc.target/loongarch/vect-frint-no-inexact.c b/gcc/testsuite/gcc.target/loongarch/vect-frint-no-inexact.c
index 7bbaf1f..e20eaea 100644
--- a/gcc/testsuite/gcc.target/loongarch/vect-frint-no-inexact.c
+++ b/gcc/testsuite/gcc.target/loongarch/vect-frint-no-inexact.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mabi=lp64d -mdouble-float -fno-math-errno -fno-fp-int-builtin-inexact -mlasx" } */
+/* { dg-options "-O2 -mabi=lp64d -mdouble-float -fno-math-errno -fno-fp-int-builtin-inexact -mlasx -mcmodel=normal" } */
#include "vect-frint.c"
diff --git a/gcc/testsuite/gcc.target/loongarch/vect-frint-scalar-no-inexact.c b/gcc/testsuite/gcc.target/loongarch/vect-frint-scalar-no-inexact.c
index 002e3b9..d5f09335 100644
--- a/gcc/testsuite/gcc.target/loongarch/vect-frint-scalar-no-inexact.c
+++ b/gcc/testsuite/gcc.target/loongarch/vect-frint-scalar-no-inexact.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mlsx -fno-fp-int-builtin-inexact" } */
+/* { dg-options "-O2 -mlsx -fno-fp-int-builtin-inexact -mcmodel=normal" } */
#include "vect-frint-scalar.c"
diff --git a/gcc/testsuite/gcc.target/loongarch/vect-frint-scalar.c b/gcc/testsuite/gcc.target/loongarch/vect-frint-scalar.c
index dbcb906..171ba98 100644
--- a/gcc/testsuite/gcc.target/loongarch/vect-frint-scalar.c
+++ b/gcc/testsuite/gcc.target/loongarch/vect-frint-scalar.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mlsx -ffp-int-builtin-inexact" } */
+/* { dg-options "-O2 -mlsx -ffp-int-builtin-inexact -mcmodel=normal" } */
#define test(func, suffix) \
__typeof__ (1.##suffix) \
diff --git a/gcc/testsuite/gcc.target/loongarch/vect-frint.c b/gcc/testsuite/gcc.target/loongarch/vect-frint.c
index 6bf211e..bda041b 100644
--- a/gcc/testsuite/gcc.target/loongarch/vect-frint.c
+++ b/gcc/testsuite/gcc.target/loongarch/vect-frint.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mabi=lp64d -mdouble-float -fno-math-errno -ffp-int-builtin-inexact -mlasx" } */
+/* { dg-options "-O2 -mabi=lp64d -mdouble-float -fno-math-errno -ffp-int-builtin-inexact -mlasx -mcmodel=normal" } */
float out_x[8];
double out_y[4];
diff --git a/gcc/testsuite/gcc.target/loongarch/vect-ftint-no-inexact.c b/gcc/testsuite/gcc.target/loongarch/vect-ftint-no-inexact.c
index 61918be..3fa9753 100644
--- a/gcc/testsuite/gcc.target/loongarch/vect-ftint-no-inexact.c
+++ b/gcc/testsuite/gcc.target/loongarch/vect-ftint-no-inexact.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mabi=lp64d -mdouble-float -fno-math-errno -fno-fp-int-builtin-inexact -mlasx" } */
+/* { dg-options "-O2 -mabi=lp64d -mdouble-float -fno-math-errno -fno-fp-int-builtin-inexact -mlasx -mcmodel=normal" } */
#include "vect-ftint.c"
diff --git a/gcc/testsuite/gcc.target/loongarch/vect-ftint.c b/gcc/testsuite/gcc.target/loongarch/vect-ftint.c
index c4962ed..96da3cd 100644
--- a/gcc/testsuite/gcc.target/loongarch/vect-ftint.c
+++ b/gcc/testsuite/gcc.target/loongarch/vect-ftint.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -mabi=lp64d -mdouble-float -fno-math-errno -ffp-int-builtin-inexact -mlasx" } */
+/* { dg-options "-O2 -mabi=lp64d -mdouble-float -fno-math-errno -ffp-int-builtin-inexact -mlasx -mcmodel=normal" } */
int out_x[8];
long out_y[4];
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index e2e14eb..468539a 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,8 @@
+2025-11-05 Tobias Burnus <tburnus@baylibre.com>
+
+ * testsuite/libgomp.c++/target-std__multimap-concurrent.C: Fix memory
+ freeing of device allocated memory with USM.
+
2025-11-03 Sam James <sam@gentoo.org>
* configure: Regenerate.
diff --git a/libiberty/simple-object-coff.c b/libiberty/simple-object-coff.c
index 922477f..7f3b462 100644
--- a/libiberty/simple-object-coff.c
+++ b/libiberty/simple-object-coff.c
@@ -57,6 +57,32 @@ struct external_filehdr
unsigned char f_flags[2]; /* flags */
};
+/* BigObj COFF file header. */
+
+struct external_filehdr_bigobj
+{
+ unsigned char sig1[2]; /* Must be 0x0000 */
+ unsigned char sig2[2]; /* Must be 0xFFFF */
+ unsigned char version[2]; /* Version, currently 2 */
+ unsigned char machine[2]; /* Machine type */
+ unsigned char timdat[4]; /* time & date stamp */
+ unsigned char classid[16]; /* Magic GUID that identifies BigObj format */
+ unsigned char sizeofdata[4]; /* Size of data (unused, set to 0) */
+ unsigned char flags[4]; /* Flags (unused, set to 0) */
+ unsigned char metadatasize[4]; /* Metadata size (unused, set to 0) */
+ unsigned char metadataoffset[4]; /* Metadata offset (unused, set to 0) */
+ unsigned char nscns[4]; /* number of sections (32-bit!) */
+ unsigned char symptr[4]; /* file pointer to symtab */
+ unsigned char nsyms[4]; /* number of symtab entries */
+};
+
+/* The BigObj magic GUID (ClassID). */
+static const unsigned char bigobj_magic[16] =
+{
+ 0xC7, 0xA1, 0xBA, 0xD1, 0xEE, 0xBA, 0xA9, 0x4B,
+ 0xAF, 0x20, 0xFA, 0xF6, 0x6A, 0xA4, 0xDC, 0xB8
+};
+
/* Bits for filehdr f_flags field. */
#define F_EXEC (0x0002)
@@ -119,6 +145,28 @@ struct external_syment
unsigned char e_numaux[1];
};
+/* BigObj COFF symbol table entry (20 bytes instead of 18). */
+
+struct external_syment_bigobj
+{
+ union
+ {
+ unsigned char e_name[E_SYMNMLEN];
+
+ struct
+ {
+ unsigned char e_zeroes[4];
+ unsigned char e_offset[4];
+ } e;
+ } e;
+
+ unsigned char e_value[4];
+ unsigned char e_scnum[4]; /* 32-bit section number! */
+ unsigned char e_type[2];
+ unsigned char e_sclass[1];
+ unsigned char e_numaux[1];
+};
+
/* Length allowed for filename in aux sym format 4. */
#define E_FILNMLEN 18
@@ -149,6 +197,33 @@ union external_auxent
} x_scn;
};
+/* BigObj auxiliary symbol (20 bytes to match symbol size). */
+
+union external_auxent_bigobj
+{
+ /* Aux sym format 4: file. */
+ union
+ {
+ char x_fname[E_FILNMLEN];
+ struct
+ {
+ unsigned char x_zeroes[4];
+ unsigned char x_offset[4];
+ } x_n;
+ } x_file;
+ /* Aux sym format 5: section. */
+ struct
+ {
+ unsigned char x_scnlen[4]; /* section length */
+ unsigned char x_nreloc[2]; /* # relocation entries */
+ unsigned char x_nlinno[2]; /* # line numbers */
+ unsigned char x_checksum[4]; /* section COMDAT checksum */
+ unsigned char x_associated[2]; /* COMDAT assoc section index */
+ unsigned char x_comdat[1]; /* COMDAT selection number */
+ unsigned char x_pad[3]; /* Padding to 20 bytes */
+ } x_scn;
+};
+
/* Symbol-related constants. */
#define IMAGE_SYM_DEBUG (-2)
@@ -168,8 +243,10 @@ struct simple_object_coff_read
unsigned short magic;
/* Whether the file is big-endian. */
unsigned char is_big_endian;
+ /* Whether this is BigObj format. */
+ unsigned char is_bigobj;
/* Number of sections. */
- unsigned short nscns;
+ unsigned int nscns;
/* File offset of symbol table. */
off_t symptr;
/* Number of symbol table entries. */
@@ -188,6 +265,8 @@ struct simple_object_coff_attributes
unsigned short magic;
/* Whether the file is big-endian. */
unsigned char is_big_endian;
+ /* Whether this is BigObj format. */
+ unsigned char is_bigobj;
/* Flags. */
unsigned short flags;
};
@@ -240,10 +319,12 @@ simple_object_coff_match (unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN],
int is_big_endian;
unsigned short (*fetch_16) (const unsigned char *);
unsigned int (*fetch_32) (const unsigned char *);
- unsigned char hdrbuf[sizeof (struct external_filehdr)];
+ unsigned char hdrbuf[sizeof (struct external_filehdr_bigobj)];
unsigned short flags;
struct simple_object_coff_read *ocr;
+ unsigned short sig1, sig2;
+ /* Try regular COFF first. */
c = sizeof (coff_magic) / sizeof (coff_magic[0]);
magic_big = simple_object_fetch_big_16 (header);
magic_little = simple_object_fetch_little_16 (header);
@@ -254,12 +335,64 @@ simple_object_coff_match (unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN],
: coff_magic[i].magic == magic_little)
break;
}
- if (i >= c)
+
+ /* Check for BigObj if regular COFF didn't match. */
+ sig1 = simple_object_fetch_little_16 (header);
+ sig2 = simple_object_fetch_little_16 (header + 2);
+
+ if (i >= c && (sig1 != 0 || sig2 != 0xFFFF))
{
+ /* Not regular COFF and not BigObj. */
*errmsg = NULL;
*err = 0;
return NULL;
}
+
+ if (sig1 == 0 && sig2 == 0xFFFF)
+ {
+ /* This looks like BigObj. Verify the ClassID. */
+ unsigned char bigobj_hdrbuf[sizeof (struct external_filehdr_bigobj)];
+
+ if (!simple_object_internal_read (descriptor, offset, bigobj_hdrbuf,
+ sizeof bigobj_hdrbuf, errmsg, err))
+ return NULL;
+
+ if (memcmp (bigobj_hdrbuf + offsetof (struct external_filehdr_bigobj,
+ classid),
+ bigobj_magic, 16) != 0)
+ {
+ *errmsg = NULL;
+ *err = 0;
+ return NULL;
+ }
+
+ /* BigObj is always little-endian. */
+ is_big_endian = 0;
+
+ ocr = XNEW (struct simple_object_coff_read);
+ ocr->magic = simple_object_fetch_little_16
+ (bigobj_hdrbuf
+ + offsetof (struct external_filehdr_bigobj, machine));
+ ocr->is_big_endian = 0;
+ ocr->is_bigobj = 1;
+ ocr->nscns = simple_object_fetch_little_32
+ (bigobj_hdrbuf
+ + offsetof (struct external_filehdr_bigobj, nscns));
+ ocr->symptr = simple_object_fetch_little_32
+ (bigobj_hdrbuf
+ + offsetof (struct external_filehdr_bigobj, symptr));
+ ocr->nsyms = simple_object_fetch_little_32
+ (bigobj_hdrbuf
+ + offsetof (struct external_filehdr_bigobj, nsyms));
+ ocr->flags = simple_object_fetch_little_32
+ (bigobj_hdrbuf
+ + offsetof (struct external_filehdr_bigobj, flags));
+ ocr->scnhdr_offset = sizeof (struct external_filehdr_bigobj);
+
+ return (void *) ocr;
+ }
+
+ /* Regular COFF. */
is_big_endian = coff_magic[i].is_big_endian;
magic = is_big_endian ? magic_big : magic_little;
@@ -270,7 +403,7 @@ simple_object_coff_match (unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN],
? simple_object_fetch_big_32
: simple_object_fetch_little_32);
- if (!simple_object_internal_read (descriptor, offset, hdrbuf, sizeof hdrbuf,
+ if (!simple_object_internal_read (descriptor, offset, hdrbuf, sizeof (struct external_filehdr),
errmsg, err))
return NULL;
@@ -285,6 +418,7 @@ simple_object_coff_match (unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN],
ocr = XNEW (struct simple_object_coff_read);
ocr->magic = magic;
ocr->is_big_endian = is_big_endian;
+ ocr->is_bigobj = 0;
ocr->nscns = fetch_16 (hdrbuf + offsetof (struct external_filehdr, f_nscns));
ocr->symptr = fetch_32 (hdrbuf
+ offsetof (struct external_filehdr, f_symptr));
@@ -309,9 +443,13 @@ simple_object_coff_read_strtab (simple_object_read *sobj, size_t *strtab_size,
unsigned char strsizebuf[4];
size_t strsize;
char *strtab;
+ size_t sym_size;
+
+ /* Symbol size depends on format. */
+ sym_size = ocr->is_bigobj ? sizeof (struct external_syment_bigobj)
+ : sizeof (struct external_syment);
- strtab_offset = sobj->offset + ocr->symptr
- + ocr->nsyms * sizeof (struct external_syment);
+ strtab_offset = sobj->offset + ocr->symptr + ocr->nsyms * sym_size;
if (!simple_object_internal_read (sobj->descriptor, strtab_offset,
strsizebuf, 4, errmsg, err))
return NULL;
@@ -444,6 +582,7 @@ simple_object_coff_fetch_attributes (simple_object_read *sobj,
ret = XNEW (struct simple_object_coff_attributes);
ret->magic = ocr->magic;
ret->is_big_endian = ocr->is_big_endian;
+ ret->is_bigobj = ocr->is_bigobj;
ret->flags = ocr->flags;
return ret;
}
@@ -466,7 +605,9 @@ simple_object_coff_attributes_merge (void *todata, void *fromdata, int *err)
struct simple_object_coff_attributes *from =
(struct simple_object_coff_attributes *) fromdata;
- if (to->magic != from->magic || to->is_big_endian != from->is_big_endian)
+ if (to->magic != from->magic
+ || to->is_big_endian != from->is_big_endian
+ || to->is_bigobj != from->is_bigobj)
{
*err = 0;
return "COFF object format mismatch";
@@ -500,6 +641,52 @@ simple_object_coff_start_write (void *attributes_data,
return ret;
}
+/* Write out a BigObj COFF filehdr. */
+
+static int
+simple_object_coff_write_filehdr_bigobj (simple_object_write *sobj,
+ int descriptor,
+ unsigned int nscns,
+ size_t symtab_offset,
+ unsigned int nsyms,
+ const char **errmsg, int *err)
+{
+ struct simple_object_coff_attributes *attrs =
+ (struct simple_object_coff_attributes *) sobj->data;
+ unsigned char hdrbuf[sizeof (struct external_filehdr_bigobj)];
+ unsigned char *hdr;
+ void (*set_16) (unsigned char *, unsigned short);
+ void (*set_32) (unsigned char *, unsigned int);
+
+ hdr = &hdrbuf[0];
+
+ /* BigObj is always little-endian. */
+ set_16 = simple_object_set_little_16;
+ set_32 = simple_object_set_little_32;
+
+ memset (hdr, 0, sizeof (struct external_filehdr_bigobj));
+
+ /* Set BigObj signatures. */
+ set_16 (hdr + offsetof (struct external_filehdr_bigobj, sig1), 0);
+ set_16 (hdr + offsetof (struct external_filehdr_bigobj, sig2), 0xFFFF);
+ set_16 (hdr + offsetof (struct external_filehdr_bigobj, version), 2);
+ set_16 (hdr + offsetof (struct external_filehdr_bigobj, machine),
+ attrs->magic);
+ /* timdat left as zero. */
+ /* Copy ClassID. */
+ memcpy (hdr + offsetof (struct external_filehdr_bigobj, classid),
+ bigobj_magic, 16);
+ /* sizeofdata, flags, metadatasize, metadataoffset left as zero. */
+ set_32 (hdr + offsetof (struct external_filehdr_bigobj, nscns), nscns);
+ set_32 (hdr + offsetof (struct external_filehdr_bigobj, symptr),
+ symtab_offset);
+ set_32 (hdr + offsetof (struct external_filehdr_bigobj, nsyms), nsyms);
+
+ return simple_object_internal_write (descriptor, 0, hdrbuf,
+ sizeof (struct external_filehdr_bigobj),
+ errmsg, err);
+}
+
/* Write out a COFF filehdr. */
static int
@@ -618,14 +805,16 @@ simple_object_coff_write_to_file (simple_object_write *sobj, int descriptor,
what 'gas' uses when told to assemble from stdin. */
const char *source_filename = "fake";
size_t sflen;
- union
- {
- struct external_syment sym;
- union external_auxent aux;
- } syms[2];
+ size_t symsize;
void (*set_16) (unsigned char *, unsigned short);
void (*set_32) (unsigned char *, unsigned int);
+ /* Determine symbol size based on format. */
+ if (attrs->is_bigobj)
+ symsize = sizeof (struct external_syment_bigobj);
+ else
+ symsize = sizeof (struct external_syment);
+
set_16 = (attrs->is_big_endian
? simple_object_set_big_16
: simple_object_set_little_16);
@@ -637,7 +826,10 @@ simple_object_coff_write_to_file (simple_object_write *sobj, int descriptor,
for (section = sobj->sections; section != NULL; section = section->next)
++nscns;
- scnhdr_offset = sizeof (struct external_filehdr);
+ if (attrs->is_bigobj)
+ scnhdr_offset = sizeof (struct external_filehdr_bigobj);
+ else
+ scnhdr_offset = sizeof (struct external_filehdr);
offset = scnhdr_offset + nscns * sizeof (struct external_scnhdr);
name_offset = 4;
for (section = sobj->sections; section != NULL; section = section->next)
@@ -693,91 +885,198 @@ simple_object_coff_write_to_file (simple_object_write *sobj, int descriptor,
symtab_offset = offset;
/* Advance across space reserved for symbol table to locate
start of string table. */
- offset += nsyms * sizeof (struct external_syment);
+ offset += nsyms * symsize;
/* Write out file symbol. */
- memset (&syms[0], 0, sizeof (syms));
- strcpy ((char *)&syms[0].sym.e.e_name[0], ".file");
- set_16 (&syms[0].sym.e_scnum[0], IMAGE_SYM_DEBUG);
- set_16 (&syms[0].sym.e_type[0], IMAGE_SYM_TYPE);
- syms[0].sym.e_sclass[0] = IMAGE_SYM_CLASS_FILE;
- syms[0].sym.e_numaux[0] = 1;
- /* The name need not be nul-terminated if it fits into the x_fname field
- directly, but must be if it has to be placed into the string table. */
- sflen = strlen (source_filename);
- if (sflen <= E_FILNMLEN)
- memcpy (&syms[1].aux.x_file.x_fname[0], source_filename, sflen);
- else
+ if (attrs->is_bigobj)
{
- set_32 (&syms[1].aux.x_file.x_n.x_offset[0], name_offset);
- if (!simple_object_internal_write (descriptor, offset + name_offset,
- ((const unsigned char *)
- source_filename),
- sflen + 1, &errmsg, err))
+ union
+ {
+ struct external_syment_bigobj sym;
+ union external_auxent_bigobj aux;
+ } syms[2];
+
+ memset (&syms[0], 0, sizeof (syms));
+ strcpy ((char *)&syms[0].sym.e.e_name[0], ".file");
+ set_32 (&syms[0].sym.e_scnum[0], IMAGE_SYM_DEBUG);
+ set_16 (&syms[0].sym.e_type[0], IMAGE_SYM_TYPE);
+ syms[0].sym.e_sclass[0] = IMAGE_SYM_CLASS_FILE;
+ syms[0].sym.e_numaux[0] = 1;
+ /* The name need not be nul-terminated if it fits into the x_fname field
+ directly, but must be if it has to be placed into the string table. */
+ sflen = strlen (source_filename);
+ if (sflen <= E_FILNMLEN)
+ memcpy (&syms[1].aux.x_file.x_fname[0], source_filename, sflen);
+ else
+ {
+ set_32 (&syms[1].aux.x_file.x_n.x_offset[0], name_offset);
+ if (!simple_object_internal_write (descriptor, offset + name_offset,
+ ((const unsigned char *)
+ source_filename),
+ sflen + 1, &errmsg, err))
+ return errmsg;
+ name_offset += strlen (source_filename) + 1;
+ }
+ if (!simple_object_internal_write (descriptor, symtab_offset,
+ (const unsigned char *) &syms[0],
+ sizeof (syms), &errmsg, err))
return errmsg;
- name_offset += strlen (source_filename) + 1;
- }
- if (!simple_object_internal_write (descriptor, symtab_offset,
- (const unsigned char *) &syms[0],
- sizeof (syms), &errmsg, err))
- return errmsg;
-
- /* Write the string table length, followed by the strings and section
- symbols in step with each other. */
- set_32 (strsizebuf, name_offset);
- if (!simple_object_internal_write (descriptor, offset, strsizebuf, 4,
- &errmsg, err))
- return errmsg;
- name_offset = 4;
- secsym_offset = symtab_offset + sizeof (syms);
- memset (&syms[0], 0, sizeof (syms));
- set_16 (&syms[0].sym.e_type[0], IMAGE_SYM_TYPE);
- syms[0].sym.e_sclass[0] = IMAGE_SYM_CLASS_STATIC;
- syms[0].sym.e_numaux[0] = 1;
- secnum = 1;
+ /* Write the string table length, followed by the strings and section
+ symbols in step with each other. */
+ set_32 (strsizebuf, name_offset);
+ if (!simple_object_internal_write (descriptor, offset, strsizebuf, 4,
+ &errmsg, err))
+ return errmsg;
- for (section = sobj->sections; section != NULL; section = section->next)
- {
- size_t namelen;
- size_t scnsize;
- struct simple_object_write_section_buffer *buffer;
+ name_offset = 4;
+ secsym_offset = symtab_offset + sizeof (syms);
+ memset (&syms[0], 0, sizeof (syms));
+ set_16 (&syms[0].sym.e_type[0], IMAGE_SYM_TYPE);
+ syms[0].sym.e_sclass[0] = IMAGE_SYM_CLASS_STATIC;
+ syms[0].sym.e_numaux[0] = 1;
+ secnum = 1;
- namelen = strlen (section->name);
- set_16 (&syms[0].sym.e_scnum[0], secnum++);
- scnsize = 0;
- for (buffer = section->buffers; buffer != NULL; buffer = buffer->next)
- scnsize += buffer->size;
- set_32 (&syms[1].aux.x_scn.x_scnlen[0], scnsize);
- if (namelen > SCNNMLEN)
+ for (section = sobj->sections; section != NULL; section = section->next)
{
- set_32 (&syms[0].sym.e.e.e_zeroes[0], 0);
- set_32 (&syms[0].sym.e.e.e_offset[0], name_offset);
- if (!simple_object_internal_write (descriptor, offset + name_offset,
- ((const unsigned char *)
- section->name),
- namelen + 1, &errmsg, err))
+ size_t namelen;
+ size_t scnsize;
+ struct simple_object_write_section_buffer *buffer;
+
+ namelen = strlen (section->name);
+ set_32 (&syms[0].sym.e_scnum[0], secnum++);
+ scnsize = 0;
+ for (buffer = section->buffers; buffer != NULL; buffer = buffer->next)
+ scnsize += buffer->size;
+ set_32 (&syms[1].aux.x_scn.x_scnlen[0], scnsize);
+ if (namelen > SCNNMLEN)
+ {
+ set_32 (&syms[0].sym.e.e.e_zeroes[0], 0);
+ set_32 (&syms[0].sym.e.e.e_offset[0], name_offset);
+ if (!simple_object_internal_write (descriptor, offset + name_offset,
+ ((const unsigned char *)
+ section->name),
+ namelen + 1, &errmsg, err))
+ return errmsg;
+ name_offset += namelen + 1;
+ }
+ else
+ {
+ memcpy (&syms[0].sym.e.e_name[0], section->name,
+ strlen (section->name));
+ memset (&syms[0].sym.e.e_name[strlen (section->name)], 0,
+ E_SYMNMLEN - strlen (section->name));
+ }
+
+ if (!simple_object_internal_write (descriptor, secsym_offset,
+ (const unsigned char *) &syms[0],
+ sizeof (syms), &errmsg, err))
return errmsg;
- name_offset += namelen + 1;
+ secsym_offset += sizeof (syms);
}
+ }
+ else
+ {
+ /* Regular COFF. */
+ union
+ {
+ struct external_syment sym;
+ union external_auxent aux;
+ } syms[2];
+
+ memset (&syms[0], 0, sizeof (syms));
+ strcpy ((char *)&syms[0].sym.e.e_name[0], ".file");
+ set_16 (&syms[0].sym.e_scnum[0], IMAGE_SYM_DEBUG);
+ set_16 (&syms[0].sym.e_type[0], IMAGE_SYM_TYPE);
+ syms[0].sym.e_sclass[0] = IMAGE_SYM_CLASS_FILE;
+ syms[0].sym.e_numaux[0] = 1;
+ /* The name need not be nul-terminated if it fits into the x_fname field
+ directly, but must be if it has to be placed into the string table. */
+ sflen = strlen (source_filename);
+ if (sflen <= E_FILNMLEN)
+ memcpy (&syms[1].aux.x_file.x_fname[0], source_filename, sflen);
else
{
- memcpy (&syms[0].sym.e.e_name[0], section->name,
- strlen (section->name));
- memset (&syms[0].sym.e.e_name[strlen (section->name)], 0,
- E_SYMNMLEN - strlen (section->name));
+ set_32 (&syms[1].aux.x_file.x_n.x_offset[0], name_offset);
+ if (!simple_object_internal_write (descriptor, offset + name_offset,
+ ((const unsigned char *)
+ source_filename),
+ sflen + 1, &errmsg, err))
+ return errmsg;
+ name_offset += strlen (source_filename) + 1;
}
-
- if (!simple_object_internal_write (descriptor, secsym_offset,
+ if (!simple_object_internal_write (descriptor, symtab_offset,
(const unsigned char *) &syms[0],
sizeof (syms), &errmsg, err))
return errmsg;
- secsym_offset += sizeof (syms);
+
+ /* Write the string table length, followed by the strings and section
+ symbols in step with each other. */
+ set_32 (strsizebuf, name_offset);
+ if (!simple_object_internal_write (descriptor, offset, strsizebuf, 4,
+ &errmsg, err))
+ return errmsg;
+
+ name_offset = 4;
+ secsym_offset = symtab_offset + sizeof (syms);
+ memset (&syms[0], 0, sizeof (syms));
+ set_16 (&syms[0].sym.e_type[0], IMAGE_SYM_TYPE);
+ syms[0].sym.e_sclass[0] = IMAGE_SYM_CLASS_STATIC;
+ syms[0].sym.e_numaux[0] = 1;
+ secnum = 1;
+
+ for (section = sobj->sections; section != NULL; section = section->next)
+ {
+ size_t namelen;
+ size_t scnsize;
+ struct simple_object_write_section_buffer *buffer;
+
+ namelen = strlen (section->name);
+ set_16 (&syms[0].sym.e_scnum[0], secnum++);
+ scnsize = 0;
+ for (buffer = section->buffers; buffer != NULL; buffer = buffer->next)
+ scnsize += buffer->size;
+ set_32 (&syms[1].aux.x_scn.x_scnlen[0], scnsize);
+ if (namelen > SCNNMLEN)
+ {
+ set_32 (&syms[0].sym.e.e.e_zeroes[0], 0);
+ set_32 (&syms[0].sym.e.e.e_offset[0], name_offset);
+ if (!simple_object_internal_write (descriptor, offset + name_offset,
+ ((const unsigned char *)
+ section->name),
+ namelen + 1, &errmsg, err))
+ return errmsg;
+ name_offset += namelen + 1;
+ }
+ else
+ {
+ memcpy (&syms[0].sym.e.e_name[0], section->name,
+ strlen (section->name));
+ memset (&syms[0].sym.e.e_name[strlen (section->name)], 0,
+ E_SYMNMLEN - strlen (section->name));
+ }
+
+ if (!simple_object_internal_write (descriptor, secsym_offset,
+ (const unsigned char *) &syms[0],
+ sizeof (syms), &errmsg, err))
+ return errmsg;
+ secsym_offset += sizeof (syms);
+ }
}
- if (!simple_object_coff_write_filehdr (sobj, descriptor, nscns,
- symtab_offset, nsyms, &errmsg, err))
- return errmsg;
+ if (attrs->is_bigobj)
+ {
+ if (!simple_object_coff_write_filehdr_bigobj (sobj, descriptor, nscns,
+ symtab_offset, nsyms,
+ &errmsg, err))
+ return errmsg;
+ }
+ else
+ {
+ if (!simple_object_coff_write_filehdr (sobj, descriptor, nscns,
+ symtab_offset, nsyms, &errmsg, err))
+ return errmsg;
+ }
return NULL;
}