[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openembedded-core
Subject:    Re: [OE-core] [kirkstone][PATCH] binutils : Fix CVE-2023-22608
From:       "Shinde, Yash" <Yash.Shinde () windriver ! com>
Date:       2023-02-28 6:10:22
Message-ID: SJ1PR11MB6129A763D8105BB88C04C8D7EBAC9 () SJ1PR11MB6129 ! namprd11 ! prod ! outlook ! com
[Download RAW message or body]

Yes, the actual fix is 0020-CVE-2023-22608-3.patch. The other two files are the \
dependent patch files required for this patch to apply. If these are excluded, the \
build gives errors in do_compile task due to missing code dependencies.

Regards,
Yash

From: MacLeod, Randy<mailto:Randy.MacLeod@windriver.com>
Sent: 28 February 2023 07:30
To: Yash Shinde<mailto:yashinde145@gmail.com>; \
openembedded-core@lists.openembedded.org<mailto:openembedded-core@lists.openembedded.org>; \
                steve@sakoman.com<mailto:steve@sakoman.com>
Cc: Kallapa, Umesh<mailto:Umesh.Kallapa@windriver.com>; Gowda, \
Naveen<mailto:Naveen.Gowda@windriver.com>; Kokkonda, \
Sundeep<mailto:Sundeep.Kokkonda@windriver.com>; Moodalappa, \
Shivaprasad<mailto:Shivaprasad.Moodalappa@windriver.com>; Shinde, \
                Yash<mailto:Yash.Shinde@windriver.com>
Subject: Re: [kirkstone][PATCH] binutils : Fix CVE-2023-22608

On 2023-02-26 04:11, Yash Shinde wrote:

From: Yash Shinde <Yash.Shinde@windriver.com><mailto:Yash.Shinde@windriver.com>



Upstream-Status: Backport \
[https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=8af23b30edbaedf009bc9b243cd4dfa10ae1ac09]




Signed-off-by: Yash Shinde \
<Yash.Shinde@windriver.com><mailto:Yash.Shinde@windriver.com>

---

 .../binutils/binutils-2.38.inc                |   3 +

 .../binutils/0020-CVE-2023-22608-1.patch      | 502 ++++++++++++++++++

 .../binutils/0020-CVE-2023-22608-2.patch      | 211 ++++++++

 .../binutils/0020-CVE-2023-22608-3.patch      |  33 ++

This is a large patch so I took a look at it.





The actual fix is: 0020-CVE-2023-22608-3.patch

https://sourceware.org/git/?p=binutils-gdb.git;a=blobdiff;f=bfd/dwarf2.c;h=88335cb4fb0 \
dddc3b1ca8a1d76c32b88ff85aa89;hp=b608afbc0cf260e98e2f87ab6d55c935937b2810;hb=8af23b30edbaedf009bc9b243cd4dfa10ae1ac09;hpb=8fbad19958c9b9c06a710bf7d6589d52f1ed8a64


which is just a few lines.

Unfortunately we do need the other two, rather large patches to make that apply it \
seems.

The patch that adds a trie seems like a feature but the code is all (I think) file
scope local structs with static functions so as far as the ABI stability, it seems \
fine to backport. It will change the memory footprint:

commit b43771b045fb5616da3964f2994eefbe8ae70d32
Author: Steinar H. Gunderson <sesse@google.com><mailto:sesse@google.com>
Date:   Fri May 20 10:10:34 2022

    add a trie to map quickly from address range to compilation unit

    When using perf to profile large binaries, _bfd_dwarf2_find_nearest_line()
    becomes a hotspot, as perf wants to get line number information
    (for inline-detection purposes) for each and every sample. In Chromium
    in particular (the content_shell binary), this entails going through
    475k address ranges, which takes a long time when done repeatedly.

    Add a radix-256 trie over the address space to quickly map address to
    compilation unit spaces; for content_shell, which is 1.6 GB when some
    (but not full) debug information turned is on, we go from 6 ms to
    0.006 ms (6 µs) for each lookup from address to compilation unit, a 1000x
    speedup.

    There is a modest RAM increase of 180 MB in this binary (the existing
    linked list over ranges uses about 10 MB, and the entire perf job uses
    between 2–3 GB for a medium-size profile); for smaller binaries with few
    ranges, there should be hardly any extra RAM usage at all.

../Randy



 4 files changed, 749 insertions(+)

 create mode 100644 meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-1.patch


 create mode 100644 meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-2.patch


 create mode 100644 meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-3.patch




diff --git a/meta/recipes-devtools/binutils/binutils-2.38.inc \
b/meta/recipes-devtools/binutils/binutils-2.38.inc

index 0a4a0d7bc1..30a34d7ba4 100644

--- a/meta/recipes-devtools/binutils/binutils-2.38.inc

+++ b/meta/recipes-devtools/binutils/binutils-2.38.inc

@@ -43,5 +43,8 @@ SRC_URI = "\

      file://0018-CVE-2022-38128-2.patch \

      file://0018-CVE-2022-38128-3.patch \

      file://0019-CVE-2022-4285.patch \

+     file://0020-CVE-2023-22608-1.patch \

+     file://0020-CVE-2023-22608-2.patch \

+     file://0020-CVE-2023-22608-3.patch \

 "

 S  = "${WORKDIR}/git"

diff --git a/meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-1.patch \
b/meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-1.patch

new file mode 100644

index 0000000000..dd3d533d0d

--- /dev/null

+++ b/meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-1.patch

@@ -0,0 +1,502 @@

+From a79c274dad99863f58b9ed627b38908daadb6d7e Mon Sep 17 00:00:00 2001

+From: "Steinar H. Gunderson" <sesse@google.com><mailto:sesse@google.com>

+Date: Fri, 20 May 2022 16:10:34 +0200

+Subject: [PATCH] add a trie to map quickly from address range to compilation

+ unit

+MIME-Version: 1.0

+Content-Type: text/plain; charset=UTF-8

+Content-Transfer-Encoding: 8bit

+

+When using perf to profile large binaries, _bfd_dwarf2_find_nearest_line()

+becomes a hotspot, as perf wants to get line number information

+(for inline-detection purposes) for each and every sample. In Chromium

+in particular (the content_shell binary), this entails going through

+475k address ranges, which takes a long time when done repeatedly.

+

+Add a radix-256 trie over the address space to quickly map address to

+compilation unit spaces; for content_shell, which is 1.6 GB when some

+(but not full) debug information turned is on, we go from 6 ms to

+0.006 ms (6 µs) for each lookup from address to compilation unit, a 1000x

+speedup.

+

+There is a modest RAM increase of 180 MB in this binary (the existing

+linked list over ranges uses about 10 MB, and the entire perf job uses

+between 2-3 GB for a medium-size profile); for smaller binaries with few

+ranges, there should be hardly any extra RAM usage at all.

+

+Upstream-Status: Backport \
[https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=b43771b045fb5616da3964f2994eefbe8ae70d32]


+

+CVE: CVE-2023-22608

+

+Signed-off-by: Yash Shinde \
<Yash.Shinde@windriver.com><mailto:Yash.Shinde@windriver.com>

+

+---

+ bfd/dwarf2.c | 326 ++++++++++++++++++++++++++++++++++++++++++++++++---

+ 1 file changed, 312 insertions(+), 14 deletions(-)

+

+diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c

+index fdf071c3..0ae50a37 100644

+--- a/bfd/dwarf2.c

++++ b/bfd/dwarf2.c

+@@ -82,6 +82,77 @@ struct adjusted_section

+   bfd_vma adj_vma;

+ };

+

++/* A trie to map quickly from address range to compilation unit.

++

++   This is a fairly standard radix-256 trie, used to quickly locate which

++   compilation unit any given address belongs to.  Given that each compilation

++   unit may register hundreds of very small and unaligned ranges (which may

++   potentially overlap, due to inlining and other concerns), and a large

++   program may end up containing hundreds of thousands of such ranges, we cannot

++   scan through them linearly without undue slowdown.

++

++   We use a hybrid trie to avoid memory explosion: There are two types of trie

++   nodes, leaves and interior nodes.  (Almost all nodes are leaves, so they

++   take up the bulk of the memory usage.) Leaves contain a simple array of

++   ranges (high/low address) and which compilation unit contains those ranges,

++   and when we get to a leaf, we scan through it linearly.  Interior nodes

++   contain pointers to 256 other nodes, keyed by the next byte of the address.

++   So for a 64-bit address like 0x1234567abcd, we would start at the root and go

++   down child[0x00]->child[0x00]->child[0x01]->child[0x23]->child[0x45] etc.,

++   until we hit a leaf.  (Nodes are, in general, leaves until they exceed the

++   default allocation of 16 elements, at which point they are converted to

++   interior node if possible.) This gives us near-constant lookup times;

++   the only thing that can be costly is if there are lots of overlapping ranges

++   within a single 256-byte segment of the binary, in which case we have to

++   scan through them all to find the best match.

++

++   For a binary with few ranges, we will in practice only have a single leaf

++   node at the root, containing a simple array.  Thus, the scheme is efficient

++   for both small and large binaries.

++ */

++

++/* Experiments have shown 16 to be a memory-efficient default leaf size.

++   The only case where a leaf will hold more memory than this, is at the

++   bottomost level (covering 256 bytes in the binary), where we'll expand

++   the leaf to be able to hold more ranges if needed.

++ */

++#define TRIE_LEAF_SIZE 16

++

++/* All trie_node pointers will really be trie_leaf or trie_interior,

++   but they have this common head.  */

++struct trie_node

++{

++  /* If zero, we are an interior node.

++     Otherwise, how many ranges we have room for in this leaf.  */

++  unsigned int num_room_in_leaf;

++};

++

++struct trie_leaf

++{

++  struct trie_node head;

++  unsigned int num_stored_in_leaf;

++  struct {

++    struct comp_unit *unit;

++    bfd_vma low_pc, high_pc;

++  } ranges[TRIE_LEAF_SIZE];

++};

++

++struct trie_interior

++{

++  struct trie_node head;

++  struct trie_node *children[256];

++};

++

++static struct trie_node *alloc_trie_leaf (bfd *abfd)

++{

++  struct trie_leaf *leaf =

++    bfd_zalloc (abfd, sizeof (struct trie_leaf));

++  if (leaf == NULL)

++    return NULL;

++  leaf->head.num_room_in_leaf = TRIE_LEAF_SIZE;

++  return &leaf->head;

++}

++

+ struct dwarf2_debug_file

+ {

+   /* The actual bfd from which debug info was loaded.  Might be

+@@ -139,6 +210,9 @@ struct dwarf2_debug_file

+   /* A list of all previously read comp_units.  */

+   struct comp_unit *all_comp_units;

+

++  /* A list of all previously read comp_units with no ranges (yet).  */

++  struct comp_unit *all_comp_units_without_ranges;

++

+   /* Last comp unit in list above.  */

+   struct comp_unit *last_comp_unit;

+

+@@ -147,6 +221,9 @@ struct dwarf2_debug_file

+

+   /* Hash table to map offsets to decoded abbrevs.  */

+   htab_t abbrev_offsets;

++

++  /* Root of a trie to map addresses to compilation units.  */

++  struct trie_node *trie_root;

+ };

+

+ struct dwarf2_debug

+@@ -220,6 +297,11 @@ struct comp_unit

+   /* Chain the previously read compilation units.  */

+   struct comp_unit *next_unit;

+

++  /* Chain the previously read compilation units that have no ranges yet.

++     We scan these separately when we have a trie over the ranges.

++     Unused if arange.high != 0. */

++  struct comp_unit *next_unit_without_ranges;

++

+   /* Likewise, chain the compilation unit read after this one.

+      The comp units are stored in reversed reading order.  */

+   struct comp_unit *prev_unit;

+@@ -296,6 +378,10 @@ struct comp_unit

+

+   /* TRUE if symbols are cached in hash table for faster lookup by name.  */

+   bool cached;

++

++  /* Used when iterating over trie leaves to know which units we have

++     already seen in this iteration.  */

++  bool mark;

