diff options
| -rw-r--r-- | gcc/ChangeLog | 44 | ||||
| -rw-r--r-- | gcc/DATESTAMP | 2 | ||||
| -rw-r--r-- | gcc/ada/ChangeLog | 7 | ||||
| -rw-r--r-- | gcc/c-family/ChangeLog | 6 | ||||
| -rw-r--r-- | gcc/config.gcc | 18 | ||||
| -rw-r--r-- | gcc/config/loongarch/loongarch-opts.cc | 2 | ||||
| -rw-r--r-- | gcc/cp/ChangeLog | 38 | ||||
| -rw-r--r-- | gcc/doc/install.texi | 2 | ||||
| -rw-r--r-- | gcc/doc/invoke.texi | 3 | ||||
| -rw-r--r-- | gcc/fortran/ChangeLog | 22 | ||||
| -rw-r--r-- | gcc/testsuite/ChangeLog | 42 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.target/loongarch/vect-frint-no-inexact.c | 2 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.target/loongarch/vect-frint-scalar-no-inexact.c | 2 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.target/loongarch/vect-frint-scalar.c | 2 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.target/loongarch/vect-frint.c | 2 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.target/loongarch/vect-ftint-no-inexact.c | 2 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.target/loongarch/vect-ftint.c | 2 | ||||
| -rw-r--r-- | libgomp/ChangeLog | 5 | ||||
| -rw-r--r-- | libiberty/simple-object-coff.c | 459 |
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; } |
