From: Jan Beulich Date: Fri, 24 Oct 2025 13:12:07 +0000 (+0200) Subject: bfd: section merging for PE/COFF images X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a04b91a64199ba87ff07efb3b07c3d1ebeb2e8cf;p=thirdparty%2Fbinutils-gdb.git bfd: section merging for PE/COFF images Leverage the generalized section merging to enable it also when linking PE/COFF images (from ELF objects). Sadly the previous hack in bfd_generic_get_relocated_section_contents() (from "bfd: generalize _bfd_elf_merge_sections()") is getting yet more bogus. --- diff --git a/bfd/coffgen.c b/bfd/coffgen.c index c1811cbce1c..071ca0d133c 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -1259,9 +1259,17 @@ coff_write_alien_symbol (bfd *abfd, } else { + asection *isec = symbol->section; + native->u.syment.n_scnum = output_section->target_index; - native->u.syment.n_value = (symbol->value - + symbol->section->output_offset); + native->u.syment.n_value = symbol->value; + + if (isec->sec_info_type == SEC_INFO_TYPE_MERGE + && !(symbol->flags & (BSF_SECTION_SYM | BSF_MERGE_RESOLVED))) + native->u.syment.n_value = + _bfd_merged_section_offset (abfd, &isec, symbol->value); + + native->u.syment.n_value += isec->output_offset; if (! obj_pe (abfd)) native->u.syment.n_value += output_section->vma; diff --git a/bfd/cofflink.c b/bfd/cofflink.c index 2ce5a0273ae..d1658ac1e89 100644 --- a/bfd/cofflink.c +++ b/bfd/cofflink.c @@ -2608,13 +2608,18 @@ _bfd_coff_write_global_sym (struct bfd_hash_entry *bh, void *data) { asection *sec; - sec = h->root.u.def.section->output_section; + sec = h->root.u.def.section; + isym.n_value = h->root.u.def.value; + if (sec->sec_info_type == SEC_INFO_TYPE_MERGE) + isym.n_value = + _bfd_merged_section_offset (output_bfd, &sec, isym.n_value); + isym.n_value += sec->output_offset; + + sec = sec->output_section; if (bfd_is_abs_section (sec)) isym.n_scnum = N_ABS; else isym.n_scnum = sec->target_index; - isym.n_value = (h->root.u.def.value - + h->root.u.def.section->output_offset); if (! obj_pe (flaginfo->output_bfd)) isym.n_value += sec->vma; #ifdef BFD64 diff --git a/bfd/merge.c b/bfd/merge.c index 0de35da5cf4..b25d55d8539 100644 --- a/bfd/merge.c +++ b/bfd/merge.c @@ -1090,7 +1090,7 @@ _bfd_write_merged_section (bfd *output_bfd, asection *sec) struct sec_merge_sec_info *secinfo = sec->sec_info; file_ptr pos; unsigned char *contents; - Elf_Internal_Shdr *hdr; + Elf_Internal_Shdr *hdr = NULL; if (!secinfo) return false; @@ -1099,8 +1099,9 @@ _bfd_write_merged_section (bfd *output_bfd, asection *sec) return true; /* FIXME: octets_per_byte. */ - hdr = &elf_section_data (sec->output_section)->this_hdr; - if (hdr->sh_offset == (file_ptr) -1) + if (bfd_get_flavour (output_bfd) == bfd_target_elf_flavour) + hdr = &elf_section_data (sec->output_section)->this_hdr; + if (hdr != NULL && hdr->sh_offset == (file_ptr) -1) { /* We must compress this section. Write output to the buffer. */ diff --git a/bfd/peicode.h b/bfd/peicode.h index 3a93e008799..8192bb9fa4b 100644 --- a/bfd/peicode.h +++ b/bfd/peicode.h @@ -82,6 +82,11 @@ static bool pe_bfd_copy_private_bfd_data (bfd *, bfd *); #define coff_mkobject_hook pe_mkobject_hook #ifdef COFF_IMAGE_WITH_PE + +/* For the case of linking ELF objects into a PE binary. */ +#undef TARGET_MERGE_SECTIONS +#define TARGET_MERGE_SECTIONS true + /* This structure contains static variables used by the ILF code. */ typedef asection * asection_ptr;