summaryrefslogtreecommitdiff
path: root/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0040-PR-debug-48253.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0040-PR-debug-48253.patch')
-rw-r--r--meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0040-PR-debug-48253.patch803
1 files changed, 803 insertions, 0 deletions
diff --git a/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0040-PR-debug-48253.patch b/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0040-PR-debug-48253.patch
new file mode 100644
index 000000000..872011cb1
--- /dev/null
+++ b/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0040-PR-debug-48253.patch
@@ -0,0 +1,803 @@
+From e4e229cd56063482aced7df857e82512b846435d Mon Sep 17 00:00:00 2001
+From: jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
+Date: Tue, 29 Mar 2011 22:47:59 +0000
+Subject: [PATCH 040/200] PR debug/48253
+ * dwarf2out.c (struct dw_fde_struct): Remove dw_fde_hot_section_label,
+ dw_fde_hot_section_end_label, dw_fde_unlikely_section_label,
+ dw_fde_unlikely_section_end_label, cold_in_std_section,
+ dw_fde_switched_sections and dw_fde_switched_cold_to_hot fields.
+ Add dw_fde_second_begin, dw_fde_second_end and second_in_std_section
+ fields.
+ (output_fde): Use dw_fde_second_{begin,end} if second is
+ true, otherwise dw_fde_{begin,end}.
+ (output_call_frame_info): Test dw_fde_second_begin != NULL
+ instead of dw_fde_switched_sections.
+ (dwarf2out_begin_prologue): Stop initializing removed dw_fde_struct
+ fields, initialize new fields. Initialize in_std_section
+ unconditionally from the first partition.
+ (dwarf2out_end_epilogue): Don't override dw_fde_end when
+ dw_fde_second_begin is non-NULL.
+ (dwarf2out_switch_text_section): Stop initializing removed
+ dw_fde_struct fields, initialize new fields, initialize
+ also dw_fde_end here. Set dw_fde_switch_cfi even when
+ dwarf2out_do_cfi_asm (). Call var_location_switch_text_section.
+ (struct var_loc_list_def): Add last_before_switch field.
+ (arange_table, arange_table_allocated, arange_table_in_use,
+ ARANGE_TABLE_INCREMENT, add_arange): Removed.
+ (size_of_aranges): Count !in_std_section and !second_in_std_section
+ hunks in fdes, instead of looking at arange_table_in_use.
+ (output_aranges): Add aranges_length argument, don't call
+ size_of_aranges here. Instead of using aranges_table*
+ emit ranges for fdes when !in_std_section resp.
+ !second_in_std_section.
+ (dw_loc_list): Break ranges crossing section switch.
+ (convert_cfa_to_fb_loc_list): Likewise. If switched sections,
+ use dw_fde_second_end instead of dw_fde_end as end of last
+ range.
+ (gen_subprogram_die): Don't call add_arange. Use
+ dw_fde_{begin,end} for first partition and if switched
+ section dw_fde_second_{begin,end} for the second.
+ (var_location_switch_text_section_1,
+ var_location_switch_text_section): New functions.
+ (dwarf2out_begin_function): Initialize cold_text_section even
+ when function_section () isn't text_section.
+ (prune_unused_types): Don't walk arange_table.
+ (dwarf2out_finish): Don't needlessly test
+ flag_reorder_blocks_and_partition when testing cold_text_section_used.
+ If info_section_emitted, call size_of_aranges and if it indicates
+ non-empty .debug_aranges, call output_aranges with the computed
+ size. Stop using removed dw_fde_struct fields, use
+ dw_fde_{begin,end} for first partition and dw_fde_second_{begin,end}
+ for second.
+
+git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@171702 138bc75d-0d04-0410-961f-82ee72b054a4
+
+index b7c06e5..1e5917c 100644
+--- a/gcc/dwarf2out.c
++++ b/gcc/dwarf2out.c
+@@ -303,10 +303,8 @@ typedef struct GTY(()) dw_fde_struct {
+ const char *dw_fde_end;
+ const char *dw_fde_vms_end_prologue;
+ const char *dw_fde_vms_begin_epilogue;
+- const char *dw_fde_hot_section_label;
+- const char *dw_fde_hot_section_end_label;
+- const char *dw_fde_unlikely_section_label;
+- const char *dw_fde_unlikely_section_end_label;
++ const char *dw_fde_second_begin;
++ const char *dw_fde_second_end;
+ dw_cfi_ref dw_fde_cfi;
+ dw_cfi_ref dw_fde_switch_cfi; /* Last CFI before switching sections. */
+ HOST_WIDE_INT stack_realignment;
+@@ -325,13 +323,9 @@ typedef struct GTY(()) dw_fde_struct {
+ unsigned drap_reg_saved: 1;
+ /* True iff dw_fde_begin label is in text_section or cold_text_section. */
+ unsigned in_std_section : 1;
+- /* True iff dw_fde_unlikely_section_label is in text_section or
++ /* True iff dw_fde_second_begin label is in text_section or
+ cold_text_section. */
+- unsigned cold_in_std_section : 1;
+- /* True iff switched sections. */
+- unsigned dw_fde_switched_sections : 1;
+- /* True iff switching from cold to hot section. */
+- unsigned dw_fde_switched_cold_to_hot : 1;
++ unsigned second_in_std_section : 1;
+ }
+ dw_fde_node;
+
+@@ -3625,28 +3619,8 @@ output_fde (dw_fde_ref fde, bool for_eh, bool second,
+ dw2_asm_output_offset (DWARF_OFFSET_SIZE, section_start_label,
+ debug_frame_section, "FDE CIE offset");
+
+- if (!fde->dw_fde_switched_sections)
+- {
+- begin = fde->dw_fde_begin;
+- end = fde->dw_fde_end;
+- }
+- else
+- {
+- /* For the first section, prefer dw_fde_begin over
+- dw_fde_{hot,cold}_section_label, as the latter
+- might be separated from the real start of the
+- function by alignment padding. */
+- if (!second)
+- begin = fde->dw_fde_begin;
+- else if (fde->dw_fde_switched_cold_to_hot)
+- begin = fde->dw_fde_hot_section_label;
+- else
+- begin = fde->dw_fde_unlikely_section_label;
+- if (second ^ fde->dw_fde_switched_cold_to_hot)
+- end = fde->dw_fde_unlikely_section_end_label;
+- else
+- end = fde->dw_fde_hot_section_end_label;
+- }
++ begin = second ? fde->dw_fde_second_begin : fde->dw_fde_begin;
++ end = second ? fde->dw_fde_second_end : fde->dw_fde_end;
+
+ if (for_eh)
+ {
+@@ -3707,7 +3681,7 @@ output_fde (dw_fde_ref fde, bool for_eh, bool second,
+ /* Loop through the Call Frame Instructions associated with
+ this FDE. */
+ fde->dw_fde_current_label = begin;
+- if (!fde->dw_fde_switched_sections)
++ if (fde->dw_fde_second_begin == NULL)
+ for (cfi = fde->dw_fde_cfi; cfi != NULL; cfi = cfi->dw_cfi_next)
+ output_cfi (cfi, fde, for_eh);
+ else if (!second)
+@@ -3986,7 +3960,7 @@ output_call_frame_info (int for_eh)
+ if (for_eh && !fde_needed_for_eh_p (fde))
+ continue;
+
+- for (k = 0; k < (fde->dw_fde_switched_sections ? 2 : 1); k++)
++ for (k = 0; k < (fde->dw_fde_second_begin ? 2 : 1); k++)
+ output_fde (fde, for_eh, k, section_start_label, fde_encoding,
+ augmentation, any_lsda_needed, lsda_encoding);
+ }
+@@ -4104,14 +4078,10 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
+ fde = &fde_table[fde_table_in_use++];
+ fde->decl = current_function_decl;
+ fde->dw_fde_begin = dup_label;
+- fde->dw_fde_current_label = dup_label;
+- fde->dw_fde_hot_section_label = NULL;
+- fde->dw_fde_hot_section_end_label = NULL;
+- fde->dw_fde_unlikely_section_label = NULL;
+- fde->dw_fde_unlikely_section_end_label = NULL;
+- fde->dw_fde_switched_sections = 0;
+- fde->dw_fde_switched_cold_to_hot = 0;
+ fde->dw_fde_end = NULL;
++ fde->dw_fde_current_label = dup_label;
++ fde->dw_fde_second_begin = NULL;
++ fde->dw_fde_second_end = NULL;
+ fde->dw_fde_vms_end_prologue = NULL;
+ fde->dw_fde_vms_begin_epilogue = NULL;
+ fde->dw_fde_cfi = NULL;
+@@ -4122,27 +4092,9 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
+ fde->nothrow = crtl->nothrow;
+ fde->drap_reg = INVALID_REGNUM;
+ fde->vdrap_reg = INVALID_REGNUM;
+- if (flag_reorder_blocks_and_partition)
+- {
+- section *unlikelysec;
+- if (first_function_block_is_cold)
+- fde->in_std_section = 1;
+- else
+- fde->in_std_section
+- = (fnsec == text_section
+- || (cold_text_section && fnsec == cold_text_section));
+- unlikelysec = unlikely_text_section ();
+- fde->cold_in_std_section
+- = (unlikelysec == text_section
+- || (cold_text_section && unlikelysec == cold_text_section));
+- }
+- else
+- {
+- fde->in_std_section
+- = (fnsec == text_section
+- || (cold_text_section && fnsec == cold_text_section));
+- fde->cold_in_std_section = 0;
+- }
++ fde->in_std_section = (fnsec == text_section
++ || (cold_text_section && fnsec == cold_text_section));
++ fde->second_in_std_section = 0;
+
+ args_size = old_args_size = 0;
+
+@@ -4238,7 +4190,8 @@ dwarf2out_end_epilogue (unsigned int line ATTRIBUTE_UNUSED,
+ ASM_OUTPUT_LABEL (asm_out_file, label);
+ fde = current_fde ();
+ gcc_assert (fde != NULL);
+- fde->dw_fde_end = xstrdup (label);
++ if (fde->dw_fde_second_begin == NULL)
++ fde->dw_fde_end = xstrdup (label);
+ }
+
+ void
+@@ -4285,20 +4238,29 @@ dwarf2out_note_section_used (void)
+ cold_text_section_used = true;
+ }
+
++static void var_location_switch_text_section (void);
++
+ void
+ dwarf2out_switch_text_section (void)
+ {
++ section *sect;
+ dw_fde_ref fde = current_fde ();
++ dw_cfi_ref cfi;
+
+- gcc_assert (cfun && fde && !fde->dw_fde_switched_sections);
+-
+- fde->dw_fde_switched_sections = 1;
+- fde->dw_fde_switched_cold_to_hot = !in_cold_section_p;
++ gcc_assert (cfun && fde && fde->dw_fde_second_begin == NULL);
+
+- fde->dw_fde_hot_section_label = crtl->subsections.hot_section_label;
+- fde->dw_fde_hot_section_end_label = crtl->subsections.hot_section_end_label;
+- fde->dw_fde_unlikely_section_label = crtl->subsections.cold_section_label;
+- fde->dw_fde_unlikely_section_end_label = crtl->subsections.cold_section_end_label;
++ if (!in_cold_section_p)
++ {
++ fde->dw_fde_end = crtl->subsections.cold_section_end_label;
++ fde->dw_fde_second_begin = crtl->subsections.hot_section_label;
++ fde->dw_fde_second_end = crtl->subsections.hot_section_end_label;
++ }
++ else
++ {
++ fde->dw_fde_end = crtl->subsections.hot_section_end_label;
++ fde->dw_fde_second_begin = crtl->subsections.cold_section_label;
++ fde->dw_fde_second_end = crtl->subsections.cold_section_end_label;
++ }
+ have_multiple_function_sections = true;
+
+ /* Reset the current label on switching text sections, so that we
+@@ -4313,7 +4275,12 @@ dwarf2out_switch_text_section (void)
+ fprintf (asm_out_file, "\t.cfi_endproc\n");
+
+ /* Now do the real section switch. */
+- switch_to_section (current_function_section ());
++ sect = current_function_section ();
++ switch_to_section (sect);
++
++ fde->second_in_std_section
++ = (sect == text_section
++ || (cold_text_section && sect == cold_text_section));
+
+ if (dwarf2out_do_cfi_asm ())
+ {
+@@ -4322,16 +4289,12 @@ dwarf2out_switch_text_section (void)
+ again. */
+ output_cfis (fde->dw_fde_cfi, true, fde, true);
+ }
+- else
+- {
+- dw_cfi_ref cfi = fde->dw_fde_cfi;
+-
+- cfi = fde->dw_fde_cfi;
+- if (cfi)
+- while (cfi->dw_cfi_next != NULL)
+- cfi = cfi->dw_cfi_next;
+- fde->dw_fde_switch_cfi = cfi;
+- }
++ cfi = fde->dw_fde_cfi;
++ if (cfi)
++ while (cfi->dw_cfi_next != NULL)
++ cfi = cfi->dw_cfi_next;
++ fde->dw_fde_switch_cfi = cfi;
++ var_location_switch_text_section ();
+ }
+
+ /* And now, the subset of the debugging information support code necessary
+@@ -6110,6 +6073,11 @@ struct GTY (()) var_loc_list_def {
+ Do not mark it for GC because it is marked through the chain. */
+ struct var_loc_node * GTY ((skip ("%h"))) last;
+
++ /* Pointer to the last element before section switch,
++ if NULL, either sections weren't switched or first
++ is after section switch. */
++ struct var_loc_node * GTY ((skip ("%h"))) last_before_switch;
++
+ /* DECL_UID of the variable decl. */
+ unsigned int decl_id;
+ };
+@@ -6177,19 +6145,6 @@ static GTY (()) VEC (pubname_entry, gc) * pubtype_table;
+ defines/undefines (and file start/end markers). */
+ static GTY (()) VEC (macinfo_entry, gc) * macinfo_table;
+
+-/* Array of dies for which we should generate .debug_arange info. */
+-static GTY((length ("arange_table_allocated"))) dw_die_ref *arange_table;
+-
+-/* Number of elements currently allocated for arange_table. */
+-static GTY(()) unsigned arange_table_allocated;
+-
+-/* Number of elements in arange_table currently in use. */
+-static GTY(()) unsigned arange_table_in_use;
+-
+-/* Size (in elements) of increments by which we may expand the
+- arange_table. */
+-#define ARANGE_TABLE_INCREMENT 64
+-
+ /* Array of dies for which we should generate .debug_ranges info. */
+ static GTY ((length ("ranges_table_allocated"))) dw_ranges_ref ranges_table;
+
+@@ -6433,8 +6388,7 @@ static void add_pubname (tree, dw_die_ref);
+ static void add_pubname_string (const char *, dw_die_ref);
+ static void add_pubtype (tree, dw_die_ref);
+ static void output_pubnames (VEC (pubname_entry,gc) *);
+-static void add_arange (tree, dw_die_ref);
+-static void output_aranges (void);
++static void output_aranges (unsigned long);
+ static unsigned int add_ranges_num (int);
+ static unsigned int add_ranges (const_tree);
+ static void add_ranges_by_labels (dw_die_ref, const char *, const char *,
+@@ -10868,7 +10822,20 @@ size_of_aranges (void)
+ size += 2 * DWARF2_ADDR_SIZE;
+ if (cold_text_section_used)
+ size += 2 * DWARF2_ADDR_SIZE;
+- size += 2 * DWARF2_ADDR_SIZE * arange_table_in_use;
++ if (have_multiple_function_sections)
++ {
++ unsigned fde_idx = 0;
++
++ for (fde_idx = 0; fde_idx < fde_table_in_use; fde_idx++)
++ {
++ dw_fde_ref fde = &fde_table[fde_idx];
++
++ if (!fde->in_std_section)
++ size += 2 * DWARF2_ADDR_SIZE;
++ if (fde->dw_fde_second_begin && !fde->second_in_std_section)
++ size += 2 * DWARF2_ADDR_SIZE;
++ }
++ }
+
+ /* Count the two zero words used to terminated the address range table. */
+ size += 2 * DWARF2_ADDR_SIZE;
+@@ -11696,35 +11663,14 @@ output_pubnames (VEC (pubname_entry, gc) * names)
+ dw2_asm_output_data (DWARF_OFFSET_SIZE, 0, NULL);
+ }
+
+-/* Add a new entry to .debug_aranges if appropriate. */
+-
+-static void
+-add_arange (tree decl, dw_die_ref die)
+-{
+- if (! DECL_SECTION_NAME (decl))
+- return;
+-
+- if (arange_table_in_use == arange_table_allocated)
+- {
+- arange_table_allocated += ARANGE_TABLE_INCREMENT;
+- arange_table = GGC_RESIZEVEC (dw_die_ref, arange_table,
+- arange_table_allocated);
+- memset (arange_table + arange_table_in_use, 0,
+- ARANGE_TABLE_INCREMENT * sizeof (dw_die_ref));
+- }
+-
+- arange_table[arange_table_in_use++] = die;
+-}
+-
+ /* Output the information that goes into the .debug_aranges table.
+ Namely, define the beginning and ending address range of the
+ text section generated for this compilation unit. */
+
+ static void
+-output_aranges (void)
++output_aranges (unsigned long aranges_length)
+ {
+ unsigned i;
+- unsigned long aranges_length = size_of_aranges ();
+
+ if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
+ dw2_asm_output_data (4, 0xffffffff,
+@@ -11769,38 +11715,28 @@ output_aranges (void)
+ cold_text_section_label, "Length");
+ }
+
+- for (i = 0; i < arange_table_in_use; i++)
++ if (have_multiple_function_sections)
+ {
+- dw_die_ref die = arange_table[i];
+-
+- /* We shouldn't see aranges for DIEs outside of the main CU. */
+- gcc_assert (die->die_mark);
++ unsigned fde_idx = 0;
+
+- if (die->die_tag == DW_TAG_subprogram)
+- {
+- dw2_asm_output_addr (DWARF2_ADDR_SIZE, get_AT_low_pc (die),
+- "Address");
+- dw2_asm_output_delta (DWARF2_ADDR_SIZE, get_AT_hi_pc (die),
+- get_AT_low_pc (die), "Length");
+- }
+- else
++ for (fde_idx = 0; fde_idx < fde_table_in_use; fde_idx++)
+ {
+- /* A static variable; extract the symbol from DW_AT_location.
+- Note that this code isn't currently hit, as we only emit
+- aranges for functions (jason 9/23/99). */
+- dw_attr_ref a = get_AT (die, DW_AT_location);
+- dw_loc_descr_ref loc;
+-
+- gcc_assert (a && AT_class (a) == dw_val_class_loc);
+-
+- loc = AT_loc (a);
+- gcc_assert (loc->dw_loc_opc == DW_OP_addr);
+-
+- dw2_asm_output_addr_rtx (DWARF2_ADDR_SIZE,
+- loc->dw_loc_oprnd1.v.val_addr, "Address");
+- dw2_asm_output_data (DWARF2_ADDR_SIZE,
+- get_AT_unsigned (die, DW_AT_byte_size),
+- "Length");
++ dw_fde_ref fde = &fde_table[fde_idx];
++
++ if (!fde->in_std_section)
++ {
++ dw2_asm_output_addr (DWARF2_ADDR_SIZE, fde->dw_fde_begin,
++ "Address");
++ dw2_asm_output_delta (DWARF2_ADDR_SIZE, fde->dw_fde_end,
++ fde->dw_fde_begin, "Length");
++ }
++ if (fde->dw_fde_second_begin && !fde->second_in_std_section)
++ {
++ dw2_asm_output_addr (DWARF2_ADDR_SIZE, fde->dw_fde_second_begin,
++ "Address");
++ dw2_asm_output_delta (DWARF2_ADDR_SIZE, fde->dw_fde_second_end,
++ fde->dw_fde_second_begin, "Length");
++ }
+ }
+ }
+
+@@ -15210,9 +15146,23 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address)
+ }
+ if (descr)
+ {
++ bool range_across_switch = false;
++ /* If section switch happens in between node->label
++ and node->next->label (or end of function) and
++ we can't emit it as a single entry list,
++ emit two ranges, first one ending at the end
++ of first partition and second one starting at the
++ beginning of second partition. */
++ if (node == loc_list->last_before_switch
++ && (node != loc_list->first || loc_list->first->next)
++ && current_function_decl)
++ {
++ endname = current_fde ()->dw_fde_end;
++ range_across_switch = true;
++ }
+ /* The variable has a location between NODE->LABEL and
+ NODE->NEXT->LABEL. */
+- if (node->next)
++ else if (node->next)
+ endname = node->next->label;
+ /* If the variable has a location at the last label
+ it keeps its location until the end of function. */
+@@ -15227,6 +15177,30 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address)
+
+ *listp = new_loc_list (descr, node->label, endname, secname);
+ listp = &(*listp)->dw_loc_next;
++
++ if (range_across_switch)
++ {
++ if (GET_CODE (node->loc) == EXPR_LIST)
++ descr = dw_sra_loc_expr (decl, node->loc);
++ else
++ {
++ initialized = NOTE_VAR_LOCATION_STATUS (node->loc);
++ varloc = NOTE_VAR_LOCATION (node->loc);
++ descr = dw_loc_list_1 (decl, varloc, want_address,
++ initialized);
++ }
++ gcc_assert (descr);
++ /* The variable has a location between NODE->LABEL and
++ NODE->NEXT->LABEL. */
++ if (node->next)
++ endname = node->next->label;
++ else
++ endname = current_fde ()->dw_fde_second_end;
++ *listp = new_loc_list (descr,
++ current_fde ()->dw_fde_second_begin,
++ endname, secname);
++ listp = &(*listp)->dw_loc_next;
++ }
+ }
+ }
+
+@@ -17305,33 +17279,61 @@ convert_cfa_to_fb_loc_list (HOST_WIDE_INT offset)
+ last_cfa = next_cfa;
+ last_label = start_label;
+
++ if (fde->dw_fde_second_begin && fde->dw_fde_switch_cfi == NULL)
++ {
++ /* If the first partition contained no CFI adjustments, the
++ CIE opcodes apply to the whole first partition. */
++ *list_tail = new_loc_list (build_cfa_loc (&last_cfa, offset),
++ fde->dw_fde_begin, fde->dw_fde_end, section);
++ list_tail =&(*list_tail)->dw_loc_next;
++ start_label = last_label = fde->dw_fde_second_begin;
++ }
++
+ for (cfi = fde->dw_fde_cfi; cfi; cfi = cfi->dw_cfi_next)
+- switch (cfi->dw_cfi_opc)
+- {
+- case DW_CFA_set_loc:
+- case DW_CFA_advance_loc1:
+- case DW_CFA_advance_loc2:
+- case DW_CFA_advance_loc4:
+- if (!cfa_equal_p (&last_cfa, &next_cfa))
+- {
+- *list_tail = new_loc_list (build_cfa_loc (&last_cfa, offset),
+- start_label, last_label, section);
++ {
++ switch (cfi->dw_cfi_opc)
++ {
++ case DW_CFA_set_loc:
++ case DW_CFA_advance_loc1:
++ case DW_CFA_advance_loc2:
++ case DW_CFA_advance_loc4:
++ if (!cfa_equal_p (&last_cfa, &next_cfa))
++ {
++ *list_tail = new_loc_list (build_cfa_loc (&last_cfa, offset),
++ start_label, last_label, section);
+
+- list_tail = &(*list_tail)->dw_loc_next;
+- last_cfa = next_cfa;
+- start_label = last_label;
+- }
+- last_label = cfi->dw_cfi_oprnd1.dw_cfi_addr;
+- break;
++ list_tail = &(*list_tail)->dw_loc_next;
++ last_cfa = next_cfa;
++ start_label = last_label;
++ }
++ last_label = cfi->dw_cfi_oprnd1.dw_cfi_addr;
++ break;
+
+- case DW_CFA_advance_loc:
+- /* The encoding is complex enough that we should never emit this. */
+- gcc_unreachable ();
++ case DW_CFA_advance_loc:
++ /* The encoding is complex enough that we should never emit this. */
++ gcc_unreachable ();
+
+- default:
+- lookup_cfa_1 (cfi, &next_cfa, &remember);
+- break;
+- }
++ default:
++ lookup_cfa_1 (cfi, &next_cfa, &remember);
++ break;
++ }
++ if (cfi == fde->dw_fde_switch_cfi)
++ {
++ if (!cfa_equal_p (&last_cfa, &next_cfa))
++ {
++ *list_tail = new_loc_list (build_cfa_loc (&last_cfa, offset),
++ start_label, last_label, section);
++
++ list_tail = &(*list_tail)->dw_loc_next;
++ last_cfa = next_cfa;
++ start_label = last_label;
++ }
++ *list_tail = new_loc_list (build_cfa_loc (&last_cfa, offset),
++ start_label, fde->dw_fde_end, section);
++ list_tail = &(*list_tail)->dw_loc_next;
++ start_label = last_label = fde->dw_fde_second_begin;
++ }
++ }
+
+ if (!cfa_equal_p (&last_cfa, &next_cfa))
+ {
+@@ -17342,7 +17344,10 @@ convert_cfa_to_fb_loc_list (HOST_WIDE_INT offset)
+ }
+
+ *list_tail = new_loc_list (build_cfa_loc (&next_cfa, offset),
+- start_label, fde->dw_fde_end, section);
++ start_label,
++ fde->dw_fde_second_begin
++ ? fde->dw_fde_second_end : fde->dw_fde_end,
++ section);
+
+ if (list && list->dw_loc_next)
+ gen_llsym (list);
+@@ -19213,14 +19218,13 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
+ #endif
+
+ add_pubname (decl, subr_die);
+- add_arange (decl, subr_die);
+ }
+ else
+ { /* Generate pubnames entries for the split function code
+ ranges. */
+ dw_fde_ref fde = &fde_table[current_funcdef_fde];
+
+- if (fde->dw_fde_switched_sections)
++ if (fde->dw_fde_second_begin)
+ {
+ if (dwarf_version >= 3 || !dwarf_strict)
+ {
+@@ -19229,28 +19233,11 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
+ section, since the HOT/COLD labels might precede an
+ alignment offset. */
+ bool range_list_added = false;
+- if (fde->in_std_section)
+- {
+- add_ranges_by_labels (subr_die,
+- fde->dw_fde_begin,
+- fde->dw_fde_end,
+- &range_list_added);
+- add_ranges_by_labels (subr_die,
+- fde->dw_fde_unlikely_section_label,
+- fde->dw_fde_unlikely_section_end_label,
+- &range_list_added);
+- }
+- else
+- {
+- add_ranges_by_labels (subr_die,
+- fde->dw_fde_begin,
+- fde->dw_fde_end,
+- &range_list_added);
+- add_ranges_by_labels (subr_die,
+- fde->dw_fde_hot_section_label,
+- fde->dw_fde_hot_section_end_label,
+- &range_list_added);
+- }
++ add_ranges_by_labels (subr_die, fde->dw_fde_begin,
++ fde->dw_fde_end, &range_list_added);
++ add_ranges_by_labels (subr_die, fde->dw_fde_second_begin,
++ fde->dw_fde_second_end,
++ &range_list_added);
+ add_pubname (decl, subr_die);
+ if (range_list_added)
+ add_ranges (NULL);
+@@ -19275,7 +19262,6 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
+ fde->dw_fde_end);
+ /* Add it. */
+ add_pubname (decl, subr_die);
+- add_arange (decl, subr_die);
+
+ /* Build a minimal DIE for the secondary section. */
+ seg_die = new_die (DW_TAG_subprogram,
+@@ -19293,30 +19279,18 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
+
+ add_linkage_name (seg_die, decl);
+ }
+- gcc_assert (name!=NULL);
++ gcc_assert (name != NULL);
+ add_pure_or_virtual_attribute (seg_die, decl);
+ if (DECL_ARTIFICIAL (decl))
+ add_AT_flag (seg_die, DW_AT_artificial, 1);
+
+- if (fde->in_std_section)
+- {
+- name = concat ("__cold_sect_of_", name, NULL);
+- add_AT_lbl_id (seg_die, DW_AT_low_pc,
+- fde->dw_fde_unlikely_section_label);
+- add_AT_lbl_id (seg_die, DW_AT_high_pc,
+- fde->dw_fde_unlikely_section_end_label);
+- }
+- else
+- {
+- name = concat ("__hot_sect_of_", name, NULL);
+- add_AT_lbl_id (seg_die, DW_AT_low_pc,
+- fde->dw_fde_hot_section_label);
+- add_AT_lbl_id (seg_die, DW_AT_high_pc,
+- fde->dw_fde_hot_section_end_label);
+- }
++ name = concat ("__second_sect_of_", name, NULL);
++ add_AT_lbl_id (seg_die, DW_AT_low_pc,
++ fde->dw_fde_second_begin);
++ add_AT_lbl_id (seg_die, DW_AT_high_pc,
++ fde->dw_fde_second_end);
+ add_name_attribute (seg_die, name);
+ add_pubname_string (name, seg_die);
+- add_arange (decl, seg_die);
+ }
+ }
+ else
+@@ -19324,7 +19298,6 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
+ add_AT_lbl_id (subr_die, DW_AT_low_pc, fde->dw_fde_begin);
+ add_AT_lbl_id (subr_die, DW_AT_high_pc, fde->dw_fde_end);
+ add_pubname (decl, subr_die);
+- add_arange (decl, subr_die);
+ }
+ }
+
+@@ -21975,6 +21948,29 @@ dwarf2out_var_location (rtx loc_note)
+ last_in_cold_section_p = in_cold_section_p;
+ }
+
++/* Note in one location list that text section has changed. */
++
++static int
++var_location_switch_text_section_1 (void **slot, void *data ATTRIBUTE_UNUSED)
++{
++ var_loc_list *list = (var_loc_list *) *slot;
++ if (list->first)
++ list->last_before_switch
++ = list->last->next ? list->last->next : list->last;
++ return 1;
++}
++
++/* Note in all location lists that text section has changed. */
++
++static void
++var_location_switch_text_section (void)
++{
++ if (decl_loc_table == NULL)
++ return;
++
++ htab_traverse (decl_loc_table, var_location_switch_text_section_1, NULL);
++}
++
+ /* We need to reset the locations at the beginning of each
+ function. We can't do this in the end_function hook, because the
+ declarations that use the locations won't have been output when
+@@ -21985,7 +21981,7 @@ dwarf2out_begin_function (tree fun)
+ {
+ if (function_section (fun) != text_section)
+ have_multiple_function_sections = true;
+- else if (flag_reorder_blocks_and_partition && !cold_text_section)
++ if (flag_reorder_blocks_and_partition && !cold_text_section)
+ {
+ gcc_assert (current_function_decl == fun);
+ cold_text_section = unlikely_text_section ();
+@@ -22702,11 +22698,9 @@ prune_unused_types (void)
+ }
+
+ /* Also set the mark on nodes referenced from the
+- pubname_table or arange_table. */
++ pubname_table. */
+ FOR_EACH_VEC_ELT (pubname_entry, pubname_table, i, pub)
+ prune_unused_types_mark (pub->die, 1);
+- for (i = 0; i < arange_table_in_use; i++)
+- prune_unused_types_mark (arange_table[i], 1);
+
+ /* Mark nodes referenced from the direct call table. */
+ FOR_EACH_VEC_ELT (dcall_entry, dcall_table, i, dcall)
+@@ -23479,7 +23473,7 @@ dwarf2out_finish (const char *filename)
+ if (text_section_used)
+ add_ranges_by_labels (comp_unit_die (), text_section_label,
+ text_end_label, &range_list_added);
+- if (flag_reorder_blocks_and_partition && cold_text_section_used)
++ if (cold_text_section_used)
+ add_ranges_by_labels (comp_unit_die (), cold_text_section_label,
+ cold_end_label, &range_list_added);
+
+@@ -23487,22 +23481,12 @@ dwarf2out_finish (const char *filename)
+ {
+ dw_fde_ref fde = &fde_table[fde_idx];
+
+- if (fde->dw_fde_switched_sections)
+- {
+- if (!fde->in_std_section)
+- add_ranges_by_labels (comp_unit_die (),
+- fde->dw_fde_hot_section_label,
+- fde->dw_fde_hot_section_end_label,
+- &range_list_added);
+- if (!fde->cold_in_std_section)
+- add_ranges_by_labels (comp_unit_die (),
+- fde->dw_fde_unlikely_section_label,
+- fde->dw_fde_unlikely_section_end_label,
+- &range_list_added);
+- }
+- else if (!fde->in_std_section)
++ if (!fde->in_std_section)
+ add_ranges_by_labels (comp_unit_die (), fde->dw_fde_begin,
+ fde->dw_fde_end, &range_list_added);
++ if (fde->dw_fde_second_begin && !fde->second_in_std_section)
++ add_ranges_by_labels (comp_unit_die (), fde->dw_fde_second_begin,
++ fde->dw_fde_second_end, &range_list_added);
+ }
+
+ if (range_list_added)
+@@ -23614,13 +23598,21 @@ dwarf2out_finish (const char *filename)
+ output_vcall_table ();
+ }
+
+- /* Output the address range information. We only put functions in the arange
+- table, so don't write it out if we don't have any. */
+- if ((text_section_used || cold_text_section_used || arange_table_in_use)
+- && info_section_emitted)
++ /* Output the address range information. We only put functions in the
++ arange table, so don't write it out if we don't have any. */
++ if (info_section_emitted)
+ {
+- switch_to_section (debug_aranges_section);
+- output_aranges ();
++ unsigned long aranges_length = size_of_aranges ();
++
++ /* Empty .debug_aranges would contain just header and
++ terminating 0,0. */
++ if (aranges_length
++ != (unsigned long) (DWARF_ARANGES_HEADER_SIZE
++ + 2 * DWARF2_ADDR_SIZE))
++ {
++ switch_to_section (debug_aranges_section);
++ output_aranges (aranges_length);
++ }
+ }
+
+ /* Output ranges section if necessary. */
+--
+1.7.0.4
+