public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: "H.J. Lu" <hjl.tools@gmail.com>
To: Alan Modra <amodra@gmail.com>
Cc: Binutils <binutils@sourceware.org>
Subject: [PATCH] bfd: Avoid signed overflow for new_size adjustment
Date: Tue, 6 Dec 2022 13:01:42 -0800	[thread overview]
Message-ID: <CAMe9rOqXffjJHb0Rm=jgdGThruJ1o+CpxsRhq9h1J6jEsFrMzA@mail.gmail.com> (raw)
In-Reply-To: <Y47NPN4wWWRZyL00@squeak.grove.modra.org>

[-- Attachment #1: Type: text/plain, Size: 6314 bytes --]

On Mon, Dec 5, 2022 at 9:04 PM Alan Modra via Binutils
<binutils@sourceware.org> wrote:
>
> SEC_ELF_RENAME is a flag used to effect section name changes when
> compressing/decompressing zlib-gnu debug sections.  This can be
> accomplished more directly in one of the objcopy specific bfd
> functions.  Renaming for ld input is simplified too.  Ld input object
> files always have BFD_DECOMPRESS set.
>
> bfd/
>         * compress.c (bfd_convert_section_size): Rename to..
>         (bfd_convert_section_setup): ..this.  Handle objcopy renaming
>         of compressed/decompressed debug sections.
>         * elf.c (_bfd_elf_make_section_from_shdr): Only rename zdebug
>         input for linker.
>         (elf_fake_sections): Don't handle renaming of debug sections for
>         objcopy here.
>         * section.c (SEC_ELF_RENAME): Delete.
>         * bfd-in2.h: Regenerate.
> binutils/
>         * objcopy.c (setup_section): Call bfd_convert_section_setup.
>         Don't call bfd_convert_section_size.
>
> diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
> index 24f9305c47c..d983268563d 100644
> --- a/bfd/bfd-in2.h
> +++ b/bfd/bfd-in2.h
> @@ -932,10 +932,6 @@ typedef struct bfd_section
>       TMS320C54X only.  */
>  #define SEC_TIC54X_BLOCK           0x10000000
>
> -  /* This section should be renamed.  This is for ELF linker
> -     internal use only.  */
> -#define SEC_ELF_RENAME             0x10000000
> -
>    /* Conditionally link this section; do not link if there are no
>       references found to any symbol in the section.  This is for TI
>       TMS320C54X only.  */
> @@ -7982,8 +7978,9 @@ void bfd_update_compression_header
>
>  int bfd_get_compression_header_size (bfd *abfd, asection *sec);
>
> -bfd_size_type bfd_convert_section_size
> -   (bfd *ibfd, asection *isec, bfd *obfd, bfd_size_type size);
> +bool bfd_convert_section_setup
> +   (bfd *ibfd, asection *isec, bfd *obfd,
> +    const char **new_name, bfd_size_type *new_size);
>
>  bool bfd_convert_section_contents
>     (bfd *ibfd, asection *isec, bfd *obfd,
> diff --git a/bfd/compress.c b/bfd/compress.c
> index a4e6a8ee7b5..bb55a6ec0ac 100644
> --- a/bfd/compress.c
> +++ b/bfd/compress.c
> @@ -225,53 +225,89 @@ bfd_get_compression_header_size (bfd *abfd, asection *sec)
>
>  /*
>  FUNCTION
> -       bfd_convert_section_size
> +       bfd_convert_section_setup
>
>  SYNOPSIS
> -       bfd_size_type bfd_convert_section_size
> -         (bfd *ibfd, asection *isec, bfd *obfd, bfd_size_type size);
> +       bool bfd_convert_section_setup
> +         (bfd *ibfd, asection *isec, bfd *obfd,
> +          const char **new_name, bfd_size_type *new_size);
>
>  DESCRIPTION
> -       Convert the size @var{size} of the section @var{isec} in input
> -       BFD @var{ibfd} to the section size in output BFD @var{obfd}.
> +       Do early setup for objcopy, when copying @var{isec} in input
> +       BFD @var{ibfd} to output BFD @var{obfd}.  Returns the name and
> +       size of the output section.
>  */
>
> -bfd_size_type
> -bfd_convert_section_size (bfd *ibfd, sec_ptr isec, bfd *obfd,
> -                         bfd_size_type size)
> +bool
> +bfd_convert_section_setup (bfd *ibfd, asection *isec, bfd *obfd,
> +                          const char **new_name, bfd_size_type *new_size)
>  {
>    bfd_size_type hdr_size;
>
> +  if ((isec->flags & SEC_DEBUGGING) != 0
> +      && (isec->flags & SEC_HAS_CONTENTS) != 0)
> +    {
> +      const char *name = *new_name;
> +
> +      if ((ibfd->flags & (BFD_DECOMPRESS | BFD_COMPRESS_GABI)) != 0)
> +       {
> +         /* When we decompress or compress with SHF_COMPRESSED,
> +            convert section name from .zdebug_* to .debug_*.  */
> +         if (startswith (name, ".zdebug_"))
> +           {
> +             name = bfd_zdebug_name_to_debug (obfd, name);
> +             if (name == NULL)
> +               return false;
> +           }
> +       }
> +
> +      /* PR binutils/18087: Compression does not always make a
> +        section smaller.  So only rename the section when
> +        compression has actually taken place.  If input section
> +        name is .zdebug_*, we should never compress it again.  */
> +      else if (isec->compress_status == COMPRESS_SECTION_DONE
> +              && startswith (name, ".debug_"))
> +       {
> +         name = bfd_debug_name_to_zdebug (obfd, name);
> +         if (name == NULL)
> +           return false;
> +       }
> +      *new_name = name;
> +    }
> +  *new_size = bfd_section_size (isec);
> +
>    /* Do nothing if either input or output aren't ELF.  */
>    if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
>        || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
> -    return size;
> +    return true;
>
>    /* Do nothing if ELF classes of input and output are the same. */
>    if (get_elf_backend_data (ibfd)->s->elfclass
>        == get_elf_backend_data (obfd)->s->elfclass)
> -    return size;
> +    return true;
>
>    /* Convert GNU property size.  */
>    if (startswith (isec->name, NOTE_GNU_PROPERTY_SECTION_NAME))
> -    return _bfd_elf_convert_gnu_property_size (ibfd, obfd);
> +    {
> +      *new_size = _bfd_elf_convert_gnu_property_size (ibfd, obfd);
> +      return true;
> +    }
>
>    /* Do nothing if input file will be decompressed.  */
>    if ((ibfd->flags & BFD_DECOMPRESS))
> -    return size;
> +    return true;
>
>    /* Do nothing if the input section isn't a SHF_COMPRESSED section. */
>    hdr_size = bfd_get_compression_header_size (ibfd, isec);
>    if (hdr_size == 0)
> -    return size;
> +    return true;
>
>    /* Adjust the size of the output SHF_COMPRESSED section.  */
>    if (hdr_size == sizeof (Elf32_External_Chdr))
> -    return (size - sizeof (Elf32_External_Chdr)
> -           + sizeof (Elf64_External_Chdr));
> +    *new_size += sizeof (Elf64_External_Chdr) - sizeof (Elf32_External_Chdr);
>    else
> -    return (size - sizeof (Elf64_External_Chdr)
> -           + sizeof (Elf32_External_Chdr));
> +    *new_size += sizeof (Elf32_External_Chdr) - sizeof (Elf64_External_Chdr);

This doesn't work for 32-bit program since

 sizeof (Elf32_External_Chdr) - sizeof (Elf64_External_Chdr);

is negative and will overflow.

We should use

*new_size -= sizeof (Elf64_External_Chdr) - sizeof (Elf32_External_Chdr);

instead.

OK for master?

-- 
H.J.

[-- Attachment #2: 0001-bfd-Avoid-signed-overflow-for-new_size-adjustment.patch --]
[-- Type: application/x-patch, Size: 1229 bytes --]

  reply	other threads:[~2022-12-06 21:02 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-06  5:03 Get rid of SEC_ELF_RENAME Alan Modra
2022-12-06 21:01 ` H.J. Lu [this message]
2022-12-06 22:46   ` [PATCH] bfd: Avoid signed overflow for new_size adjustment Alan Modra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAMe9rOqXffjJHb0Rm=jgdGThruJ1o+CpxsRhq9h1J6jEsFrMzA@mail.gmail.com' \
    --to=hjl.tools@gmail.com \
    --cc=amodra@gmail.com \
    --cc=binutils@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).