Index: src/gas/dw2gencfi.c =================================================================== --- src.orig/gas/dw2gencfi.c 2011-04-16 12:06:37.722473700 +0200 +++ src/gas/dw2gencfi.c 2011-04-18 09:02:12.640362500 +0200 @@ -76,6 +76,147 @@ # define DWARF2_ADDR_SIZE(bfd) (bfd_arch_bits_per_address (bfd) / 8) #endif +/* Private segment collection list. */ +struct dwcfi_seg_list { + segT seg; + int subseg; + char *seg_name; +}; + +static struct hash_control *dwcfi_hash; + +/* Build based on segment the derived .debug_... + segment name containing origin segment's postfix name part. */ +static char * +get_debugseg_name (segT seg, const char *base_name) +{ + const char *name,*dollar, *dot; + char *sname; + + if (!seg) + name = ""; + else + name = bfd_get_section_name (stdoutput, seg); + + dollar = strchr (name, '$'); + dot = strchr (name + 1, '.'); + + if (!dollar && !dot) + name = ""; + else if (!dollar) + name = dot; + else if (!dot) + name = dollar; + else if (dot < dollar) + name = dot; + else + name = dollar; + + sname = concat (base_name, name, NULL); + + return sname; +} + +/* Allocate a dwcfi_seg_list structure. */ +static struct dwcfi_seg_list * +alloc_debugseg_item (segT seg, int subseg, char *name) +{ + struct dwcfi_seg_list *r; + + r = (struct dwcfi_seg_list *) + xmalloc (sizeof (struct dwcfi_seg_list) + strlen (name)); + r->seg = seg; + r->subseg = subseg; + r->seg_name = name; + return r; +} + +static segT +is_now_linkonce_segment (void) +{ + if ((bfd_get_section_flags (stdoutput, now_seg) + & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD + | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE + | SEC_LINK_DUPLICATES_SAME_CONTENTS)) != 0) + return now_seg; + return NULL; +} + +/* Generate debug... segment with same linkonce properties + of based segment. */ +static segT +make_debug_seg (segT cseg, char *name, int sflags) +{ + segT save_seg = now_seg; + int save_subseg = now_subseg; + segT r; + flagword flags; + + r = subseg_new (name, 0); + /* Check if code segment is marked as linked once. */ + if (!cseg) + flags = 0; + else + flags = bfd_get_section_flags (stdoutput, cseg) + & (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD + | SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE + | SEC_LINK_DUPLICATES_SAME_CONTENTS); + + /* Add standard section flags. */ + flags |= sflags; + + /* Apply possibly linked once flags to new generated segment, too. */ + if (!bfd_set_section_flags (stdoutput, r, flags)) + as_bad (_("bfd_set_section_flags: %s"), + bfd_errmsg (bfd_get_error ())); + + /* Restore to previous segment. */ + if (save_seg != NULL) + subseg_set (save_seg, save_subseg); + return r; +} + +static void +dwcfi_hash_insert (const char *name, struct dwcfi_seg_list *item) +{ + const char *error_string; + + if ((error_string = hash_jam (dwcfi_hash, name, (char *) item))) + as_fatal (_("Inserting \"%s\" into structure table failed: %s"), + name, error_string); +} + +static struct dwcfi_seg_list * +dwcfi_hash_find (char *name) +{ + return (struct dwcfi_seg_list *) hash_find (dwcfi_hash, name); +} + +static struct dwcfi_seg_list * +dwcfi_hash_find_or_make (segT cseg, const char *base_name, int flags) +{ + struct dwcfi_seg_list *item; + char *name; + + /* Initialize dwcfi_hash once. */ + if (!dwcfi_hash) + dwcfi_hash = hash_new (); + + name = get_debugseg_name (cseg, base_name); + + item = dwcfi_hash_find (name); + if (!item) + { + item = alloc_debugseg_item (make_debug_seg (cseg, name, flags), 0, name); + + dwcfi_hash_insert (item->seg_name, item); + } + else + free (name); + + return item; +} + /* ??? Share this with dwarf2cfg.c. */ #ifndef TC_DWARF2_EMIT_OFFSET #define TC_DWARF2_EMIT_OFFSET generic_dwarf2_emit_offset @@ -102,6 +243,7 @@ struct cfi_escape_data { struct cfi_insn_data { struct cfi_insn_data *next; + segT cur_seg; int insn; union { struct { @@ -134,6 +276,7 @@ struct cfi_insn_data struct fde_entry { struct fde_entry *next; + segT cseg; symbolS *start_address; symbolS *end_address; struct cfi_insn_data *data; @@ -144,11 +287,13 @@ struct fde_entry expressionS lsda; unsigned int return_column; unsigned int signal_frame; + int handled; }; struct cie_entry { struct cie_entry *next; + segT cur_seg; symbolS *start_address; unsigned int return_column; unsigned int signal_frame; @@ -195,7 +340,8 @@ alloc_fde_entry (void) frchain_now->frch_cfi_data->cur_fde_data = fde; *last_fde_data = fde; last_fde_data = &fde->next; - + fde->cseg = is_now_linkonce_segment (); + fde->handled = 0; fde->last = &fde->data; fde->return_column = DWARF2_DEFAULT_RETURN_COLUMN; fde->per_encoding = DW_EH_PE_omit; @@ -219,6 +365,7 @@ alloc_cfi_insn_data (void) *cur_fde_data->last = insn; cur_fde_data->last = &insn->next; + insn->cur_seg = is_now_linkonce_segment (); return insn; } @@ -254,7 +401,7 @@ cfi_set_return_column (unsigned regno) /* Universal functions to store new instructions. */ static void -cfi_add_CFA_insn(int insn) +cfi_add_CFA_insn (int insn) { struct cfi_insn_data *insn_ptr = alloc_cfi_insn_data (); @@ -916,9 +1063,9 @@ dot_cfi_sections (int ignored ATTRIBUTE_ name = input_line_pointer; c = get_symbol_end (); - if (strcmp (name, ".eh_frame") == 0) + if (strncmp (name, ".eh_frame", 9) == 0) sections |= CFI_EMIT_eh_frame; - else if (strcmp (name, ".debug_frame") == 0) + else if (strncmp (name, ".debug_frame", 12) == 0) sections |= CFI_EMIT_debug_frame; else { @@ -1384,8 +1531,14 @@ output_cie (struct cie_entry *cie, bfd_b out_one (enc); if (cie->first) - for (i = cie->first; i != cie->last; i = i->next) - output_cfi_insn (i); + { + for (i = cie->first; i != cie->last; i = i->next) + { + if (i->cur_seg != cie->cur_seg) + continue; + output_cfi_insn (i); + } + } frag_align (align, DW_CFA_nop, 0); symbol_set_value_now (end_address); @@ -1492,7 +1645,10 @@ output_fde (struct fde_entry *fde, struc } for (; first; first = first->next) - output_cfi_insn (first); + { + if (first->cur_seg == fde->cseg) + output_cfi_insn (first); + } frag_align (align, DW_CFA_nop, 0); symbol_set_value_now (end_address); @@ -1507,7 +1663,8 @@ select_cie_for_fde (struct fde_entry *fd for (cie = cie_root; cie; cie = cie->next) { - if (cie->return_column != fde->return_column + if (cie->cur_seg != fde->cseg + || cie->return_column != fde->return_column || cie->signal_frame != fde->signal_frame || cie->per_encoding != fde->per_encoding || cie->lsda_encoding != fde->lsda_encoding) @@ -1605,6 +1762,7 @@ select_cie_for_fde (struct fde_entry *fd cie = (struct cie_entry *) xmalloc (sizeof (struct cie_entry)); cie->next = cie_root; cie_root = cie; + cie->cur_seg = fde->cseg; cie->return_column = fde->return_column; cie->signal_frame = fde->signal_frame; cie->per_encoding = fde->per_encoding; @@ -1629,130 +1787,183 @@ select_cie_for_fde (struct fde_entry *fd #ifdef md_reg_eh_frame_to_debug_frame static void -cfi_change_reg_numbers (struct cfi_insn_data *insn) +cfi_change_reg_numbers (struct cfi_insn_data *insn, segT ccseg) { for (; insn; insn = insn->next) - switch (insn->insn) - { - case DW_CFA_advance_loc: - case DW_CFA_def_cfa_offset: - case DW_CFA_remember_state: - case DW_CFA_restore_state: - case DW_CFA_GNU_window_save: - case CFI_escape: - break; + { + if (insn->cur_seg != ccseg) + continue; + switch (insn->insn) + { + case DW_CFA_advance_loc: + case DW_CFA_def_cfa_offset: + case DW_CFA_remember_state: + case DW_CFA_restore_state: + case DW_CFA_GNU_window_save: + case CFI_escape: + break; - case DW_CFA_def_cfa: - case DW_CFA_offset: - insn->u.ri.reg = md_reg_eh_frame_to_debug_frame (insn->u.ri.reg); - break; + case DW_CFA_def_cfa: + case DW_CFA_offset: + insn->u.ri.reg = md_reg_eh_frame_to_debug_frame (insn->u.ri.reg); + break; - case DW_CFA_def_cfa_register: - case DW_CFA_undefined: - case DW_CFA_same_value: - case DW_CFA_restore: - insn->u.r = md_reg_eh_frame_to_debug_frame (insn->u.r); - break; + case DW_CFA_def_cfa_register: + case DW_CFA_undefined: + case DW_CFA_same_value: + case DW_CFA_restore: + insn->u.r = md_reg_eh_frame_to_debug_frame (insn->u.r); + break; - case DW_CFA_register: - insn->u.rr.reg1 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg1); - insn->u.rr.reg2 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg2); - break; + case DW_CFA_register: + insn->u.rr.reg1 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg1); + insn->u.rr.reg2 = md_reg_eh_frame_to_debug_frame (insn->u.rr.reg2); + break; - case CFI_val_encoded_addr: - insn->u.ea.reg = md_reg_eh_frame_to_debug_frame (insn->u.ea.reg); - break; + case CFI_val_encoded_addr: + insn->u.ea.reg = md_reg_eh_frame_to_debug_frame (insn->u.ea.reg); + break; - default: - abort (); - } + default: + abort (); + } + } } #else -#define cfi_change_reg_numbers(insn) do { } while (0) +#define cfi_change_reg_numbers(insn, cseg) do { } while (0) #endif +static segT +get_cfi_seg (segT cseg, const char *base, flagword flags, int align) +{ + struct dwcfi_seg_list *l; + + l = dwcfi_hash_find_or_make (cseg, base, flags); + + subseg_set (l->seg, l->subseg); + record_alignment (l->seg, align); + return l->seg; +} + void cfi_finish (void) { - segT cfi_seg; + struct cie_entry *cie, *cie_next; + segT cfi_seg, ccseg; struct fde_entry *fde; - int save_flag_traditional_format; + struct cfi_insn_data *first; + int save_flag_traditional_format, seek_next_seg; if (all_fde_data == 0) return; if ((cfi_sections & CFI_EMIT_eh_frame) != 0) { - /* Open .eh_frame section. */ - cfi_seg = subseg_new (".eh_frame", 0); - bfd_set_section_flags (stdoutput, cfi_seg, - SEC_ALLOC | SEC_LOAD | SEC_DATA - | DWARF2_EH_FRAME_READ_ONLY); - subseg_set (cfi_seg, 0); - record_alignment (cfi_seg, EH_FRAME_ALIGNMENT); - -#ifdef md_fix_up_eh_frame - md_fix_up_eh_frame (cfi_seg); -#endif - /* Make sure check_eh_frame doesn't do anything with our output. */ save_flag_traditional_format = flag_traditional_format; flag_traditional_format = 1; - for (fde = all_fde_data; fde ; fde = fde->next) - { - struct cfi_insn_data *first; - struct cie_entry *cie; - - if (fde->end_address == NULL) + do + { + ccseg = NULL; + cfi_seg = NULL; + seek_next_seg = 0; + for (cie = cie_root; cie; cie = cie_next) { - as_bad (_("open CFI at the end of file; missing .cfi_endproc directive")); - fde->end_address = fde->start_address; + cie_next = cie->next; + free ((void *) cie); } + cie_root = NULL; - cie = select_cie_for_fde (fde, TRUE, &first, 2); - output_fde (fde, cie, TRUE, first, - fde->next == NULL ? EH_FRAME_ALIGNMENT : 2); + for (fde = all_fde_data; fde ; fde = fde->next) + { + if (fde->handled != 0) + continue; + if (seek_next_seg && fde->cseg != ccseg) + continue; + if (!seek_next_seg) + { + ccseg = fde->cseg; + /* Open .eh_frame section. */ + cfi_seg = get_cfi_seg (ccseg, ".eh_frame", + SEC_ALLOC | SEC_LOAD | SEC_DATA + | DWARF2_EH_FRAME_READ_ONLY, + EH_FRAME_ALIGNMENT); +#ifdef md_fix_up_eh_frame + md_fix_up_eh_frame (cfi_seg); +#endif + } + fde->handled = 1; + seek_next_seg = 1; + + if (fde->end_address == NULL) + { + as_bad (_("open CFI at the end of file; missing .cfi_endproc directive")); + fde->end_address = fde->start_address; + } + + cie = select_cie_for_fde (fde, TRUE, &first, 2); + output_fde (fde, cie, TRUE, first, + fde->next == NULL ? EH_FRAME_ALIGNMENT : 2); + } } + while (seek_next_seg != 0); + + for (fde = all_fde_data; fde ; fde = fde->next) + fde->handled = 0; flag_traditional_format = save_flag_traditional_format; } if ((cfi_sections & CFI_EMIT_debug_frame) != 0) { - struct cie_entry *cie, *cie_next; int alignment = ffs (DWARF2_ADDR_SIZE (stdoutput)) - 1; - for (cie = cie_root; cie; cie = cie_next) - { - cie_next = cie->next; - free ((void *) cie); - } - cie_root = NULL; - - /* Open .debug_frame section. */ - cfi_seg = subseg_new (".debug_frame", 0); - bfd_set_section_flags (stdoutput, cfi_seg, - SEC_READONLY | SEC_DEBUGGING); - subseg_set (cfi_seg, 0); - record_alignment (cfi_seg, alignment); - - for (fde = all_fde_data; fde ; fde = fde->next) - { - struct cfi_insn_data *first; - - if (fde->end_address == NULL) + do + { + ccseg = NULL; + cfi_seg = NULL; + seek_next_seg = 0; + for (cie = cie_root; cie; cie = cie_next) { - as_bad (_("open CFI at the end of file; missing .cfi_endproc directive")); - fde->end_address = fde->start_address; + cie_next = cie->next; + free ((void *) cie); } + cie_root = NULL; - fde->per_encoding = DW_EH_PE_omit; - fde->lsda_encoding = DW_EH_PE_omit; - cfi_change_reg_numbers (fde->data); - cie = select_cie_for_fde (fde, FALSE, &first, alignment); - output_fde (fde, cie, FALSE, first, alignment); + for (fde = all_fde_data; fde ; fde = fde->next) + { + if (fde->handled != 0) + continue; + if (seek_next_seg && fde->cseg != ccseg) + continue; + if (!seek_next_seg) + { + ccseg = fde->cseg; + /* Open .debug_frame section. */ + cfi_seg = get_cfi_seg (ccseg, ".debug_frame", + SEC_READONLY | SEC_DEBUGGING, + alignment); + } + fde->handled = 1; + seek_next_seg = 1; + if (fde->end_address == NULL) + { + as_bad (_("open CFI at the end of file; missing .cfi_endproc directive")); + fde->end_address = fde->start_address; + } + + fde->per_encoding = DW_EH_PE_omit; + fde->lsda_encoding = DW_EH_PE_omit; + cfi_change_reg_numbers (fde->data, ccseg); + cie = select_cie_for_fde (fde, FALSE, &first, alignment); + output_fde (fde, cie, FALSE, first, alignment); + } } + while (seek_next_seg != 0); + + for (fde = all_fde_data; fde ; fde = fde->next) + fde->handled = 0; } } Index: src/gas/ehopt.c =================================================================== --- src.orig/gas/ehopt.c 2011-04-16 12:06:37.754473700 +0200 +++ src/gas/ehopt.c 2011-04-16 12:09:55.252923900 +0200 @@ -120,7 +120,7 @@ get_cie_info (struct cie_info *info) /* First make sure that the CIE Identifier Tag is 0/-1. */ - if (strcmp (segment_name (now_seg), ".debug_frame") == 0) + if (strncmp (segment_name (now_seg), ".debug_frame", 12) == 0) CIE_id = (char)0xff; else CIE_id = 0; @@ -285,9 +285,9 @@ check_eh_frame (expressionS *exp, unsign #endif /* Select the proper section data. */ - if (strcmp (segment_name (now_seg), ".eh_frame") == 0) + if (strncmp (segment_name (now_seg), ".eh_frame", 9) == 0) d = &eh_frame_data; - else if (strcmp (segment_name (now_seg), ".debug_frame") == 0) + else if (strncmp (segment_name (now_seg), ".debug_frame", 12) == 0) d = &debug_frame_data; else return 0; Index: src/ld/scripttempl/alphavms.sc =================================================================== --- src.orig/ld/scripttempl/alphavms.sc 2011-04-16 12:06:37.771473700 +0200 +++ src/ld/scripttempl/alphavms.sc 2011-04-16 12:09:55.254924000 +0200 @@ -29,7 +29,7 @@ SECTIONS *(\$LITERAL\$) *(\$READONLY\$) *(\$READONLY_ADDR\$) - *(eh_frame) + *(eh_frame) *(eh_frame\$*) *(eh_frame.*) *(jcr) *(ctors) *(dtors) Index: src/ld/scripttempl/armbpabi.sc =================================================================== --- src.orig/ld/scripttempl/armbpabi.sc 2011-04-16 12:06:37.784473700 +0200 +++ src/ld/scripttempl/armbpabi.sc 2011-04-16 12:09:55.257924200 +0200 @@ -241,7 +241,7 @@ cat < ${DATA_MEMORY}} /* C++ exception support. */ - .eh_frame ${RELOCATING-0} : { KEEP (*(.eh_frame)) } ${RELOCATING+ > ${DATA_MEMORY}} + .eh_frame ${RELOCATING-0} : { KEEP (*(.eh_frame) *(.eh_frame\$*) *(.eh_frame.*)) } ${RELOCATING+ > ${DATA_MEMORY}} .gcc_except_table ${RELOCATING-0} : { *(.gcc_except_table) } ${RELOCATING+ > ${DATA_MEMORY}} /* Java class registration support. */ @@ -211,7 +211,7 @@ SECTIONS .debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } + .debug_frame 0 : { *(.debug_frame*) } .debug_str 0 : { *(.debug_str) } .debug_loc 0 : { *(.debug_loc) } .debug_macinfo 0 : { *(.debug_macinfo) } Index: src/ld/scripttempl/elfi370.sc =================================================================== --- src.orig/ld/scripttempl/elfi370.sc 2011-04-16 12:06:37.886473700 +0200 +++ src/ld/scripttempl/elfi370.sc 2011-04-16 12:09:55.284925700 +0200 @@ -203,7 +203,7 @@ SECTIONS .debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } + .debug_frame 0 : { *(.debug_frame*) } .debug_str 0 : { *(.debug_str) } .debug_loc 0 : { *(.debug_loc) } .debug_macinfo 0 : { *(.debug_macinfo) } Index: src/ld/scripttempl/elfm68hc11.sc =================================================================== --- src.orig/ld/scripttempl/elfm68hc11.sc 2011-04-16 12:06:37.898473700 +0200 +++ src/ld/scripttempl/elfm68hc11.sc 2011-04-16 12:09:55.286925800 +0200 @@ -325,7 +325,7 @@ SECTIONS .eh_frame ${RELOCATING-0} : { - KEEP (*(.eh_frame)) + KEEP (*(.eh_frame) *(.eh_frame\$*) *(.eh_frame.*)) } ${RELOCATING+ > ${TEXT_MEMORY}} .gcc_except_table ${RELOCATING-0} : @@ -452,7 +452,7 @@ SECTIONS .debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } + .debug_frame 0 : { *(.debug_frame*) } .debug_str 0 : { *(.debug_str) } .debug_loc 0 : { *(.debug_loc) } .debug_macinfo 0 : { *(.debug_macinfo) } Index: src/ld/scripttempl/elfm68hc12.sc =================================================================== --- src.orig/ld/scripttempl/elfm68hc12.sc 2011-04-16 12:06:37.905473700 +0200 +++ src/ld/scripttempl/elfm68hc12.sc 2011-04-16 12:09:55.288926000 +0200 @@ -324,7 +324,7 @@ SECTIONS .eh_frame ${RELOCATING-0} : { - KEEP (*(.eh_frame)) + KEEP (*(.eh_frame) *(.eh_frame\$*) *(.eh_frame.*)) } ${RELOCATING+ > ${TEXT_MEMORY}} .gcc_except_table ${RELOCATING-0} : @@ -455,7 +455,7 @@ SECTIONS .debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } + .debug_frame 0 : { *(.debug_frame*) } .debug_str 0 : { *(.debug_str) } .debug_loc 0 : { *(.debug_loc) } .debug_macinfo 0 : { *(.debug_macinfo) } Index: src/ld/scripttempl/elfmicroblaze.sc =================================================================== --- src.orig/ld/scripttempl/elfmicroblaze.sc 2011-04-16 12:06:37.918473700 +0200 +++ src/ld/scripttempl/elfmicroblaze.sc 2011-04-16 12:09:55.290926100 +0200 @@ -142,7 +142,7 @@ SECTIONS /* Added by Sathya to handle C++ exceptions */ .eh_frame : { - ${RELOCATING+*(.eh_frame)} + ${RELOCATING+*(.eh_frame) *(.eh_frame\$*) *(.eh_frame.*)} } .jcr : { Index: src/ld/scripttempl/elfxtensa.sc =================================================================== --- src.orig/ld/scripttempl/elfxtensa.sc 2011-04-16 12:06:37.935473700 +0200 +++ src/ld/scripttempl/elfxtensa.sc 2011-04-16 12:09:55.293926200 +0200 @@ -429,7 +429,7 @@ cat < ROM} - .eh_frame : { KEEP (*(.eh_frame)) } ${RELOCATING+> ROM} + .eh_frame : { KEEP (*(.eh_frame) *(.eh_frame\$*) *(.eh_frame.*)) } ${RELOCATING+> ROM} .gcc_except_table : { *(.gcc_except_table) *(.gcc_except_table.*) } ${RELOCATING+> ROM} .plt : { *(.plt) } ${RELOCATING+> ROM} @@ -222,7 +222,7 @@ SECTIONS .debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } + .debug_frame 0 : { *(.debug_frame*) } .debug_str 0 : { *(.debug_str) } .debug_loc 0 : { *(.debug_loc) } .debug_macinfo 0 : { *(.debug_macinfo) } Index: src/bfd/coffcode.h =================================================================== --- src.orig/bfd/coffcode.h 2011-04-16 12:06:37.720473700 +0200 +++ src/bfd/coffcode.h 2011-04-17 10:45:28.910093500 +0200 @@ -658,7 +658,10 @@ sec_to_styp_flags (const char *sec_name, /* FIXME: There is no gas syntax to specify the debug section flag. */ if (is_dbg) - sec_flags = SEC_DEBUGGING | SEC_READONLY; + { + sec_flags &= (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD); + sec_flags |= SEC_DEBUGGING | SEC_READONLY; + } /* skip LOAD */ /* READONLY later */ Index: src/ld/scripttempl/elf.sc =================================================================== --- src.orig/ld/scripttempl/elf.sc 2011-04-16 12:06:37.798473700 +0200 +++ src/ld/scripttempl/elf.sc 2011-04-16 12:09:55.328928200 +0200 @@ -469,7 +469,7 @@ cat <