SOURCES: binutils-pr-5755.patch (NEW) - fix for upstream bug 5755
arekm
arekm at pld-linux.org
Sat Feb 16 21:48:21 CET 2008
Author: arekm Date: Sat Feb 16 20:48:21 2008 GMT
Module: SOURCES Tag: HEAD
---- Log message:
- fix for upstream bug 5755
---- Files affected:
SOURCES:
binutils-pr-5755.patch (NONE -> 1.1) (NEW)
---- Diffs:
================================================================
Index: SOURCES/binutils-pr-5755.patch
diff -u /dev/null SOURCES/binutils-pr-5755.patch:1.1
--- /dev/null Sat Feb 16 21:48:21 2008
+++ SOURCES/binutils-pr-5755.patch Sat Feb 16 21:48:15 2008
@@ -0,0 +1,1572 @@
+diff -urN binutils-2.18.50.0.4.org/bfd/arange-set.c binutils-2.18.50.0.4/bfd/arange-set.c
+--- binutils-2.18.50.0.4.org/bfd/arange-set.c 2008-02-08 17:44:56.000000000 +0100
++++ binutils-2.18.50.0.4/bfd/arange-set.c 1970-01-01 01:00:00.000000000 +0100
+@@ -1,737 +0,0 @@
+-/* DWARF 2 Arange-Set.
+- Copyright 2007 Free Software Foundation, Inc.
+- Contributed by Doug Kwan, Google Inc.
+-
+- This file is part of BFD.
+-
+- This program is free software; you can redistribute it and/or modify
+- it under the terms of the GNU General Public License as published by
+- the Free Software Foundation; either version 3 of the License, or (at
+- your option) any later version.
+-
+- This program is distributed in the hope that it will be useful, but
+- WITHOUT ANY WARRANTY; without even the implied warranty of
+- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+- General Public License for more details.
+-
+- You should have received a copy of the GNU General Public License
+- along with this program; if not, write to the Free Software
+- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+- MA 02110-1301, USA. */
+-
+-#include "sysdep.h"
+-#include "bfd.h"
+-#include "libiberty.h"
+-#include "libbfd.h"
+-#include "arange-set.h"
+-#include "splay-tree.h"
+-
+-/* Implementation of an arange-set. The set is implemented using the
+- splay tree support in libiberty. The advantage of using this is
+- that it has been well tested and is relatively simple to use. The
+- disadvantage is that it is too general and it does not fit our design
+- exactly. So we waste a bit of memory for unneeded generality and work
+- around for mis-match between the splay tree API and the arange-set
+- internals. A specialized implentation of a balanced tree type for
+- arange-set exclusively may speed up things a little and reduce memory
+- consumption. Until there is a pressing need, we stick to the splay
+- tree in libiberty. */
+-
+-struct arange_set_s
+-{
+- /* Splay tree containing aranges. */
+- splay_tree ranges;
+-
+- /* Lowest address in set. If set is empty, it is ~0. */
+- bfd_vma lower_bound;
+-
+- /* Highest address in set. If set is empty, it is 0. */
+- bfd_vma upper_bound;
+-
+- /* TRUE if aranges in this set have values. */
+- bfd_boolean value_p;
+-
+- /* Function to compare arange values. */
+- arange_value_equal_fn value_equal_fn;
+-
+- /* Function to copy an arange value. */
+- arange_value_copy_fn value_copy_fn;
+-
+- /* Function to combine arange values. */
+- arange_value_combine_fn value_combine_fn;
+-
+- /* Function to delete an arange value. */
+- arange_value_delete_fn value_delete_fn;
+-
+- /* Function to allocate a piece of memory. */
+- arange_set_allocate_fn allocate_fn;
+-
+- /* Function to deallocate a piece of memory. */
+- arange_set_deallocate_fn deallocate_fn;
+-
+- /* Call back data shared by all callbacks. */
+- void *data;
+-};
+-
+-/* Structure for aranges with a value attached. Since a splay tree
+- node can only hold one value, we need to use the container struct
+- to store data associated with an arange and have the splay tree value
+- to be a pointer to this struct. */
+-
+-typedef struct
+-{
+- /* High-pc of an arange. This is different from the DWARF2 semantics that
+- the high-pc is really the last location in an arange. */
+- bfd_vma high;
+-
+- /* We need to store a pointer to the set because splay_tree_value_delete
+- only takes a pointer to the value deleted. If we use a deallocator
+- that need extra information like a pointer to the memory pool, we need to
+- look up via the set pointer. This adds one extra pointer per arange. */
+- arange_set set;
+-
+- /* Value associated with this arange. */
+- arange_value_type value;
+-
+-} arange_value_container_t;
+-
+-
+-
+-static void
+-arange_set_delete_value (arange_set set, arange_value_type value)
+-{
+- if (set->value_delete_fn)
+- (set->value_delete_fn) (value, set->data);
+-}
+-
+-/* Compare two VMAs as keys of splay tree nodes. */
+-
+-static int
+-splay_tree_compare_bfd_vmas (splay_tree_key k1, splay_tree_key k2)
+-{
+- if ((bfd_vma) k1 < (bfd_vma) k2)
+- return -1;
+- else if ((bfd_vma) k1 > (bfd_vma) k2)
+- return 1;
+-
+- return 0;
+-}
+-
+-/* Default memory allocator and deallocator. */
+-
+-void *
+-arange_set_allocate (arange_set set, int size)
+-{
+- if (set->allocate_fn)
+- return (set->allocate_fn) (size, set->data);
+-
+- return xmalloc (size);
+-}
+-
+-void
+-arange_set_deallocate (arange_set set, void *object)
+-{
+- if (set->deallocate_fn)
+- (set->deallocate_fn) (object, set->data);
+- else
+- free (object);
+-}
+-
+-static void
+-arange_set_delete_value_container (splay_tree_value value)
+-{
+- arange_value_container_t *container;
+-
+- container = (arange_value_container_t*) value;
+- arange_set_delete_value (container->set, container->value);
+- arange_set_deallocate (container->set, container);
+-}
+-
+-/* Create an arange set. Return the new set of NULL if there is any
+- error.
+-
+- allocate_fn is the memory allocator function of this arange set. If
+- it is NULL, the default allocator will be used.
+-
+- deallocate_fn is the memory deallocator function of this arange set. If
+- it is NULL, the default allocator will be used.
+-
+- value_p specifies whether an arange set supports values. If it is
+- TURE. Each arange can be associated with a value of type arange_value_type.
+- If it is FALSE, the following parameters value_equal_fn, value_copy_fn,
+- value_combine_fn and value_delete_fn will be ignored.
+-
+- value_equal_fn is the value equality function. An arange uses it to
+- check if two values are the same. If it is NULL, the default bit-wise
+- equality function will be used.
+-
+- value_copy_fn is the value copy function. An arange uses it to copy
+- values of type arange_value_type. If it is NULL, the default bit-wise
+- copy function will be used.
+-
+- value_combine_fn is the value combine function. An arange uses it to
+- combine values of two identical arange. If it is NULL, the default
+- constant zero function will be used.
+-
+- value_delete_fn is the value deletion function. If it is not NULL,
+- it will be called when an arange deletes a value.
+-
+- data is pointer to an object, which will be passed to all allocate_fn,
+- deallocate_fn, value_equal_fn, value_copy_fn, value_combine_fn and
+- value_delete_fn. */
+-
+-arange_set
+-arange_set_new (arange_set_allocate_fn allocate_fn,
+- arange_set_deallocate_fn deallocate_fn,
+- bfd_boolean value_p,
+- arange_value_equal_fn value_equal_fn,
+- arange_value_copy_fn value_copy_fn,
+- arange_value_combine_fn value_combine_fn,
+- arange_value_delete_fn value_delete_fn,
+- void *data)
+-{
+- arange_set set;
+- splay_tree sp;
+- splay_tree_delete_value_fn fn;
+-
+- if (sizeof (bfd_vma) > sizeof (splay_tree_key)
+- || sizeof (bfd_vma) > sizeof (splay_tree_value))
+- {
+- (*_bfd_error_handler)
+- (_("size of bfd_vma > size of splay_tree types"));
+- abort ();
+- }
+-
+- /* Allocate space for arange structure. */
+- set = (arange_set)
+- (*allocate_fn) (sizeof (struct arange_set_s), data);
+- if (!set)
+- return set;
+-
+- fn = value_p ? arange_set_delete_value_container : NULL;
+- sp = splay_tree_new_with_allocator (splay_tree_compare_bfd_vmas, NULL,
+- fn, allocate_fn, deallocate_fn,
+- data);
+- if (!sp)
+- {
+- (deallocate_fn) (set, data);
+- return NULL;
+- }
+-
+- set->ranges = sp;
+- set->lower_bound = ~0;
+- set->upper_bound = 0;
+- set->value_p = value_p;
+- set->allocate_fn = allocate_fn;
+- set->deallocate_fn = deallocate_fn;
+- set->value_equal_fn = value_equal_fn;
+- set->value_copy_fn = value_copy_fn;
+- set->value_combine_fn = value_combine_fn;
+- set->value_delete_fn = value_delete_fn;
+- set->data = data;
+- return set;
+-}
+-
+-/* Delete an arange set. */
+-
+-void
+-arange_set_delete (arange_set set)
+-{
+- splay_tree_delete (set->ranges);
+- (*set->deallocate_fn) (set, set->data);
+-}
+-
+-/* Return TRUE if and only if arange set is empty. */
+-
+-bfd_boolean
+-arange_set_empty_p (arange_set set)
+-{
+- return set->lower_bound > set->upper_bound;
+-}
+-
+-/* Accessors for low and high of an arange.
+-
+- There is no arange_set_node_set_low since the low address is the
+- key of the splay tree node. */
+-
+-/* Get the high VMA address of a node. */
+-
+-static bfd_vma
+-arange_set_node_high (arange_set set, splay_tree_node node)
+-{
+- arange_value_container_t *container;
+-
+- if (set->value_p)
+- {
+- container = (arange_value_container_t*) node->value;
+- return container->high;
+- }
+-
+- return (bfd_vma) node->value;
+-}
+-
+-/* Set the high VMA address of a node. */
+-
+-static void
+-arange_set_node_set_high (arange_set set, splay_tree_node node, bfd_vma address)
+-{
+- arange_value_container_t *container;
+-
+- if (set->value_p)
+- {
+- container = (arange_value_container_t*) node->value;
+- container->high = address;
+- }
+- else
+- node->value = (splay_tree_value) address;
+-}
+-
+-/* Get the low VMA address of a node. */
+-
+-static bfd_vma
+-arange_set_node_low (splay_tree_node node)
+-{
+- return (bfd_vma) node->key;
+-}
+-
+-/* If arange set supports values, return value of an arange; otheriwse
+- always return 0 so that it appears that all aranges have the same value. */
+-
+-static arange_value_type
+-arange_set_node_value (arange_set set, splay_tree_node node)
+-{
+- arange_value_container_t *container;
+-
+- if (set->value_p)
+- {
+- container = (arange_value_container_t*) node->value;
+- return container->value;
+- }
+-
+- return 0;
+-}
+-
+-/* If arange set supports values, return value of an arange; otheriwse
+- always return 0 so that it appears that all aranges have the same value. */
+-
+-static void
+-arange_set_node_set_value (arange_set set,
+- splay_tree_node node,
+- arange_value_type value)
+-{
+- arange_value_container_t *container;
+-
+- if (set->value_p)
+- {
+- container = (arange_value_container_t*) node->value;
+- container->value = value;
+- }
+-}
+-
+-/* Return TRUE if and only if arange set supports values. */
+-
+-bfd_boolean
+-arange_set_has_values_p (arange_set set)
+-{
+- return set->value_p;
+-}
+-
+-/* Copy a value using the value copying function of an arange set. If
+- the set does not support values or if there is not value copying
+- function specified, it simply returns the input value. */
+-
+-arange_value_type
+-arange_set_copy_value (arange_set set, arange_value_type value)
+-{
+- /* If no copy function is specified or set does not support values,
+- default is bit-wise copy. */
+- if (set->value_p && set->value_copy_fn)
+- return (set->value_copy_fn) (value, set->data);
+-
+- return value;
+-}
+-
+-static arange_value_type
+-arange_set_combine_value (arange_set set,
+- arange_value_type value1,
+- arange_value_type value2)
+-{
+- /* If no combine function is specified or set does not support values,
+- default is returning 0. */
+- if (set->value_p && set->value_combine_fn)
+- return (set->value_combine_fn) (value1, value2, set->data);
+-
+- return (arange_value_type) 0;
+-}
+-
+-/* Compares two values for equality. If the arange set does not support values
+- or if no value equality function is specified, this function simply does
+- a bit-wise comparison. */
+-
+-bfd_boolean
+-arange_set_value_equal_p (arange_set set,
+- arange_value_type value1,
+- arange_value_type value2)
+-{
+- /* If no equality function is specified or set does not support values,
+- default is bit-wise comparison. */
+- if (set->value_p && set->value_equal_fn)
+- return (set->value_equal_fn) (value1, value2, set->data);
+-
+- return value1 == value2;
+-}
+-
+-/* Check to see if a given address is in an arange set. Return TRUE if the
+- address is inside one of the aranges. If low_ptr, high_ptr and value_ptr are
+- used to return lower address, upper address and value associated with a
+- found arounge. If anyone of them is NULL, the corresponding information
+- is not returned. For arange set without values, no information is returned
+- through the pointer value_ptr. */
+-
+-bfd_boolean
+-arange_set_lookup_address (arange_set set, bfd_vma address,
+- bfd_vma *low_ptr, bfd_vma *high_ptr,
+- arange_value_type *value_ptr)
+-{
+- splay_tree_node pred, node;
+-
+- if (address < set->lower_bound || address > set->upper_bound)
+- return FALSE;
+-
+- /* Find immediate predecessor. */
+- pred = splay_tree_predecessor (set->ranges, (splay_tree_key) address);
+- if (pred
+- && arange_set_node_high (set, pred) >= address)
+- node = pred;
+- else
+- /* If the predecessor range does not cover this address, the address
+- is in the arange set only if itself starts an arange. */
+- node = splay_tree_lookup (set->ranges, (splay_tree_key) address);
+-
+- if (node)
+- {
+- /* Also return arange boundaries if caller supplies pointers. */
+- if (low_ptr)
+- *low_ptr = arange_set_node_low (node);
+- if (high_ptr)
+- *high_ptr = arange_set_node_high (set, node);
+- if (set->value_p && value_ptr)
+- *value_ptr = arange_set_node_value (set, node);
+- return TRUE;
+- }
+-
+- return FALSE;
+-}
+-
+-/* Insert an arange [low, high] into a set's splay tree. If the set supports
+- value, also insert with the given value. Return the inserted node if there
+- is no error or NULL otherwise. */
+-
+-static splay_tree_node
+-arange_set_splay_tree_insert (arange_set set,
+- bfd_vma low,
+- bfd_vma high,
+- arange_value_type value)
+-{
+- splay_tree_value sp_value;
+- arange_value_container_t *container;
+-
+- if (set->value_p)
+- {
+- int size = sizeof (arange_value_container_t);
+- void *data = set->ranges->allocate_data;
+-
+- container =
+- (arange_value_container_t*) (*set->ranges->allocate) (size, data);
+- if (!container)
+- return NULL;
+- container->high = high;
+-
+- /* Due to the design of splay tree API, there is no way of passing
+- callback data to the splay tree value delete function. Hence we need
+- to store a pointer to set in every containier! */
+- container->set = set;
+-
+- container->value = value;
+- sp_value = (splay_tree_value) container;
+- }
+- else
+- sp_value = (splay_tree_value) high;
+-
+- /* Currently splay_tree_insert does not return any status to tell if there
+- is an error. */
+- return splay_tree_insert (set->ranges, (splay_tree_key) low, sp_value);
+-}
+-
+-/* Split [low, high] to [low, address) & [address, high]. */
+-
+-static bfd_boolean
+-arange_set_split_node (arange_set set, splay_tree_node node, bfd_vma address)
+-{
+- splay_tree_node node2;
+- arange_value_type value;
+- bfd_vma low, high;
+-
+- low = arange_set_node_low (node);
+- high = arange_set_node_high (set, node);
+-
+- BFD_ASSERT (low < address && address <= high);
+-
+- value = arange_set_copy_value (set, arange_set_node_value (set, node));
+- node2 = arange_set_splay_tree_insert (set, address, high, value);
+- if (!node2)
+- return FALSE;
+-
+- arange_set_node_set_high (set, node, address - 1);
+- return TRUE;
+-}
+-
+-static splay_tree_node
+-arange_set_maybe_merge_with_predecessor (arange_set set, splay_tree_node node)
+-{
+- splay_tree_node pred;
+- bfd_vma low, high;
+-
+- low = arange_set_node_low (node);
+- high = arange_set_node_high (set, node);
+-
+- pred = splay_tree_predecessor (set->ranges, low);
+- if (! pred)
+- return node;
+-
+- if (arange_set_node_high (set, pred) + 1 == low
+- && arange_set_value_equal_p (set,
+- arange_set_node_value (set, pred),
+- arange_set_node_value (set, node)))
+- {
+- splay_tree_remove (set->ranges, arange_set_node_low (node));
+- arange_set_node_set_high (set, pred, high);
+- return arange_set_maybe_merge_with_predecessor (set, pred);
+- }
+-
+- return node;
+-}
+-
+-/* Insert an arange [low,high] into a set. Return TRUE if and only if there
+- is no error. Note that the address high is also included where as in
+- DWARF2 an address range between low & high means [low,high).
+-
+- This only handles sets with values. For the simpler case of sets without
+- value, it is handled in arange_set_insert(). This function is
+- tail-recurive. It is guaranteed to terminate because it only recurses
+- with a smaller range than it is given. */
+-
+-static bfd_boolean
+-arange_set_insert_value (arange_set set,
+- bfd_vma low,
+- bfd_vma high,
+- arange_value_type value)
+-{
+- splay_tree_node succ, pred, node;
+- bfd_vma succ_high, succ_low;
+- arange_value_type combined, old_value;
+-
+- if (low > high)
+- {
+- arange_set_delete_value (set, value);
+- return FALSE;
+- }
+-
+- pred = splay_tree_predecessor (set->ranges, low);
+- if (pred && arange_set_node_high (set, pred) >= low)
+- arange_set_split_node (set, pred, low);
+-
+- node = splay_tree_lookup (set->ranges, low);
+- if (node)
+- {
+- /* Split node if its arange is larger than inserted arange. */
+- if (arange_set_node_high (set, node) > high)
+- arange_set_split_node (set, node, high + 1);
+-
+- old_value = arange_set_node_value (set, node);
+- combined = arange_set_combine_value (set, old_value, value);
+- arange_set_node_set_value (set, node, combined);
+- node = arange_set_maybe_merge_with_predecessor (set, node);
+- arange_set_delete_value (set, old_value);
+-
+- /* Insert remaining arange by tail-recursion. */
+- if (high > arange_set_node_high (set, node))
+- return arange_set_insert_value (set,
+- arange_set_node_high (set, node) + 1,
+- high, value);
+- else
+- {
+- /* Node must cover exactly the range. */
+- BFD_ASSERT (high == arange_set_node_high (set, node));
+- arange_set_delete_value (set, value);
+- succ = splay_tree_successor (set->ranges, arange_set_node_low (node));
+- if (succ)
+- succ = arange_set_maybe_merge_with_predecessor (set, succ);
+- return TRUE;
+- }
+- }
+-
+- succ = splay_tree_successor (set->ranges, low);
+- if (succ)
+- {
+- succ_low = arange_set_node_low (succ);
+- succ_high = arange_set_node_high (set, succ);
+-
+- if (succ_low <= high)
+- {
+- node = arange_set_splay_tree_insert (set, low, succ_low - 1, value);
+- if (!node)
+- return FALSE;
+-
+- /* Update set lower bound only after insertion is successful. */
+- if (low < set->lower_bound)
<<Diff was trimmed, longer than 597 lines>>
More information about the pld-cvs-commit
mailing list