+ };

+

+ /* This data structure holds the information of an abbrev.  */

+@@ -1766,9 +1852,189 @@ concat_filename (struct line_info_table *table, unsigned int \
file)

+   return strdup (filename);

+ }

+

++/* Number of bits in a bfd_vma.  */

++#define VMA_BITS (8 * sizeof (bfd_vma))

++

++/* Check whether [low1, high1) can be combined with [low2, high2),

++   i.e., they touch or overlap.  */

++static bool ranges_overlap (bfd_vma low1,

++                      bfd_vma high1,

++                      bfd_vma low2,

++                      bfd_vma high2)

++{

++  if (low1 == low2 || high1 == high2)

++    return true;

++

++  /* Sort so that low1 is below low2. */

++  if (low1 > low2)

++    {

++      bfd_vma tmp;

++

++      tmp = low1;

++      low1 = low2;

++      low2 = tmp;

++

++      tmp = high1;

++      high1 = high2;

++      high2 = tmp;

++    }

++

++  /* We touch iff low2 == high1.

++     We overlap iff low2 is within [low1, high1). */

++  return (low2 <= high1);

++}

++

++/* Insert an address range in the trie mapping addresses to compilation units.

++   Will return the new trie node (usually the same as is being sent in, but

++   in case of a leaf-to-interior conversion, or expansion of a leaf, it may be

++   different), or NULL on failure.

++ */

++static struct trie_node *insert_arange_in_trie(bfd *abfd,

++                                  struct trie_node *trie,

++                                  bfd_vma trie_pc,

++                                  unsigned int trie_pc_bits,

++                                  struct comp_unit *unit,

++                                  bfd_vma low_pc,

++                                  bfd_vma high_pc)

++{

++  bfd_vma clamped_low_pc, clamped_high_pc;

++  int ch, from_ch, to_ch;

++  bool is_full_leaf = false;

++

++  /* See if we can extend any of the existing ranges.  This merging

++     isn't perfect (if merging opens up the possibility of merging two existing

++     ranges, we won't find them), but it takes the majority of the cases.  */

++  if (trie->num_room_in_leaf > 0)

++    {

++      struct trie_leaf *leaf = (struct trie_leaf *) trie;

++      unsigned int i;

++

++      for (i = 0; i < leaf->num_stored_in_leaf; ++i)

++       {

++         if (leaf->ranges[i].unit == unit &&

++             ranges_overlap(low_pc, high_pc,

++                       leaf->ranges[i].low_pc, leaf->ranges[i].high_pc))

++           {

++             if (low_pc < leaf->ranges[i].low_pc)

++               leaf->ranges[i].low_pc = low_pc;

++             if (high_pc > leaf->ranges[i].high_pc)

++               leaf->ranges[i].high_pc = high_pc;

++             return trie;

++           }

++       }

++

++      is_full_leaf = leaf->num_stored_in_leaf == trie->num_room_in_leaf;

++    }

++

++  /* If we're a leaf with no more room and we're _not_ at the bottom,

++     convert to an interior node.  */

++  if (is_full_leaf && trie_pc_bits < VMA_BITS)

++    {

++      const struct trie_leaf *leaf = (struct trie_leaf *) trie;

++      unsigned int i;

++

++      trie = bfd_zalloc (abfd, sizeof (struct trie_interior));

++      if (!trie)

++       return NULL;

++      is_full_leaf = false;

++

++      /* TODO: If we wanted to save a little more memory at the cost of

++        complexity, we could have reused the old leaf node as one of the

++        children of the new interior node, instead of throwing it away.  */

++      for (i = 0; i < leaf->num_stored_in_leaf; ++i)

++        {

++         if (!insert_arange_in_trie (abfd, trie, trie_pc, trie_pc_bits,

++                           leaf->ranges[i].unit, leaf->ranges[i].low_pc,

++                           leaf->ranges[i].high_pc))

++           return NULL;

++       }

++    }

++

++  /* If we're a leaf with no more room and we _are_ at the bottom,

++     we have no choice but to just make it larger. */

++  if (is_full_leaf)

++    {

++      const struct trie_leaf *leaf = (struct trie_leaf *) trie;

++      unsigned int new_room_in_leaf = trie->num_room_in_leaf * 2;

++      struct trie_leaf *new_leaf;

++

++      new_leaf = bfd_zalloc (abfd,

++       sizeof (struct trie_leaf) +

++         (new_room_in_leaf - TRIE_LEAF_SIZE) * sizeof (leaf->ranges[0]));

++      new_leaf->head.num_room_in_leaf = new_room_in_leaf;

++      new_leaf->num_stored_in_leaf = leaf->num_stored_in_leaf;

++

++      memcpy (new_leaf->ranges,

++             leaf->ranges,

++             leaf->num_stored_in_leaf * sizeof (leaf->ranges[0]));

++      trie = &new_leaf->head;

++      is_full_leaf = false;

++

++      /* Now the insert below will go through.  */

++    }

++

++  /* If we're a leaf (now with room), we can just insert at the end.  */

++  if (trie->num_room_in_leaf > 0)

++    {

++      struct trie_leaf *leaf = (struct trie_leaf *) trie;

++

++      unsigned int i = leaf->num_stored_in_leaf++;

++      leaf->ranges[i].unit = unit;

++      leaf->ranges[i].low_pc = low_pc;

++      leaf->ranges[i].high_pc = high_pc;

++      return trie;

++    }

++

++  /* Now we are definitely an interior node, so recurse into all

++     the relevant buckets.  */

++

++  /* Clamp the range to the current trie bucket.  */

++  clamped_low_pc = low_pc;

++  clamped_high_pc = high_pc;

++  if (trie_pc_bits > 0)

++    {

++      bfd_vma bucket_high_pc =

++       trie_pc + ((bfd_vma)-1 >> trie_pc_bits);  /* Inclusive.  */

++      if (clamped_low_pc < trie_pc)

++       clamped_low_pc = trie_pc;

++      if (clamped_high_pc > bucket_high_pc)

++       clamped_high_pc = bucket_high_pc;

++    }

++

++  /* Insert the ranges in all buckets that it spans.  */

++  from_ch = (clamped_low_pc >> (VMA_BITS - trie_pc_bits - 8)) & 0xff;

++  to_ch = ((clamped_high_pc - 1) >> (VMA_BITS - trie_pc_bits - 8)) & 0xff;

++  for (ch = from_ch; ch <= to_ch; ++ch)

++    {

++      struct trie_interior *interior = (struct trie_interior *) trie;

++      struct trie_node *child = interior->children[ch];

++

++      if (child == NULL)

++        {

++         child = alloc_trie_leaf (abfd);

++         if (!child)

++           return NULL;

++       }

++      child = insert_arange_in_trie (abfd,

++                          child,

++                          trie_pc + ((bfd_vma)ch << (VMA_BITS - trie_pc_bits - 8)),

++                          trie_pc_bits + 8,

++                          unit,

++                          low_pc,

++                          high_pc);

++      if (!child)

++       return NULL;

++

++      interior->children[ch] = child;

++    }

++

++    return trie;

++}

++

++

+ static bool

+-arange_add (const struct comp_unit *unit, struct arange *first_arange,

+-           bfd_vma low_pc, bfd_vma high_pc)

++arange_add (struct comp_unit *unit, struct arange *first_arange,

++           struct trie_node **trie_root, bfd_vma low_pc, bfd_vma high_pc)

