X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fdwarf2-frame.c;h=719e06570d1e5a06798c17a607eaba7f757bc9cc;hb=be09caf15d3d57da2173d26abdb0bf92ef90f28f;hp=45af947c8e5325f03d0e6419951bcea30e575ece;hpb=39ef2f6256737db92f5d60fa201fe0b301bb8100;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index 45af947c8e..719e06570d 100644 --- a/gdb/dwarf2-frame.c +++ b/gdb/dwarf2-frame.c @@ -39,10 +39,12 @@ #include "ax.h" #include "dwarf2loc.h" #include "dwarf2-frame-tailcall.h" +#include "gdbsupport/gdb_binary_search.h" #if GDB_SELF_TEST #include "gdbsupport/selftest.h" #include "selftest-arch.h" #endif +#include #include @@ -100,11 +102,9 @@ struct dwarf2_cie unsigned char segment_size; }; -struct dwarf2_cie_table -{ - int num_entries; - struct dwarf2_cie **entries; -}; +/* The CIE table is used to find CIEs during parsing, but then + discarded. It maps from the CIE's offset to the CIE. */ +typedef std::unordered_map dwarf2_cie_table; /* Frame Description Entry (FDE). */ @@ -1344,7 +1344,7 @@ dwarf2_frame_sniffer (const struct frame_unwind *self, if (!dwarf2_frame_unwinders_enabled_p) return 0; - /* Grab an address that is guarenteed to reside somewhere within the + /* Grab an address that is guaranteed to reside somewhere within the function. get_frame_pc(), with a no-return next function, can end up returning something past the end of this function's body. If the frame we're sniffing for is a signal frame whose start @@ -1643,64 +1643,22 @@ read_encoded_value (struct comp_unit *unit, gdb_byte encoding, } -static int -bsearch_cie_cmp (const void *key, const void *element) -{ - ULONGEST cie_pointer = *(ULONGEST *) key; - struct dwarf2_cie *cie = *(struct dwarf2_cie **) element; - - if (cie_pointer == cie->cie_pointer) - return 0; - - return (cie_pointer < cie->cie_pointer) ? -1 : 1; -} - /* Find CIE with the given CIE_POINTER in CIE_TABLE. */ static struct dwarf2_cie * -find_cie (struct dwarf2_cie_table *cie_table, ULONGEST cie_pointer) +find_cie (const dwarf2_cie_table &cie_table, ULONGEST cie_pointer) { - struct dwarf2_cie **p_cie; - - /* The C standard (ISO/IEC 9899:TC2) requires the BASE argument to - bsearch be non-NULL. */ - if (cie_table->entries == NULL) - { - gdb_assert (cie_table->num_entries == 0); - return NULL; - } - - p_cie = ((struct dwarf2_cie **) - bsearch (&cie_pointer, cie_table->entries, cie_table->num_entries, - sizeof (cie_table->entries[0]), bsearch_cie_cmp)); - if (p_cie != NULL) - return *p_cie; + auto iter = cie_table.find (cie_pointer); + if (iter != cie_table.end ()) + return iter->second; return NULL; } -/* Add a pointer to new CIE to the CIE_TABLE, allocating space for it. */ -static void -add_cie (struct dwarf2_cie_table *cie_table, struct dwarf2_cie *cie) +static inline int +bsearch_fde_cmp (const dwarf2_fde *fde, CORE_ADDR seek_pc) { - const int n = cie_table->num_entries; - - gdb_assert (n < 1 - || cie_table->entries[n - 1]->cie_pointer < cie->cie_pointer); - - cie_table->entries - = XRESIZEVEC (struct dwarf2_cie *, cie_table->entries, n + 1); - cie_table->entries[n] = cie; - cie_table->num_entries = n + 1; -} - -static int -bsearch_fde_cmp (const void *key, const void *element) -{ - CORE_ADDR seek_pc = *(CORE_ADDR *) key; - struct dwarf2_fde *fde = *(struct dwarf2_fde **) element; - - if (seek_pc < fde->initial_location) + if (fde->initial_location + fde->address_range <= seek_pc) return -1; - if (seek_pc < fde->initial_location + fde->address_range) + if (fde->initial_location <= seek_pc) return 0; return 1; } @@ -1714,7 +1672,6 @@ dwarf2_frame_find_fde (CORE_ADDR *pc, CORE_ADDR *out_offset) for (objfile *objfile : current_program_space->objfiles ()) { struct dwarf2_fde_table *fde_table; - struct dwarf2_fde **p_fde; CORE_ADDR offset; CORE_ADDR seek_pc; @@ -1737,15 +1694,14 @@ dwarf2_frame_find_fde (CORE_ADDR *pc, CORE_ADDR *out_offset) continue; seek_pc = *pc - offset; - p_fde = ((struct dwarf2_fde **) - bsearch (&seek_pc, fde_table->entries, fde_table->num_entries, - sizeof (fde_table->entries[0]), bsearch_fde_cmp)); - if (p_fde != NULL) + auto end = fde_table->entries + fde_table->num_entries; + auto it = gdb::binary_search (fde_table->entries, end, seek_pc, bsearch_fde_cmp); + if (it != end) { - *pc = (*p_fde)->initial_location + offset; + *pc = (*it)->initial_location + offset; if (out_offset) *out_offset = offset; - return *p_fde; + return *it; } } return NULL; @@ -1780,7 +1736,7 @@ enum eh_frame_type static const gdb_byte *decode_frame_entry (struct comp_unit *unit, const gdb_byte *start, int eh_frame_p, - struct dwarf2_cie_table *cie_table, + dwarf2_cie_table &cie_table, struct dwarf2_fde_table *fde_table, enum eh_frame_type entry_type); @@ -1790,7 +1746,7 @@ static const gdb_byte *decode_frame_entry (struct comp_unit *unit, static const gdb_byte * decode_frame_entry_1 (struct comp_unit *unit, const gdb_byte *start, int eh_frame_p, - struct dwarf2_cie_table *cie_table, + dwarf2_cie_table &cie_table, struct dwarf2_fde_table *fde_table, enum eh_frame_type entry_type) { @@ -2009,7 +1965,7 @@ decode_frame_entry_1 (struct comp_unit *unit, const gdb_byte *start, cie->end = end; cie->unit = unit; - add_cie (cie_table, cie); + cie_table[cie->cie_pointer] = cie; } else { @@ -2092,7 +2048,7 @@ decode_frame_entry_1 (struct comp_unit *unit, const gdb_byte *start, static const gdb_byte * decode_frame_entry (struct comp_unit *unit, const gdb_byte *start, int eh_frame_p, - struct dwarf2_cie_table *cie_table, + dwarf2_cie_table &cie_table, struct dwarf2_fde_table *fde_table, enum eh_frame_type entry_type) { @@ -2206,13 +2162,10 @@ dwarf2_build_frame_info (struct objfile *objfile) { struct comp_unit *unit; const gdb_byte *frame_ptr; - struct dwarf2_cie_table cie_table; + dwarf2_cie_table cie_table; struct dwarf2_fde_table fde_table; struct dwarf2_fde_table *fde_table2; - cie_table.num_entries = 0; - cie_table.entries = NULL; - fde_table.num_entries = 0; fde_table.entries = NULL; @@ -2254,7 +2207,7 @@ dwarf2_build_frame_info (struct objfile *objfile) frame_ptr = unit->dwarf_frame_buffer; while (frame_ptr < unit->dwarf_frame_buffer + unit->dwarf_frame_size) frame_ptr = decode_frame_entry (unit, frame_ptr, 1, - &cie_table, &fde_table, + cie_table, &fde_table, EH_CIE_OR_FDE_TYPE_ID); } @@ -2269,16 +2222,10 @@ dwarf2_build_frame_info (struct objfile *objfile) fde_table.entries = NULL; fde_table.num_entries = 0; } - /* The cie_table is discarded by the next if. */ + /* The cie_table is discarded below. */ } - if (cie_table.num_entries != 0) - { - /* Reinit cie_table: debug_frame has different CIEs. */ - xfree (cie_table.entries); - cie_table.num_entries = 0; - cie_table.entries = NULL; - } + cie_table.clear (); } } @@ -2295,7 +2242,7 @@ dwarf2_build_frame_info (struct objfile *objfile) frame_ptr = unit->dwarf_frame_buffer; while (frame_ptr < unit->dwarf_frame_buffer + unit->dwarf_frame_size) frame_ptr = decode_frame_entry (unit, frame_ptr, 0, - &cie_table, &fde_table, + cie_table, &fde_table, EH_CIE_OR_FDE_TYPE_ID); } catch (const gdb_exception_error &e) @@ -2319,18 +2266,9 @@ dwarf2_build_frame_info (struct objfile *objfile) } } fde_table.num_entries = num_old_fde_entries; - /* The cie_table is discarded by the next if. */ } } - /* Discard the cie_table, it is no longer needed. */ - if (cie_table.num_entries != 0) - { - xfree (cie_table.entries); - cie_table.entries = NULL; /* Paranoia. */ - cie_table.num_entries = 0; /* Paranoia. */ - } - /* Copy fde_table to obstack: it is needed at runtime. */ fde_table2 = XOBNEW (&objfile->objfile_obstack, struct dwarf2_fde_table);