+ {

+   struct arange *arange;

+

+@@ -1776,6 +2042,19 @@ arange_add (const struct comp_unit *unit, struct arange \
*first_arange,

+   if (low_pc == high_pc)

+     return true;

+

++  if (trie_root != NULL)

++    {

++      *trie_root = insert_arange_in_trie (unit->file->bfd_ptr,

++                             *trie_root,

++                             0,

++                             0,

++                             unit,

++                             low_pc,

++                             high_pc);

++      if (*trie_root == NULL)

++       return false;

++    }

++

+   /* If the first arange is empty, use it.  */

+   if (first_arange->high == 0)

+     {

+@@ -2410,7 +2689,8 @@ decode_line_info (struct comp_unit *unit)

+            low_pc = address;

+          if (address > high_pc)

+            high_pc = address;

+-                 if (!arange_add (unit, &unit->arange, low_pc, high_pc))

++                 if (!arange_add (unit, &unit->arange, &unit->file->trie_root,

++                        low_pc, high_pc))

+            goto line_fail;

+          break;

+        case DW_LNE_set_address:

+@@ -3134,7 +3414,7 @@ find_abstract_instance (struct comp_unit *unit,

+

+ static bool

+ read_ranges (struct comp_unit *unit, struct arange *arange,

+-            bfd_uint64_t offset)

++            struct trie_node **trie_root, bfd_uint64_t offset)

+ {

+   bfd_byte *ranges_ptr;

+   bfd_byte *ranges_end;

+@@ -3169,7 +3449,7 @@ read_ranges (struct comp_unit *unit, struct arange *arange,

+ base_address = high_pc;

+        else

+ {

+-         if (!arange_add (unit, arange,

++         if (!arange_add (unit, arange, trie_root,

+                   base_address + low_pc, base_address + high_pc))

+     return false;

+ }

+@@ -3179,7 +3459,7 @@ read_ranges (struct comp_unit *unit, struct arange *arange,

+

+ static bool

+ read_rnglists (struct comp_unit *unit, struct arange *arange,

+-              bfd_uint64_t offset)

++              struct trie_node **trie_root, bfd_uint64_t offset)

+ {

+   bfd_byte *rngs_ptr;

+   bfd_byte *rngs_end;

+@@ -3253,19 +3533,19 @@ read_rnglists (struct comp_unit *unit, struct arange \
*arange,

+   return false;

+ }

+

+-      if (!arange_add (unit, arange, low_pc, high_pc))

++      if (!arange_add (unit, arange, trie_root, low_pc, high_pc))

+ return false;

+     }

+ }

+

+ static bool

+ read_rangelist (struct comp_unit *unit, struct arange *arange,

+-               bfd_uint64_t offset)

++               struct trie_node **trie_root, bfd_uint64_t offset)

+ {

+   if (unit->version <= 4)

+-    return read_ranges (unit, arange, offset);

++    return read_ranges (unit, arange, trie_root, offset);

+   else

+-    return read_rnglists (unit, arange, offset);

++    return read_rnglists (unit, arange, trie_root, offset);

+ }

+

+ static struct funcinfo *

+@@ -3563,7 +3843,8 @@ scan_unit_for_symbols (struct comp_unit *unit)

+

+        case DW_AT_ranges:

+          if (is_int_form (&attr)

+-                     && !read_rangelist (unit, &func->arange, attr.u.val))

++                     && !read_rangelist (unit, &func->arange,

++                             &unit->file->trie_root, attr.u.val))

+            goto fail;

+          break;

+

+@@ -3679,7 +3960,8 @@ scan_unit_for_symbols (struct comp_unit *unit)

+

+       if (func && high_pc != 0)

+ {

+-         if (!arange_add (unit, &func->arange, low_pc, high_pc))

++         if (!arange_add (unit, &func->arange, &unit->file->trie_root,

++                     low_pc, high_pc))

+     goto fail;

+ }

+     }

+@@ -3874,7 +4156,8 @@ parse_comp_unit (struct dwarf2_debug *stash,

+

+ case DW_AT_ranges:

+   if (is_int_form (&attr)

+-             && !read_rangelist (unit, &unit->arange, attr.u.val))

++             && !read_rangelist (unit, &unit->arange,

++                       &unit->file->trie_root, attr.u.val))

+     return NULL;

+   break;

+

+@@ -3916,7 +4199,8 @@ parse_comp_unit (struct dwarf2_debug *stash,

+     high_pc += low_pc;

+   if (high_pc != 0)

+     {

+-      if (!arange_add (unit, &unit->arange, low_pc, high_pc))

++      if (!arange_add (unit, &unit->arange, &unit->file->trie_root,

++                      low_pc, high_pc))

+ return NULL;

+     }

+

+@@ -4747,6 +5031,14 @@ _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,

+   if (!stash->alt.abbrev_offsets)

+     return false;

+

++  stash->f.trie_root = alloc_trie_leaf (abfd);

++  if (!stash->f.trie_root)

++    return false;

++

++  stash->alt.trie_root = alloc_trie_leaf (abfd);

++  if (!stash->alt.trie_root)

++    return false;

++

+   *pinfo = stash;

+

+   if (debug_bfd == NULL)

+@@ -4918,6 +5210,12 @@ stash_comp_unit (struct dwarf2_debug *stash, struct \
dwarf2_debug_file *file)

+   each->next_unit = file->all_comp_units;

+   file->all_comp_units = each;

+

++         if (each->arange.high == 0)

++           {

++             each->next_unit_without_ranges = file->all_comp_units_without_ranges;

++             file->all_comp_units_without_ranges = each->next_unit_without_ranges;

++           }

++

+   file->info_ptr += length;

+   return each;

+ }

diff --git a/meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-2.patch \
b/meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-2.patch

new file mode 100644

index 0000000000..8ffb500c1d

--- /dev/null

+++ b/meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-2.patch

@@ -0,0 +1,211 @@

+From 73e97e32e1428d63d81d971176772ae69397a1a0 Mon Sep 17 00:00:00 2001

+From: Nick Clifton <nickc@redhat.com><mailto:nickc@redhat.com>

+Date: Tue, 30 Aug 2022 16:01:20 +0100

+Subject: [PATCH] BFD library: Use entry 0 in directory and filename tables of

+ DWARF-5 debug info.

+

+ PR 29529

+ * dwarf2.c (struct line_info_table): Add new field:

+ use_dir_and_file_0.

+ (concat_filename): Use new field to help select the correct table

+ slot.

+ (read_formatted_entries): Do not skip entry 0.

+ (decode_line_info): Set new field depending upon the version of

+ DWARF being parsed.  Initialise filename based upon the setting of

+ the new field.

+

+Upstream-Status: Backport \
[https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=37833b966576c5d25e797ea3b6c33d0459a71892]


+CVE: CVE-2023-22608

+

+Signed-off-by: Yash Shinde \
<Yash.Shinde@windriver.com><mailto:Yash.Shinde@windriver.com>

+

+---

+ bfd/ChangeLog                      | 12 +++++

+ bfd/dwarf2.c                       | 86 ++++++++++++++++++++----------

+ ld/ChangeLog                       |  5 ++

+ ld/testsuite/ld-x86-64/pr27587.err |  2 +-

+ 4 files changed, 76 insertions(+), 29 deletions(-)

+

+diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c

+index 0ae50a37..b7839ad6 100644

+--- a/bfd/dwarf2.c

++++ b/bfd/dwarf2.c

+@@ -1571,6 +1571,7 @@ struct line_info_table

+   unsigned int    num_files;

+   unsigned int    num_dirs;

+   unsigned int    num_sequences;

++  bool                  use_dir_and_file_0;

+   char *          comp_dir;

+   char **         dirs;

+   struct fileinfo*   files;

+@@ -1791,16 +1792,30 @@ concat_filename (struct line_info_table *table, unsigned int \
file)

+ {

+   char *filename;

+

+-  if (table == NULL || file - 1 >= table->num_files)

++  /* Pre DWARF-5 entry 0 in the directory and filename tables was not used.

++     So in order to save space in the tables used here the info for, eg

++     directory 1 is stored in slot 0 of the directory table, directory 2

++     in slot 1 and so on.

++

++     Starting with DWARF-5 the 0'th entry is used so there is a one to one

++     mapping between DWARF slots and internal table entries.  */

++  if (! table->use_dir_and_file_0)

+     {

+-      /* FILE == 0 means unknown.  */

+-      if (file)

+-       _bfd_error_handler

+-         (_("DWARF error: mangled line number section (bad file number)"));

++      /* Pre DWARF-5, FILE == 0 means unknown.  */

++      if (file == 0)

++       return strdup ("<unknown>");

++      -- file;

++    }

++

++  if (table == NULL || file >= table->num_files)

++    {

++      _bfd_error_handler

++       (_("DWARF error: mangled line number section (bad file number)"));

+       return strdup ("<unknown>");

+     }

+

+-  filename = table->files[file - 1].name;

++  filename = table->files[file].name;

++

+   if (filename == NULL)

+     return strdup ("<unknown>");

+

+@@ -1811,12 +1826,17 @@ concat_filename (struct line_info_table *table, unsigned int \
file)

+       char *name;

+       size_t len;

+

+-      if (table->files[file - 1].dir

++      if (table->files[file].dir

+   /* PR 17512: file: 0317e960.  */

+-         && table->files[file - 1].dir <= table->num_dirs

++         && table->files[file].dir <= table->num_dirs

+   /* PR 17512: file: 7f3d2e4b.  */

+   && table->dirs != NULL)

+-       subdir_name = table->dirs[table->files[file - 1].dir - 1];

++       {

++         if (table->use_dir_and_file_0)

++           subdir_name = table->dirs[table->files[file].dir];

++         else

++           subdir_name = table->dirs[table->files[file].dir - 1];

++       }

+

+       if (!subdir_name || !IS_ABSOLUTE_PATH (subdir_name))

+ dir_name = table->comp_dir;

+@@ -1857,10 +1877,12 @@ concat_filename (struct line_info_table *table, unsigned int \
file)

+

+ /* Check whether [low1, high1) can be combined with [low2, high2),

+    i.e., they touch or overlap.  */

+-static bool ranges_overlap (bfd_vma low1,

+-                      bfd_vma high1,

+-                      bfd_vma low2,

+-                      bfd_vma high2)

++

++static bool

++ranges_overlap (bfd_vma low1,

++               bfd_vma high1,

++               bfd_vma low2,

++               bfd_vma high2)

+ {

+   if (low1 == low2 || high1 == high2)

+     return true;

+@@ -1887,15 +1909,16 @@ static bool ranges_overlap (bfd_vma low1,

+ /* Insert an address range in the trie mapping addresses to compilation units.

+    Will return the new trie node (usually the same as is being sent in, but

+    in case of a leaf-to-interior conversion, or expansion of a leaf, it may be

+-   different), or NULL on failure.

+- */

+-static struct trie_node *insert_arange_in_trie(bfd *abfd,

+-                                  struct trie_node *trie,

+-                                  bfd_vma trie_pc,

+-                                  unsigned int trie_pc_bits,

+-                                  struct comp_unit *unit,

+-                                  bfd_vma low_pc,

+-                                  bfd_vma high_pc)

++   different), or NULL on failure.  */

++

++static struct trie_node *

++insert_arange_in_trie (bfd *abfd,

++                      struct trie_node *trie,

++                      bfd_vma trie_pc,

++                      unsigned int trie_pc_bits,

++                      struct comp_unit *unit,

++                      bfd_vma low_pc,

++                      bfd_vma high_pc)

+ {

+   bfd_vma clamped_low_pc, clamped_high_pc;

+   int ch, from_ch, to_ch;

+@@ -2031,7 +2054,6 @@ static struct trie_node *insert_arange_in_trie(bfd *abfd,

+     return trie;

+ }

+

+-

+ static bool

+ arange_add (struct comp_unit *unit, struct arange *first_arange,

+     struct trie_node **trie_root, bfd_vma low_pc, bfd_vma high_pc)

+@@ -2412,10 +2434,8 @@ read_formatted_entries (struct comp_unit *unit, bfd_byte \
**bufp,

+     }

+ }

+

+-      /* Skip the first "zero entry", which is the compilation dir/file.  */

+-      if (datai != 0)

+-       if (!callback (table, fe.name, fe.dir, fe.time, fe.size))

+-         return false;

++      if (!callback (table, fe.name, fe.dir, fe.time, fe.size))

++       return false;

+     }

+

+   *bufp = buf;

+@@ -2592,6 +2612,7 @@ decode_line_info (struct comp_unit *unit)

+       if (!read_formatted_entries (unit, &line_ptr, line_end, table,

+                      line_info_add_file_name))

+ goto fail;

++      table->use_dir_and_file_0 = true;

+     }

+   else

+     {

+@@ -2614,6 +2635,7 @@ decode_line_info (struct comp_unit *unit)

+   if (!line_info_add_file_name (table, cur_file, dir, xtime, size))

+     goto fail;

+ }

++      table->use_dir_and_file_0 = false;

+     }

+

+   /* Read the statement sequences until there's nothing left.  */

+@@ -2622,7 +2644,7 @@ decode_line_info (struct comp_unit *unit)

+       /* State machine registers.  */

+       bfd_vma address = 0;

+       unsigned char op_index = 0;

+-      char * filename = table->num_files ? concat_filename (table, 1) : NULL;

++      char * filename = NULL;

+       unsigned int line = 1;

+       unsigned int column = 0;

+       unsigned int discriminator = 0;

+@@ -2637,6 +2659,14 @@ decode_line_info (struct comp_unit *unit)

+       bfd_vma low_pc  = (bfd_vma) -1;

+       bfd_vma high_pc = 0;

+

++      if (table->num_files)

++       {

++         if (table->use_dir_and_file_0)

++           filename = concat_filename (table, 0);

++         else

++           filename = concat_filename (table, 1);

++       }

++

+       /* Decode the table.  */

+       while (!end_sequence && line_ptr < line_end)

+ {

+diff --git a/ld/testsuite/ld-x86-64/pr27587.err b/ld/testsuite/ld-x86-64/pr27587.err

+index fa870790..807750ca 100644

+--- a/ld/testsuite/ld-x86-64/pr27587.err

++++ b/ld/testsuite/ld-x86-64/pr27587.err

+@@ -1,3 +1,3 @@

+ #...

+-.*pr27587.i:4: undefined reference to `stack_size'

++.*pr27587/<artificial>:4: undefined reference to `stack_size'

+ #...

diff --git a/meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-3.patch \
b/meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-3.patch

new file mode 100644

index 0000000000..603824155b

--- /dev/null

+++ b/meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-3.patch

@@ -0,0 +1,33 @@

+From 20c75f063a999f9e849a77613a82b15de78ea45f Mon Sep 17 00:00:00 2001

+From: Nick Clifton <nickc@redhat.com><mailto:nickc@redhat.com>

+Date: Fri, 23 Dec 2022 13:02:04 +0000

+Subject: [PATCH] Fix illegal memory access parsing corrupt DWARF information.

+

+ PR 29936

+ * dwarf2.c (concat_filename): Fix check for a directory index off

+ the end of the directory table.

+

+Upstream-Status: Backport \
[https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=8af23b30edbaedf009bc9b243cd4dfa10ae1ac09]


+CVE: CVE-2023-22608

+

+Signed-off-by: Yash Shinde \
<Yash.Shinde@windriver.com><mailto:Yash.Shinde@windriver.com>

+

+---

+ bfd/ChangeLog | 6 ++++++

+ bfd/dwarf2.c  | 3 ++-

+ 2 files changed, 8 insertions(+), 1 deletion(-)

+

+diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c

+index b7839ad6..8b07a24c 100644

+--- a/bfd/dwarf2.c

++++ b/bfd/dwarf2.c

+@@ -1828,7 +1828,8 @@ concat_filename (struct line_info_table *table, unsigned int \
file)

+

+       if (table->files[file].dir

+   /* PR 17512: file: 0317e960.  */

+-         && table->files[file].dir <= table->num_dirs

++         && table->files[file].dir

++         <= (table->use_dir_and_file_0 ? table->num_dirs - 1 : table->num_dirs)

+   /* PR 17512: file: 7f3d2e4b.  */

+   && table->dirs != NULL)

+ {



--

# Randy MacLeod

# Wind River Linux


[Attachment #3 (text/html)]

<html xmlns:o="urn:schemas-microsoft-com:office:office" \
xmlns:w="urn:schemas-microsoft-com:office:word" \
xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" \
xmlns="http://www.w3.org/TR/REC-html40"> <head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
	{font-family:Mangal;
	panose-1:2 4 5 3 5 2 3 3 2 2;}
@font-face
	{font-family:"Cambria Math";
	panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
	{font-family:Calibri;
	panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
	{margin:0cm;
	font-size:11.0pt;
	font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
	{mso-style-priority:99;
	color:blue;
	text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
	{mso-style-priority:99;
	color:#954F72;
	text-decoration:underline;}
pre
	{mso-style-priority:99;
	mso-style-link:"HTML Preformatted Char";
	margin:0cm;
	font-size:10.0pt;
	font-family:"Courier New";}
span.HTMLPreformattedChar
	{mso-style-name:"HTML Preformatted Char";
	mso-style-priority:99;
	mso-style-link:"HTML Preformatted";
	font-family:"Courier New";}
p.msonormal0, li.msonormal0, div.msonormal0
	{mso-style-name:msonormal;
	mso-margin-top-alt:auto;
	margin-right:0cm;
	mso-margin-bottom-alt:auto;
	margin-left:0cm;
	font-size:11.0pt;
	font-family:"Calibri",sans-serif;}
.MsoChpDefault
	{mso-style-type:export-only;}
@page WordSection1
	{size:612.0pt 792.0pt;
	margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
	{page:WordSection1;}
--></style>
</head>
<body lang="EN-IN" link="blue" vlink="#954F72" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal">Yes, the actual fix is <i>0020-CVE-2023-22608-3.patch</i>. The \
other two files are the dependent patch files required for this patch to apply. If \
these are excluded, the build gives errors in <i>do_compile</i> task due to missing \
code dependencies.</p> <p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<p class="MsoNormal">Regards,<br>
Yash<o:p></o:p></p>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<div style="mso-element:para-border-div;border:none;border-top:solid #E1E1E1 \
1.0pt;padding:3.0pt 0cm 0cm 0cm"> <p class="MsoNormal" \
style="border:none;padding:0cm"><b>From: </b><a \
href="mailto:Randy.MacLeod@windriver.com">MacLeod, Randy</a><br> <b>Sent: </b>28 \
February 2023 07:30<br> <b>To: </b><a href="mailto:yashinde145@gmail.com">Yash \
Shinde</a>; <a href="mailto:openembedded-core@lists.openembedded.org"> \
openembedded-core@lists.openembedded.org</a>; <a href="mailto:steve@sakoman.com"> \
steve@sakoman.com</a><br> <b>Cc: </b><a \
href="mailto:Umesh.Kallapa@windriver.com">Kallapa, Umesh</a>; <a \
href="mailto:Naveen.Gowda@windriver.com"> Gowda, Naveen</a>; <a \
href="mailto:Sundeep.Kokkonda@windriver.com">Kokkonda, Sundeep</a>; <a \
href="mailto:Shivaprasad.Moodalappa@windriver.com">Moodalappa, Shivaprasad</a>; <a \
href="mailto:Yash.Shinde@windriver.com">Shinde, Yash</a><br> <b>Subject: </b>Re: \
[kirkstone][PATCH] binutils : Fix CVE-2023-22608</p> </div>
<p class="MsoNormal"><o:p>&nbsp;</o:p></p>
<div>
<p class="MsoNormal">On 2023-02-26 04:11, Yash Shinde wrote:<o:p></o:p></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<pre>From: Yash Shinde <a \
href="mailto:Yash.Shinde@windriver.com">&lt;Yash.Shinde@windriver.com&gt;</a></pre> \
<pre><o:p>&nbsp;</o:p></pre> <pre>Upstream-Status: Backport [<a \
href="https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=8af23b30edbaedf009 \
bc9b243cd4dfa10ae1ac09">https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=8af23b30edbaedf009bc9b243cd4dfa10ae1ac09</a>]</pre>
 <pre><o:p>&nbsp;</o:p></pre>
<pre>Signed-off-by: Yash Shinde <a \
href="mailto:Yash.Shinde@windriver.com">&lt;Yash.Shinde@windriver.com&gt;</a></pre> \
<pre>---</pre> <pre> \
.../binutils/binutils-2.38.inc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
|&nbsp;&nbsp; 3 +</pre> <pre> \
.../binutils/0020-CVE-2023-22608-1.patch&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | 502 \
++++++++++++++++++</pre> <pre> \
.../binutils/0020-CVE-2023-22608-2.patch&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | 211 \
++++++++</pre> <pre> \
.../binutils/0020-CVE-2023-22608-3.patch&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp; 33 \
++</pre> </blockquote>
<pre>This is a large patch so I took a look at it.</pre>
<pre><o:p>&nbsp;</o:p></pre>
<pre><o:p>&nbsp;</o:p></pre>
<pre>The actual fix is: 0020-CVE-2023-22608-3.patch</pre>
<p><a href="https://sourceware.org/git/?p=binutils-gdb.git;a=blobdiff;f=bfd/dwarf2.c;h \
=88335cb4fb0dddc3b1ca8a1d76c32b88ff85aa89;hp=b608afbc0cf260e98e2f87ab6d55c935937b2810; \
hb=8af23b30edbaedf009bc9b243cd4dfa10ae1ac09;hpb=8fbad19958c9b9c06a710bf7d6589d52f1ed8a \
64">https://sourceware.org/git/?p=binutils-gdb.git;a=blobdiff;f=bfd/dwarf2.c;h=88335cb \
4fb0dddc3b1ca8a1d76c32b88ff85aa89;hp=b608afbc0cf260e98e2f87ab6d55c935937b2810;hb=8af23 \
b30edbaedf009bc9b243cd4dfa10ae1ac09;hpb=8fbad19958c9b9c06a710bf7d6589d52f1ed8a64</a></p>
 <p>which is just a few lines.</p>
<p>Unfortunately we do need the other two, rather large patches to make that apply it \
seems.</p> <p>The patch that adds a trie seems like a feature but the code is all (I \
think) file<br> scope local structs with static functions so as far as the ABI \
stability, it seems fine<br> to backport. It will change the memory footprint:<br>
<br>
commit b43771b045fb5616da3964f2994eefbe8ae70d32<br>
Author: Steinar H. Gunderson <a \
href="mailto:sesse@google.com">&lt;sesse@google.com&gt;</a><br> Date:&nbsp;&nbsp; Fri \
May 20 10:10:34 2022<br> <br>
&nbsp;&nbsp;&nbsp; add a trie to map quickly from address range to compilation \
unit<br> &nbsp;&nbsp; &nbsp;<br>
&nbsp;&nbsp;&nbsp; When using perf to profile large binaries, \
_bfd_dwarf2_find_nearest_line()<br> &nbsp;&nbsp;&nbsp; becomes a hotspot, as perf \
wants to get line number information<br> &nbsp;&nbsp;&nbsp; (for inline-detection \
purposes) for each and every sample. In Chromium<br> &nbsp;&nbsp;&nbsp; in particular \
(the content_shell binary), this entails going through<br> &nbsp;&nbsp;&nbsp; 475k \
address ranges, which takes a long time when done repeatedly.<br> &nbsp;&nbsp; \
&nbsp;<br> &nbsp;&nbsp;&nbsp; Add a radix-256 trie over the address space to quickly \
map address to<br> &nbsp;&nbsp;&nbsp; compilation unit spaces; for content_shell, \
which is 1.6 GB when some<br> &nbsp;&nbsp;&nbsp; (but not full) debug information \
turned is on, we go from 6 ms to<br> &nbsp;&nbsp;&nbsp; 0.006 ms (6 µs) for each \
lookup from address to compilation unit, a 1000x<br> &nbsp;&nbsp;&nbsp; speedup.<br>
&nbsp;&nbsp; &nbsp;<br>
&nbsp;&nbsp;&nbsp; There is a modest RAM increase of 180 MB in this binary (the \
existing<br> &nbsp;&nbsp;&nbsp; linked list over ranges uses about 10 MB, and the \
entire perf job uses<br> &nbsp;&nbsp;&nbsp; between 2–3 GB for a medium-size \
profile); for smaller binaries with few<br> &nbsp;&nbsp;&nbsp; ranges, there should \
be hardly any extra RAM usage at all.<br> <br>
../Randy</p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<pre><o:p>&nbsp;</o:p></pre>
<pre> 4 files changed, 749 insertions(+)</pre>
<pre> create mode 100644 \
meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-1.patch</pre> <pre> \
create mode 100644 meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-2.patch</pre>
 <pre> create mode 100644 \
meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-3.patch</pre> \
<pre><o:p>&nbsp;</o:p></pre> <pre>diff --git \
a/meta/recipes-devtools/binutils/binutils-2.38.inc \
b/meta/recipes-devtools/binutils/binutils-2.38.inc</pre> <pre>index \
0a4a0d7bc1..30a34d7ba4 100644</pre> <pre>--- \
a/meta/recipes-devtools/binutils/binutils-2.38.inc</pre> <pre>+++ \
b/meta/recipes-devtools/binutils/binutils-2.38.inc</pre> <pre>@@ -43,5 +43,8 @@ \
SRC_URI = &quot;\</pre> <pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a \
href="file://0018-CVE-2022-38128-2.patch">file://0018-CVE-2022-38128-2.patch</a> \
\</pre> <pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a \
href="file://0018-CVE-2022-38128-3.patch">file://0018-CVE-2022-38128-3.patch</a> \
\</pre> <pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a \
href="file://0019-CVE-2022-4285.patch">file://0019-CVE-2022-4285.patch</a> \</pre> \
<pre>+&nbsp;&nbsp;&nbsp;&nbsp; <a \
href="file://0020-CVE-2023-22608-1.patch">file://0020-CVE-2023-22608-1.patch</a> \
\</pre> <pre>+&nbsp;&nbsp;&nbsp;&nbsp; <a \
href="file://0020-CVE-2023-22608-2.patch">file://0020-CVE-2023-22608-2.patch</a> \
\</pre> <pre>+&nbsp;&nbsp;&nbsp;&nbsp; <a \
href="file://0020-CVE-2023-22608-3.patch">file://0020-CVE-2023-22608-3.patch</a> \
\</pre> <pre> &quot;</pre>
<pre> S&nbsp; = &quot;${WORKDIR}/git&quot;</pre>
<pre>diff --git a/meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-1.patch \
b/meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-1.patch</pre> <pre>new \
file mode 100644</pre> <pre>index 0000000000..dd3d533d0d</pre>
<pre>--- /dev/null</pre>
<pre>+++ b/meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-1.patch</pre>
<pre>@@ -0,0 +1,502 @@</pre>
<pre>+From a79c274dad99863f58b9ed627b38908daadb6d7e Mon Sep 17 00:00:00 2001</pre>
<pre>+From: &quot;Steinar H. Gunderson&quot; <a \
href="mailto:sesse@google.com">&lt;sesse@google.com&gt;</a></pre> <pre>+Date: Fri, 20 \
May 2022 16:10:34 +0200</pre> <pre>+Subject: [PATCH] add a trie to map quickly from \
address range to compilation</pre> <pre>+ unit</pre>
<pre>+MIME-Version: 1.0</pre>
<pre>+Content-Type: text/plain; charset=UTF-8</pre>
<pre>+Content-Transfer-Encoding: 8bit</pre>
<pre>+</pre>
<pre>+When using perf to profile large binaries, \
_bfd_dwarf2_find_nearest_line()</pre> <pre>+becomes a hotspot, as perf wants to get \
line number information</pre> <pre>+(for inline-detection purposes) for each and \
every sample. In Chromium</pre> <pre>+in particular (the content_shell binary), this \
entails going through</pre> <pre>+475k address ranges, which takes a long time when \
done repeatedly.</pre> <pre>+</pre>
<pre>+Add a radix-256 trie over the address space to quickly map address to</pre>
<pre>+compilation unit spaces; for content_shell, which is 1.6 GB when some</pre>
<pre>+(but not full) debug information turned is on, we go from 6 ms to</pre>
<pre>+0.006 ms (6 µs) for each lookup from address to compilation unit, a 1000x</pre>
<pre>+speedup.</pre>
<pre>+</pre>
<pre>+There is a modest RAM increase of 180 MB in this binary (the existing</pre>
<pre>+linked list over ranges uses about 10 MB, and the entire perf job uses</pre>
<pre>+between 2-3 GB for a medium-size profile); for smaller binaries with few</pre>
<pre>+ranges, there should be hardly any extra RAM usage at all.</pre>
<pre>+</pre>
<pre>+Upstream-Status: Backport [<a \
href="https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=b43771b045fb5616da \
3964f2994eefbe8ae70d32">https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=b43771b045fb5616da3964f2994eefbe8ae70d32</a>]</pre>
 <pre>+</pre>
<pre>+CVE: CVE-2023-22608</pre>
<pre>+</pre>
<pre>+Signed-off-by: Yash Shinde <a \
href="mailto:Yash.Shinde@windriver.com">&lt;Yash.Shinde@windriver.com&gt;</a></pre> \
<pre>+</pre> <pre>+---</pre>
<pre>+ bfd/dwarf2.c | 326 ++++++++++++++++++++++++++++++++++++++++++++++++---</pre>
<pre>+ 1 file changed, 312 insertions(+), 14 deletions(-)</pre>
<pre>+</pre>
<pre>+diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c</pre>
<pre>+index fdf071c3..0ae50a37 100644</pre>
<pre>+--- a/bfd/dwarf2.c</pre>
<pre>++++ b/bfd/dwarf2.c</pre>
<pre>+@@ -82,6 +82,77 @@ struct adjusted_section</pre>
<pre>+&nbsp;&nbsp; bfd_vma adj_vma;</pre>
<pre>+ };</pre>
<pre>+</pre>
<pre>++/* A trie to map quickly from address range to compilation unit.</pre>
<pre>++</pre>
<pre>++&nbsp;&nbsp; This is a fairly standard radix-256 trie, used to quickly locate \
which</pre> <pre>++&nbsp;&nbsp; compilation unit any given address belongs to.&nbsp; \
Given that each compilation</pre> <pre>++&nbsp;&nbsp; unit may register hundreds of \
very small and unaligned ranges (which may</pre> <pre>++&nbsp;&nbsp; potentially \
overlap, due to inlining and other concerns), and a large</pre> <pre>++&nbsp;&nbsp; \
program may end up containing hundreds of thousands of such ranges, we cannot</pre> \
<pre>++&nbsp;&nbsp; scan through them linearly without undue slowdown.</pre> \
<pre>++</pre> <pre>++&nbsp;&nbsp; We use a hybrid trie to avoid memory explosion: \
There are two types of trie</pre> <pre>++&nbsp;&nbsp; nodes, leaves and interior \
nodes.&nbsp; (Almost all nodes are leaves, so they</pre> <pre>++&nbsp;&nbsp; take up \
the bulk of the memory usage.) Leaves contain a simple array of</pre> \
<pre>++&nbsp;&nbsp; ranges (high/low address) and which compilation unit contains \
those ranges,</pre> <pre>++&nbsp;&nbsp; and when we get to a leaf, we scan through it \
linearly.&nbsp; Interior nodes</pre> <pre>++&nbsp;&nbsp; contain pointers to 256 \
other nodes, keyed by the next byte of the address.</pre> <pre>++&nbsp;&nbsp; So for \
a 64-bit address like 0x1234567abcd, we would start at the root and go</pre> \
<pre>++&nbsp;&nbsp; down \
child[0x00]-&gt;child[0x00]-&gt;child[0x01]-&gt;child[0x23]-&gt;child[0x45] \
etc.,</pre> <pre>++&nbsp;&nbsp; until we hit a leaf.&nbsp; (Nodes are, in general, \
leaves until they exceed the</pre> <pre>++&nbsp;&nbsp; default allocation of 16 \
elements, at which point they are converted to</pre> <pre>++&nbsp;&nbsp; interior \
node if possible.) This gives us near-constant lookup times;</pre> \
<pre>++&nbsp;&nbsp; the only thing that can be costly is if there are lots of \
overlapping ranges</pre> <pre>++&nbsp;&nbsp; within a single 256-byte segment of the \
binary, in which case we have to</pre> <pre>++&nbsp;&nbsp; scan through them all to \
find the best match.</pre> <pre>++</pre>
<pre>++&nbsp;&nbsp; For a binary with few ranges, we will in practice only have a \
single leaf</pre> <pre>++&nbsp;&nbsp; node at the root, containing a simple \
array.&nbsp; Thus, the scheme is efficient</pre> <pre>++&nbsp; &nbsp;for both small \
and large binaries.</pre> <pre>++ */</pre>
<pre>++</pre>
<pre>++/* Experiments have shown 16 to be a memory-efficient default leaf size.</pre>
<pre>++&nbsp;&nbsp; The only case where a leaf will hold more memory than this, is at \
the</pre> <pre>++&nbsp;&nbsp; bottomost level (covering 256 bytes in the binary), \
where we'll expand</pre> <pre>++&nbsp;&nbsp; the leaf to be able to hold more ranges \
if needed.</pre> <pre>++ */</pre>
<pre>++#define TRIE_LEAF_SIZE 16</pre>
<pre>++</pre>
<pre>++/* All trie_node pointers will really be trie_leaf or trie_interior,</pre>
<pre>++&nbsp;&nbsp; but they have this common head.&nbsp; */</pre>
<pre>++struct trie_node</pre>
<pre>++{</pre>
<pre>++&nbsp; /* If zero, we are an interior node.</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp; Otherwise, how many ranges we have room for in this \
leaf.&nbsp; */</pre> <pre>++&nbsp; unsigned int num_room_in_leaf;</pre>
<pre>++};</pre>
<pre>++</pre>
<pre>++struct trie_leaf</pre>
<pre>++{</pre>
<pre>++&nbsp; struct trie_node head;</pre>
<pre>++&nbsp; unsigned int num_stored_in_leaf;</pre>
<pre>++&nbsp; struct {</pre>
<pre>++&nbsp;&nbsp;&nbsp; struct comp_unit *unit;</pre>
<pre>++&nbsp;&nbsp;&nbsp; bfd_vma low_pc, high_pc;</pre>
<pre>++&nbsp; } ranges[TRIE_LEAF_SIZE];</pre>
<pre>++};</pre>
<pre>++</pre>
<pre>++struct trie_interior</pre>
<pre>++{</pre>
<pre>++&nbsp; struct trie_node head;</pre>
<pre>++&nbsp; struct trie_node *children[256];</pre>
<pre>++};</pre>
<pre>++</pre>
<pre>++static struct trie_node *alloc_trie_leaf (bfd *abfd)</pre>
<pre>++{</pre>
<pre>++&nbsp; struct trie_leaf *leaf =</pre>
<pre>++&nbsp;&nbsp;&nbsp; bfd_zalloc (abfd, sizeof (struct trie_leaf));</pre>
<pre>++&nbsp; if (leaf == NULL)</pre>
<pre>++&nbsp;&nbsp;&nbsp; return NULL;</pre>
<pre>++&nbsp; leaf-&gt;head.num_room_in_leaf = TRIE_LEAF_SIZE;</pre>
<pre>++&nbsp; return &amp;leaf-&gt;head;</pre>
<pre>++}</pre>
<pre>++</pre>
<pre>+ struct dwarf2_debug_file</pre>
<pre>+ {</pre>
<pre>+&nbsp;&nbsp; /* The actual bfd from which debug info was loaded.&nbsp; Might \
be</pre> <pre>+@@ -139,6 +210,9 @@ struct dwarf2_debug_file</pre>
<pre>+&nbsp;&nbsp; /* A list of all previously read comp_units.&nbsp; */</pre>
<pre>+&nbsp;&nbsp; struct comp_unit *all_comp_units;</pre>
<pre>+</pre>
<pre>++&nbsp; /* A list of all previously read comp_units with no ranges (yet).&nbsp; \
*/</pre> <pre>++&nbsp; struct comp_unit *all_comp_units_without_ranges;</pre>
<pre>++</pre>
<pre>+&nbsp;&nbsp; /* Last comp unit in list above.&nbsp; */</pre>
<pre>+&nbsp;&nbsp; struct comp_unit *last_comp_unit;</pre>
<pre>+</pre>
<pre>+@@ -147,6 +221,9 @@ struct dwarf2_debug_file</pre>
<pre>+</pre>
<pre>+&nbsp;&nbsp; /* Hash table to map offsets to decoded abbrevs.&nbsp; */</pre>
<pre>+&nbsp;&nbsp; htab_t abbrev_offsets;</pre>
<pre>++</pre>
<pre>++&nbsp; /* Root of a trie to map addresses to compilation units.&nbsp; */</pre>
<pre>++&nbsp; struct trie_node *trie_root;</pre>
<pre>+ };</pre>
<pre>+</pre>
<pre>+ struct dwarf2_debug</pre>
<pre>+@@ -220,6 +297,11 @@ struct comp_unit</pre>
<pre>+&nbsp;&nbsp; /* Chain the previously read compilation units.&nbsp; */</pre>
<pre>+&nbsp;&nbsp; struct comp_unit *next_unit;</pre>
<pre>+</pre>
<pre>++&nbsp; /* Chain the previously read compilation units that have no ranges \
yet.</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp; We scan these separately when we have a \
trie over the ranges.</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp; Unused if arange.high != \
0. */</pre> <pre>++&nbsp; struct comp_unit *next_unit_without_ranges;</pre>
<pre>++</pre>
<pre>+&nbsp;&nbsp; /* Likewise, chain the compilation unit read after this one.</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The comp units are stored in reversed reading \
order.&nbsp; */</pre> <pre>+&nbsp;&nbsp; struct comp_unit *prev_unit;</pre>
<pre>+@@ -296,6 +378,10 @@ struct comp_unit</pre>
<pre>+</pre>
<pre>+&nbsp;&nbsp; /* TRUE if symbols are cached in hash table for faster lookup by \
name.&nbsp; */</pre> <pre>+&nbsp;&nbsp; bool cached;</pre>
<pre>++</pre>
<pre>++&nbsp; /* Used when iterating over trie leaves to know which units we \
have</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp; already seen in this iteration.&nbsp; \
*/</pre> <pre>++&nbsp; bool mark;</pre>
<pre>+ };</pre>
<pre>+</pre>
<pre>+ /* This data structure holds the information of an abbrev.&nbsp; */</pre>
<pre>+@@ -1766,9 +1852,189 @@ concat_filename (struct line_info_table *table, \
unsigned int file)</pre> <pre>+&nbsp;&nbsp; return strdup (filename);</pre>
<pre>+ }</pre>
<pre>+</pre>
<pre>++/* Number of bits in a bfd_vma.&nbsp; */</pre>
<pre>++#define VMA_BITS (8 * sizeof (bfd_vma))</pre>
<pre>++</pre>
<pre>++/* Check whether [low1, high1) can be combined with [low2, high2),</pre>
<pre>++&nbsp;&nbsp; i.e., they touch or overlap.&nbsp; */</pre>
<pre>++static bool ranges_overlap (bfd_vma low1,</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp; bfd_vma high1,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp; bfd_vma low2,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp; bfd_vma high2)</pre> <pre>++{</pre>
<pre>++&nbsp; if (low1 == low2 || high1 == high2)</pre>
<pre>++&nbsp;&nbsp;&nbsp; return true;</pre>
<pre>++</pre>
<pre>++&nbsp; /* Sort so that low1 is below low2. */</pre>
<pre>++&nbsp; if (low1 &gt; low2)</pre>
<pre>++&nbsp;&nbsp;&nbsp; {</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bfd_vma tmp;</pre>
<pre>++</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tmp = low1;</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; low1 = low2;</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; low2 = tmp;</pre>
<pre>++</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tmp = high1;</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; high1 = high2;</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; high2 = tmp;</pre>
<pre>++&nbsp;&nbsp;&nbsp; }</pre>
<pre>++</pre>
<pre>++&nbsp; /* We touch iff low2 == high1.</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp; We overlap iff low2 is within [low1, high1). */</pre>
<pre>++&nbsp; return (low2 &lt;= high1);</pre>
<pre>++}</pre>
<pre>++</pre>
<pre>++/* Insert an address range in the trie mapping addresses to compilation \
units.</pre> <pre>++&nbsp;&nbsp; Will return the new trie node (usually the same as \
is being sent in, but</pre> <pre>++&nbsp;&nbsp; in case of a leaf-to-interior \
conversion, or expansion of a leaf, it may be</pre> <pre>++&nbsp;&nbsp; different), \
or NULL on failure.</pre> <pre>++ */</pre>
<pre>++static struct trie_node *insert_arange_in_trie(bfd *abfd,</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct trie_node *trie,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bfd_vma trie_pc,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int trie_pc_bits,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct comp_unit *unit,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bfd_vma low_pc,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bfd_vma high_pc)</pre> <pre>++{</pre>
<pre>++&nbsp; bfd_vma clamped_low_pc, clamped_high_pc;</pre>
<pre>++&nbsp; int ch, from_ch, to_ch;</pre>
<pre>++&nbsp; bool is_full_leaf = false;</pre>
<pre>++</pre>
<pre>++&nbsp; /* See if we can extend any of the existing ranges.&nbsp; This \
merging</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp; isn't perfect (if merging opens up the \
possibility of merging two existing</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp; ranges, we \
won't find them), but it takes the majority of the cases.&nbsp; */</pre> \
<pre>++&nbsp; if (trie-&gt;num_room_in_leaf &gt; 0)</pre> <pre>++&nbsp;&nbsp;&nbsp; \
{</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct trie_leaf *leaf = (struct \
trie_leaf *) trie;</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int i;</pre>
<pre>++</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; leaf-&gt;num_stored_in_leaf; \
++i)</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; if (leaf-&gt;ranges[i].unit == \
unit &amp;&amp;</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ranges_overlap(low_pc, high_pc,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp; leaf-&gt;ranges[i].low_pc, \
leaf-&gt;ranges[i].high_pc))</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp; {</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (low_pc &lt; leaf-&gt;ranges[i].low_pc)</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
leaf-&gt;ranges[i].low_pc = low_pc;</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (high_pc &gt; leaf-&gt;ranges[i].high_pc)</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
leaf-&gt;ranges[i].high_pc = high_pc;</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return \
trie;</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre>
<pre>++</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; is_full_leaf = leaf-&gt;num_stored_in_leaf == \
trie-&gt;num_room_in_leaf;</pre> <pre>++&nbsp;&nbsp;&nbsp; }</pre>
<pre>++</pre>
<pre>++&nbsp; /* If we're a leaf with no more room and we're _not_ at the \
bottom,</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp; convert to an interior node.&nbsp; \
*/</pre> <pre>++&nbsp; if (is_full_leaf &amp;&amp; trie_pc_bits &lt; VMA_BITS)</pre>
<pre>++&nbsp;&nbsp;&nbsp; {</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const struct trie_leaf *leaf = (struct \
trie_leaf *) trie;</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int i;</pre>
<pre>++</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trie = bfd_zalloc (abfd, sizeof (struct \
trie_interior));</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!trie)</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return NULL;</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; is_full_leaf = false;</pre>
<pre>++</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* TODO: If we wanted to save a little more \
memory at the cost of</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  complexity, \
we could have reused the old leaf node as one of the</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  children of the new interior node, \
instead of throwing it away.&nbsp; */</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for \
(i = 0; i &lt; leaf-&gt;num_stored_in_leaf; ++i)</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; if (!insert_arange_in_trie (abfd, \
trie, trie_pc, trie_pc_bits,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leaf-&gt;ranges[i].unit, \
leaf-&gt;ranges[i].low_pc,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leaf-&gt;ranges[i].high_pc))</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return NULL;</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre> <pre>++&nbsp;&nbsp;&nbsp; }</pre>
<pre>++</pre>
<pre>++&nbsp; /* If we're a leaf with no more room and we _are_ at the bottom,</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp; we have no choice but to just make it larger. \
*/</pre> <pre>++&nbsp; if (is_full_leaf)</pre>
<pre>++&nbsp;&nbsp;&nbsp; {</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const struct trie_leaf *leaf = (struct \
trie_leaf *) trie;</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int \
new_room_in_leaf = trie-&gt;num_room_in_leaf * 2;</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct trie_leaf *new_leaf;</pre> <pre>++</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new_leaf = bfd_zalloc (abfd,</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sizeof (struct trie_leaf) +</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; (new_room_in_leaf - \
TRIE_LEAF_SIZE) * sizeof (leaf-&gt;ranges[0]));</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new_leaf-&gt;head.num_room_in_leaf = \
new_room_in_leaf;</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
new_leaf-&gt;num_stored_in_leaf = leaf-&gt;num_stored_in_leaf;</pre> <pre>++</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memcpy (new_leaf-&gt;ranges,</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
leaf-&gt;ranges,</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leaf-&gt;num_stored_in_leaf * sizeof \
(leaf-&gt;ranges[0]));</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trie = \
&amp;new_leaf-&gt;head;</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; is_full_leaf = \
false;</pre> <pre>++</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Now the insert below will go through.&nbsp; \
*/</pre> <pre>++&nbsp;&nbsp;&nbsp; }</pre>
<pre>++</pre>
<pre>++&nbsp; /* If we're a leaf (now with room), we can just insert at the \
end.&nbsp; */</pre> <pre>++&nbsp; if (trie-&gt;num_room_in_leaf &gt; 0)</pre>
<pre>++&nbsp;&nbsp;&nbsp; {</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct trie_leaf *leaf = (struct trie_leaf *) \
trie;</pre> <pre>++</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int i = \
leaf-&gt;num_stored_in_leaf++;</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
leaf-&gt;ranges[i].unit = unit;</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
leaf-&gt;ranges[i].low_pc = low_pc;</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
leaf-&gt;ranges[i].high_pc = high_pc;</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
return trie;</pre> <pre>++&nbsp;&nbsp;&nbsp; }</pre>
<pre>++</pre>
<pre>++&nbsp; /* Now we are definitely an interior node, so recurse into all</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp; the relevant buckets.&nbsp; */</pre>
<pre>++</pre>
<pre>++&nbsp; /* Clamp the range to the current trie bucket.&nbsp; */</pre>
<pre>++&nbsp; clamped_low_pc = low_pc;</pre>
<pre>++&nbsp; clamped_high_pc = high_pc;</pre>
<pre>++&nbsp; if (trie_pc_bits &gt; 0)</pre>
<pre>++&nbsp;&nbsp;&nbsp; {</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bfd_vma bucket_high_pc =</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; trie_pc + ((bfd_vma)-1 &gt;&gt; \
trie_pc_bits);&nbsp; /* Inclusive.&nbsp; */</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (clamped_low_pc &lt; trie_pc)</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clamped_low_pc = trie_pc;</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (clamped_high_pc &gt; bucket_high_pc)</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clamped_high_pc = bucket_high_pc;</pre> \
<pre>++&nbsp;&nbsp;&nbsp; }</pre> <pre>++</pre>
<pre>++&nbsp; /* Insert the ranges in all buckets that it spans.&nbsp; */</pre>
<pre>++&nbsp; from_ch = (clamped_low_pc &gt;&gt; (VMA_BITS - trie_pc_bits - 8)) &amp; \
0xff;</pre> <pre>++&nbsp; to_ch = ((clamped_high_pc - 1) &gt;&gt; (VMA_BITS - \
trie_pc_bits - 8)) &amp; 0xff;</pre> <pre>++&nbsp; for (ch = from_ch; ch &lt;= to_ch; \
++ch)</pre> <pre>++&nbsp;&nbsp;&nbsp; {</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct trie_interior *interior = (struct \
trie_interior *) trie;</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct trie_node \
*child = interior-&gt;children[ch];</pre> <pre>++</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (child == NULL)</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; child = alloc_trie_leaf \
(abfd);</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; if (!child)</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return NULL;</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; child = insert_arange_in_trie (abfd,</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp; child,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp; trie_pc + ((bfd_vma)ch &lt;&lt; (VMA_BITS - trie_pc_bits - \
8)),</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp; trie_pc_bits + 8,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp; unit,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp; low_pc,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp; high_pc);</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if \
(!child)</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return NULL;</pre>
<pre>++</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; interior-&gt;children[ch] = child;</pre>
<pre>++&nbsp;&nbsp;&nbsp; }</pre>
<pre>++</pre>
<pre>++&nbsp;&nbsp;&nbsp; return trie;</pre>
<pre>++}</pre>
<pre>++</pre>
<pre>++</pre>
<pre>+ static bool</pre>
<pre>+-arange_add (const struct comp_unit *unit, struct arange *first_arange,</pre>
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; bfd_vma low_pc, \
bfd_vma high_pc)</pre> <pre>++arange_add (struct comp_unit *unit, struct arange \
*first_arange,</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; \
struct trie_node **trie_root, bfd_vma low_pc, bfd_vma high_pc)</pre> <pre>+ {</pre>
<pre>+&nbsp;&nbsp; struct arange *arange;</pre>
<pre>+</pre>
<pre>+@@ -1776,6 +2042,19 @@ arange_add (const struct comp_unit *unit, struct arange \
*first_arange,</pre> <pre>+&nbsp;&nbsp; if (low_pc == high_pc)</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp; return true;</pre>
<pre>+</pre>
<pre>++&nbsp; if (trie_root != NULL)</pre>
<pre>++&nbsp;&nbsp;&nbsp; {</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *trie_root = insert_arange_in_trie \
(unit-&gt;file-&gt;bfd_ptr,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp; *trie_root,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp; 0,</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb \
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp; 0,</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb \
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp; unit,</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp; low_pc,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp; high_pc);</pre> <pre>++ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (*trie_root == \
NULL)</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;</pre>
<pre>++&nbsp;&nbsp;&nbsp; }</pre>
<pre>++</pre>
<pre>+&nbsp;&nbsp; /* If the first arange is empty, use it.&nbsp; */</pre>
<pre>+&nbsp;&nbsp; if (first_arange-&gt;high == 0)</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp; {</pre>
<pre>+@@ -2410,7 +2689,8 @@ decode_line_info (struct comp_unit *unit)</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; low_pc = \
address;</pre> <pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; if (address \
&gt; high_pc)</pre> <pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp; high_pc = address;</pre> \
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp; if (!arange_add (unit, &amp;unit-&gt;arange, low_pc, high_pc))</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp; if (!arange_add (unit, &amp;unit-&gt;arange, \
&amp;unit-&gt;file-&gt;trie_root,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp; low_pc, high_pc))</pre> <pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp; goto line_fail;</pre> \
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; break;</pre> \
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case DW_LNE_set_address:</pre> \
<pre>+@@ -3134,7 +3414,7 @@ find_abstract_instance (struct comp_unit *unit,</pre> \
<pre>+</pre> <pre>+ static bool</pre>
<pre>+ read_ranges (struct comp_unit *unit, struct arange *arange,</pre>
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; bfd_uint64_t \
offset)</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; \
struct trie_node **trie_root, bfd_uint64_t offset)</pre> <pre>+ {</pre>
<pre>+&nbsp;&nbsp; bfd_byte *ranges_ptr;</pre>
<pre>+&nbsp;&nbsp; bfd_byte *ranges_end;</pre>
<pre>+@@ -3169,7 +3449,7 @@ read_ranges (struct comp_unit *unit, struct arange \
*arange,</pre> <pre>+ base_address = high_pc;</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</pre>
<pre>+ {</pre>
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; if (!arange_add (unit, \
arange,</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; if (!arange_add \
(unit, arange, trie_root,</pre> \
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp; base_address + low_pc, base_address + high_pc))</pre> <pre>+ \
&nbsp;&nbsp;&nbsp; return false;</pre> <pre>+ }</pre>
<pre>+@@ -3179,7 +3459,7 @@ read_ranges (struct comp_unit *unit, struct arange \
*arange,</pre> <pre>+</pre>
<pre>+ static bool</pre>
<pre>+ read_rnglists (struct comp_unit *unit, struct arange *arange,</pre>
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
bfd_uint64_t offset)</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct trie_node **trie_root, bfd_uint64_t \
offset)</pre> <pre>+ {</pre>
<pre>+&nbsp;&nbsp; bfd_byte *rngs_ptr;</pre>
<pre>+&nbsp;&nbsp; bfd_byte *rngs_end;</pre>
<pre>+@@ -3253,19 +3533,19 @@ read_rnglists (struct comp_unit *unit, struct arange \
*arange,</pre> <pre>+ &nbsp; return false;</pre>
<pre>+ }</pre>
<pre>+</pre>
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!arange_add (unit, arange, low_pc, \
high_pc))</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!arange_add (unit, arange, \
trie_root, low_pc, high_pc))</pre> <pre>+ return false;</pre>
<pre>+&nbsp;&nbsp; &nbsp;&nbsp;}</pre>
<pre>+ }</pre>
<pre>+</pre>
<pre>+ static bool</pre>
<pre>+ read_rangelist (struct comp_unit *unit, struct arange *arange,</pre>
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
bfd_uint64_t offset)</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
struct trie_node **trie_root, bfd_uint64_t offset)</pre> <pre>+ {</pre>
<pre>+&nbsp;&nbsp; if (unit-&gt;version &lt;= 4)</pre>
<pre>+-&nbsp;&nbsp;&nbsp; return read_ranges (unit, arange, offset);</pre>
<pre>++&nbsp;&nbsp;&nbsp; return read_ranges (unit, arange, trie_root, offset);</pre>
<pre>+&nbsp;&nbsp; else</pre>
<pre>+-&nbsp;&nbsp;&nbsp; return read_rnglists (unit, arange, offset);</pre>
<pre>++&nbsp;&nbsp;&nbsp; return read_rnglists (unit, arange, trie_root, \
offset);</pre> <pre>+ }</pre>
<pre>+</pre>
<pre>+ static struct funcinfo *</pre>
<pre>+@@ -3563,7 +3843,8 @@ scan_unit_for_symbols (struct comp_unit *unit)</pre>
<pre>+</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case DW_AT_ranges:</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; if (is_int_form \
(&amp;attr)</pre> <pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp; !read_rangelist (unit, \
&amp;func-&gt;arange, attr.u.val))</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp; !read_rangelist (unit, \
&amp;func-&gt;arange,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp; &amp;unit-&gt;file-&gt;trie_root, attr.u.val))</pre> \
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; goto fail;</pre> \
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; break;</pre> <pre>+</pre>
<pre>+@@ -3679,7 +3960,8 @@ scan_unit_for_symbols (struct comp_unit *unit)</pre>
<pre>+</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (func &amp;&amp; high_pc != 0)</pre>
<pre>+ {</pre>
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; if (!arange_add (unit, \
&amp;func-&gt;arange, low_pc, high_pc))</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; if (!arange_add (unit, \
&amp;func-&gt;arange, &amp;unit-&gt;file-&gt;trie_root,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp; low_pc, high_pc))</pre> <pre>+ &nbsp;&nbsp;&nbsp; goto fail;</pre>
<pre>+ }</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp; }</pre>
<pre>+@@ -3874,7 +4156,8 @@ parse_comp_unit (struct dwarf2_debug *stash,</pre>
<pre>+</pre>
<pre>+ case DW_AT_ranges:</pre>
<pre>+ &nbsp; if (is_int_form (&amp;attr)</pre>
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp; \
!read_rangelist (unit, &amp;unit-&gt;arange, attr.u.val))</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp; \
!read_rangelist (unit, &amp;unit-&gt;arange,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp; &amp;unit-&gt;file-&gt;trie_root, attr.u.val))</pre> <pre>+ &nbsp;&nbsp;&nbsp; \
return NULL;</pre> <pre>+ &nbsp; break;</pre>
<pre>+</pre>
<pre>+@@ -3916,7 +4199,8 @@ parse_comp_unit (struct dwarf2_debug *stash,</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp; high_pc += low_pc;</pre>
<pre>+&nbsp;&nbsp; if (high_pc != 0)</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp; {</pre>
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!arange_add (unit, &amp;unit-&gt;arange, \
low_pc, high_pc))</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!arange_add (unit, \
&amp;unit-&gt;arange, &amp;unit-&gt;file-&gt;trie_root,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; low_pc, high_pc))</pre> <pre>+ return \
NULL;</pre> <pre>+&nbsp;&nbsp;&nbsp;&nbsp; }</pre>
<pre>+</pre>
<pre>+@@ -4747,6 +5031,14 @@ _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd \
*debug_bfd,</pre> <pre>+&nbsp;&nbsp; if (!stash-&gt;alt.abbrev_offsets)</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp; return false;</pre>
<pre>+</pre>
<pre>++&nbsp; stash-&gt;f.trie_root = alloc_trie_leaf (abfd);</pre>
<pre>++&nbsp; if (!stash-&gt;f.trie_root)</pre>
<pre>++&nbsp;&nbsp;&nbsp; return false;</pre>
<pre>++</pre>
<pre>++&nbsp; stash-&gt;alt.trie_root = alloc_trie_leaf (abfd);</pre>
<pre>++&nbsp; if (!stash-&gt;alt.trie_root)</pre>
<pre>++&nbsp;&nbsp;&nbsp; return false;</pre>
<pre>++</pre>
<pre>+&nbsp;&nbsp; *pinfo = stash;</pre>
<pre>+</pre>
<pre>+&nbsp;&nbsp; if (debug_bfd == NULL)</pre>
<pre>+@@ -4918,6 +5210,12 @@ stash_comp_unit (struct dwarf2_debug *stash, struct \
dwarf2_debug_file *file)</pre> <pre>+ &nbsp; each-&gt;next_unit = \
file-&gt;all_comp_units;</pre> <pre>+ &nbsp; file-&gt;all_comp_units = each;</pre>
<pre>+</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; if (each-&gt;arange.high == \
0)</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
each-&gt;next_unit_without_ranges = file-&gt;all_comp_units_without_ranges;</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
file-&gt;all_comp_units_without_ranges = each-&gt;next_unit_without_ranges;</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</pre> <pre>++</pre>
<pre>+ &nbsp; file-&gt;info_ptr += length;</pre>
<pre>+ &nbsp; return each;</pre>
<pre>+ }</pre>
<pre>diff --git a/meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-2.patch \
b/meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-2.patch</pre> <pre>new \
file mode 100644</pre> <pre>index 0000000000..8ffb500c1d</pre>
<pre>--- /dev/null</pre>
<pre>+++ b/meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-2.patch</pre>
<pre>@@ -0,0 +1,211 @@</pre>
<pre>+From 73e97e32e1428d63d81d971176772ae69397a1a0 Mon Sep 17 00:00:00 2001</pre>
<pre>+From: Nick Clifton <a \
href="mailto:nickc@redhat.com">&lt;nickc@redhat.com&gt;</a></pre> <pre>+Date: Tue, 30 \
Aug 2022 16:01:20 +0100</pre> <pre>+Subject: [PATCH] BFD library: Use entry 0 in \
directory and filename tables of</pre> <pre>+ DWARF-5 debug info.</pre>
<pre>+</pre>
<pre>+ PR 29529</pre>
<pre>+ * dwarf2.c (struct line_info_table): Add new field:</pre>
<pre>+ use_dir_and_file_0.</pre>
<pre>+ (concat_filename): Use new field to help select the correct table</pre>
<pre>+ slot.</pre>
<pre>+ (read_formatted_entries): Do not skip entry 0.</pre>
<pre>+ (decode_line_info): Set new field depending upon the version of</pre>
<pre>+ DWARF being parsed.&nbsp; Initialise filename based upon the setting of</pre>
<pre>+ the new field.</pre>
<pre>+</pre>
<pre>+Upstream-Status: Backport [<a \
href="https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=37833b966576c5d25e \
797ea3b6c33d0459a71892">https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=37833b966576c5d25e797ea3b6c33d0459a71892</a>]</pre>
 <pre>+CVE: CVE-2023-22608</pre>
<pre>+</pre>
<pre>+Signed-off-by: Yash Shinde <a \
href="mailto:Yash.Shinde@windriver.com">&lt;Yash.Shinde@windriver.com&gt;</a></pre> \
<pre>+</pre> <pre>+---</pre>
<pre>+ bfd/ChangeLog&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
| 12 +++++</pre> <pre>+ \
bfd/dwarf2.c&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
| 86 ++++++++++++++++++++----------</pre> <pre>+ \
ld/ChangeLog&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp; 5 ++</pre> <pre>+ ld/testsuite/ld-x86-64/pr27587.err \
|&nbsp; 2 +-</pre> <pre>+ 4 files changed, 76 insertions(+), 29 deletions(-)</pre>
<pre>+</pre>
<pre>+diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c</pre>
<pre>+index 0ae50a37..b7839ad6 100644</pre>
<pre>+--- a/bfd/dwarf2.c</pre>
<pre>++++ b/bfd/dwarf2.c</pre>
<pre>+@@ -1571,6 +1571,7 @@ struct line_info_table</pre>
<pre>+&nbsp;&nbsp; unsigned int&nbsp;&nbsp;&nbsp; num_files;</pre>
<pre>+&nbsp;&nbsp; unsigned int&nbsp;&nbsp;&nbsp; num_dirs;</pre>
<pre>+&nbsp;&nbsp; unsigned int&nbsp;&nbsp;&nbsp; num_sequences;</pre>
<pre>++&nbsp; bool&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
use_dir_and_file_0;</pre> <pre>+&nbsp;&nbsp; char \
*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; comp_dir;</pre> \
<pre>+&nbsp;&nbsp; char **&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
dirs;</pre> <pre>+&nbsp;&nbsp; struct fileinfo*&nbsp;&nbsp; files;</pre>
<pre>+@@ -1791,16 +1792,30 @@ concat_filename (struct line_info_table *table, \
unsigned int file)</pre> <pre>+ {</pre>
<pre>+&nbsp;&nbsp; char *filename;</pre>
<pre>+</pre>
<pre>+-&nbsp; if (table == NULL || file - 1 &gt;= table-&gt;num_files)</pre>
<pre>++&nbsp; /* Pre DWARF-5 entry 0 in the directory and filename tables was not \
used.</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp; So in order to save space in the tables \
used here the info for, eg</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp; directory 1 is \
stored in slot 0 of the directory table, directory 2</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp; in slot 1 and so on.</pre> <pre>++</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp; Starting with DWARF-5 the 0'th entry is used so there \
is a one to one</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp; mapping between DWARF slots and \
internal table entries.&nbsp; */</pre> <pre>++&nbsp; if (! \
table-&gt;use_dir_and_file_0)</pre> <pre>+&nbsp;&nbsp;&nbsp;&nbsp; {</pre>
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* FILE == 0 means unknown.&nbsp; */</pre>
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (file)</pre>
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _bfd_error_handler</pre>
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; (_(&quot;DWARF error: mangled line \
number section (bad file number)&quot;));</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
/* Pre DWARF-5, FILE == 0 means unknown.&nbsp; */</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (file == 0)</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return strdup \
(&quot;&lt;unknown&gt;&quot;);</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- \
file;</pre> <pre>++&nbsp;&nbsp;&nbsp; }</pre>
<pre>++</pre>
<pre>++&nbsp; if (table == NULL || file &gt;= table-&gt;num_files)</pre>
<pre>++&nbsp;&nbsp;&nbsp; {</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _bfd_error_handler</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (_(&quot;DWARF error: mangled line number \
section (bad file number)&quot;));</pre> <pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
return strdup (&quot;&lt;unknown&gt;&quot;);</pre> <pre>+&nbsp;&nbsp;&nbsp;&nbsp; \
}</pre> <pre>+</pre>
<pre>+-&nbsp; filename = table-&gt;files[file - 1].name;</pre>
<pre>++&nbsp; filename = table-&gt;files[file].name;</pre>
<pre>++</pre>
<pre>+&nbsp;&nbsp; if (filename == NULL)</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp; return strdup (&quot;&lt;unknown&gt;&quot;);</pre>
<pre>+</pre>
<pre>+@@ -1811,12 +1826,17 @@ concat_filename (struct line_info_table *table, \
unsigned int file)</pre> <pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char *name;</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; size_t len;</pre>
<pre>+</pre>
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (table-&gt;files[file - 1].dir</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (table-&gt;files[file].dir</pre>
<pre>+ &nbsp; /* PR 17512: file: 0317e960.&nbsp; */</pre>
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &amp;&amp; table-&gt;files[file - \
1].dir &lt;= table-&gt;num_dirs</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp; &amp;&amp; table-&gt;files[file].dir &lt;= table-&gt;num_dirs</pre> <pre>+ \
&nbsp; /* PR 17512: file: 7f3d2e4b.&nbsp; */</pre> <pre>+ &nbsp; &amp;&amp; \
table-&gt;dirs != NULL)</pre> <pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; subdir_name \
= table-&gt;dirs[table-&gt;files[file - 1].dir - 1];</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; if \
(table-&gt;use_dir_and_file_0)</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp; subdir_name = table-&gt;dirs[table-&gt;files[file].dir];</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; else</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; subdir_name = \
table-&gt;dirs[table-&gt;files[file].dir - 1];</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre> <pre>+</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!subdir_name || !IS_ABSOLUTE_PATH \
(subdir_name))</pre> <pre>+ dir_name = table-&gt;comp_dir;</pre>
<pre>+@@ -1857,10 +1877,12 @@ concat_filename (struct line_info_table *table, \
unsigned int file)</pre> <pre>+</pre>
<pre>+ /* Check whether [low1, high1) can be combined with [low2, high2),</pre>
<pre>+&nbsp;&nbsp;&nbsp; i.e., they touch or overlap.&nbsp; */</pre>
<pre>+-static bool ranges_overlap (bfd_vma low1,</pre>
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp; bfd_vma high1,</pre> \
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp; bfd_vma low2,</pre> \
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp; bfd_vma high2)</pre> <pre>++</pre>
<pre>++static bool</pre>
<pre>++ranges_overlap (bfd_vma low1,</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
bfd_vma high1,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
bfd_vma low2,</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
bfd_vma high2)</pre> <pre>+ {</pre>
<pre>+&nbsp;&nbsp; if (low1 == low2 || high1 == high2)</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp; return true;</pre>
<pre>+@@ -1887,15 +1909,16 @@ static bool ranges_overlap (bfd_vma low1,</pre>
<pre>+ /* Insert an address range in the trie mapping addresses to compilation \
units.</pre> <pre>+&nbsp;&nbsp;&nbsp; Will return the new trie node (usually the same \
as is being sent in, but</pre> <pre>+&nbsp;&nbsp;&nbsp; in case of a leaf-to-interior \
conversion, or expansion of a leaf, it may be</pre> <pre>+-&nbsp;&nbsp; different), \
or NULL on failure.</pre> <pre>+- */</pre>
<pre>+-static struct trie_node *insert_arange_in_trie(bfd *abfd,</pre>
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct trie_node *trie,</pre> \
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bfd_vma trie_pc,</pre> \
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int trie_pc_bits,</pre> \
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct comp_unit *unit,</pre> \
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bfd_vma low_pc,</pre> \
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bfd_vma high_pc)</pre> <pre>++&nbsp;&nbsp; \
different), or NULL on failure.&nbsp; */</pre> <pre>++</pre>
<pre>++static struct trie_node *</pre>
<pre>++insert_arange_in_trie (bfd *abfd,</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct trie_node *trie,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bfd_vma trie_pc,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int trie_pc_bits,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct comp_unit *unit,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bfd_vma low_pc,</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bfd_vma high_pc)</pre> <pre>+ {</pre>
<pre>+&nbsp;&nbsp; bfd_vma clamped_low_pc, clamped_high_pc;</pre>
<pre>+&nbsp;&nbsp; int ch, from_ch, to_ch;</pre>
<pre>+@@ -2031,7 +2054,6 @@ static struct trie_node *insert_arange_in_trie(bfd \
*abfd,</pre> <pre>+&nbsp;&nbsp;&nbsp;&nbsp; return trie;</pre>
<pre>+ }</pre>
<pre>+</pre>
<pre>+-</pre>
<pre>+ static bool</pre>
<pre>+ arange_add (struct comp_unit *unit, struct arange *first_arange,</pre>
<pre>+ &nbsp;&nbsp;&nbsp; struct trie_node **trie_root, bfd_vma low_pc, bfd_vma \
high_pc)</pre> <pre>+@@ -2412,10 +2434,8 @@ read_formatted_entries (struct comp_unit \
*unit, bfd_byte **bufp,</pre> <pre>+ &nbsp;&nbsp;&nbsp; }</pre>
<pre>+ }</pre>
<pre>+</pre>
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Skip the first &quot;zero entry&quot;, which \
is the compilation dir/file.&nbsp; */</pre> <pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if \
(datai != 0)</pre> <pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!callback (table, \
fe.name, fe.dir, fe.time, fe.size))</pre> <pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp; return false;</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!callback \
(table, fe.name, fe.dir, fe.time, fe.size))</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;</pre> \
<pre>+&nbsp;&nbsp;&nbsp;&nbsp; }</pre> <pre>+</pre>
<pre>+&nbsp;&nbsp; *bufp = buf;</pre>
<pre>+@@ -2592,6 +2612,7 @@ decode_line_info (struct comp_unit *unit)</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!read_formatted_entries (unit, \
&amp;line_ptr, line_end, table,</pre> \
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp; line_info_add_file_name))</pre> <pre>+ goto fail;</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; table-&gt;use_dir_and_file_0 = true;</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp; }</pre>
<pre>+&nbsp;&nbsp; else</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp; {</pre>
<pre>+@@ -2614,6 +2635,7 @@ decode_line_info (struct comp_unit *unit)</pre>
<pre>+ &nbsp; if (!line_info_add_file_name (table, cur_file, dir, xtime, size))</pre>
<pre>+ &nbsp;&nbsp;&nbsp; goto fail;</pre>
<pre>+ }</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; table-&gt;use_dir_and_file_0 = false;</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp; }</pre>
<pre>+</pre>
<pre>+&nbsp;&nbsp; /* Read the statement sequences until there's nothing left.&nbsp; \
*/</pre> <pre>+@@ -2622,7 +2644,7 @@ decode_line_info (struct comp_unit *unit)</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* State machine registers.&nbsp; */</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bfd_vma address = 0;</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned char op_index = 0;</pre>
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char * filename = table-&gt;num_files ? \
concat_filename (table, 1) : NULL;</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char * \
filename = NULL;</pre> <pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int line = \
1;</pre> <pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int column = 0;</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int discriminator = 0;</pre>
<pre>+@@ -2637,6 +2659,14 @@ decode_line_info (struct comp_unit *unit)</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bfd_vma low_pc&nbsp; = (bfd_vma) -1;</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bfd_vma high_pc = 0;</pre>
<pre>+</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (table-&gt;num_files)</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</pre>
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; if \
(table-&gt;use_dir_and_file_0)</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \
&nbsp;&nbsp;&nbsp; filename = concat_filename (table, 0);</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; else</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; filename = \
concat_filename (table, 1);</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</pre>
<pre>++</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Decode the table.&nbsp; */</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (!end_sequence &amp;&amp; line_ptr \
&lt; line_end)</pre> <pre>+ {</pre>
<pre>+diff --git a/ld/testsuite/ld-x86-64/pr27587.err \
b/ld/testsuite/ld-x86-64/pr27587.err</pre> <pre>+index fa870790..807750ca \
100644</pre> <pre>+--- a/ld/testsuite/ld-x86-64/pr27587.err</pre>
<pre>++++ b/ld/testsuite/ld-x86-64/pr27587.err</pre>
<pre>+@@ -1,3 +1,3 @@</pre>
<pre>+ #...</pre>
<pre>+-.*pr27587.i:4: undefined reference to `stack_size'</pre>
<pre>++.*pr27587/&lt;artificial&gt;:4: undefined reference to `stack_size'</pre>
<pre>+ #...</pre>
<pre>diff --git a/meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-3.patch \
b/meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-3.patch</pre> <pre>new \
file mode 100644</pre> <pre>index 0000000000..603824155b</pre>
<pre>--- /dev/null</pre>
<pre>+++ b/meta/recipes-devtools/binutils/binutils/0020-CVE-2023-22608-3.patch</pre>
<pre>@@ -0,0 +1,33 @@</pre>
<pre>+From 20c75f063a999f9e849a77613a82b15de78ea45f Mon Sep 17 00:00:00 2001</pre>
<pre>+From: Nick Clifton <a \
href="mailto:nickc@redhat.com">&lt;nickc@redhat.com&gt;</a></pre> <pre>+Date: Fri, 23 \
Dec 2022 13:02:04 +0000</pre> <pre>+Subject: [PATCH] Fix illegal memory access \
parsing corrupt DWARF information.</pre> <pre>+</pre>
<pre>+ PR 29936</pre>
<pre>+ * dwarf2.c (concat_filename): Fix check for a directory index off</pre>
<pre>+ the end of the directory table.</pre>
<pre>+</pre>
<pre>+Upstream-Status: Backport [<a \
href="https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=8af23b30edbaedf009 \
bc9b243cd4dfa10ae1ac09">https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=8af23b30edbaedf009bc9b243cd4dfa10ae1ac09</a>]</pre>
 <pre>+CVE: CVE-2023-22608</pre>
<pre>+</pre>
<pre>+Signed-off-by: Yash Shinde <a \
href="mailto:Yash.Shinde@windriver.com">&lt;Yash.Shinde@windriver.com&gt;</a></pre> \
<pre>+</pre> <pre>+---</pre>
<pre>+ bfd/ChangeLog | 6 ++++++</pre>
<pre>+ bfd/dwarf2.c&nbsp; | 3 ++-</pre>
<pre>+ 2 files changed, 8 insertions(+), 1 deletion(-)</pre>
<pre>+</pre>
<pre>+diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c</pre>
<pre>+index b7839ad6..8b07a24c 100644</pre>
<pre>+--- a/bfd/dwarf2.c</pre>
<pre>++++ b/bfd/dwarf2.c</pre>
<pre>+@@ -1828,7 +1828,8 @@ concat_filename (struct line_info_table *table, unsigned \
int file)</pre> <pre>+</pre>
<pre>+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (table-&gt;files[file].dir</pre>
<pre>+ &nbsp; /* PR 17512: file: 0317e960.&nbsp; */</pre>
<pre>+-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &amp;&amp; \
table-&gt;files[file].dir &lt;= table-&gt;num_dirs</pre> \
<pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &amp;&amp; \
table-&gt;files[file].dir</pre> <pre>++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; \
&lt;= (table-&gt;use_dir_and_file_0 ? table-&gt;num_dirs - 1 : \
table-&gt;num_dirs)</pre> <pre>+ &nbsp; /* PR 17512: file: 7f3d2e4b.&nbsp; */</pre>
<pre>+ &nbsp; &amp;&amp; table-&gt;dirs != NULL)</pre>
<pre>+ {</pre>
</blockquote>
<p><o:p>&nbsp;</o:p></p>
<pre>-- </pre>
<pre># Randy MacLeod</pre>
<pre># Wind River Linux</pre>
<p class="MsoNormal"><span style="font-size:10.0pt;font-family:&quot;Courier \
New&quot;"><o:p>&nbsp;</o:p></span></p> </div>
</body>
</html>



-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#177818): https://lists.openembedded.org/g/openembedded-core/message/177818
Mute This Topic: https://lists.openembedded.org/mt/97242671/4454766
Group Owner: openembedded-core+owner@lists.openembedded.org
Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [openembedded-core@marc.info]
-=-=-=-=-=-=-=-=-=-=-=-


--VZ2G4nVkF2cFL13gc4uI--

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic