diff options
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 22 | ||||
-rw-r--r-- | gas/config/obj-coff.c | 11 | ||||
-rw-r--r-- | gas/config/tc-ppc.c | 235 | ||||
-rw-r--r-- | gas/config/tc-ppc.h | 28 | ||||
-rw-r--r-- | gas/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gas/testsuite/gas/ppc/aix.exp | 3 | ||||
-rw-r--r-- | gas/testsuite/gas/ppc/xcoff-dwsect-1-32.d | 9 | ||||
-rw-r--r-- | gas/testsuite/gas/ppc/xcoff-dwsect-1-64.d | 10 | ||||
-rw-r--r-- | gas/testsuite/gas/ppc/xcoff-dwsect-1.s | 8 |
9 files changed, 312 insertions, 21 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 88b266e..4db0f47 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,25 @@ +2011-05-18 Tristan Gingold <gingold@adacore.com> + + * config/tc-ppc.h (ppc_tc_sy): Reorder fields. + Put size into an union with dw. + (OBJ_COPY_SYMBOL_ATTRIBUTES): Adjust. + (ppc_xcoff_end): Declare. + (md_end): Define. + * config/tc-ppc.c: Add includes for xcoff. + (ppc_dwsect): New function. + (md_pseudo_table): Add dwsect. + (struct dw_subsection): New. + (dw_sections): New. + (ppc_change_debug_section): New function. + (ppc_xcoff_end): Ditto. + (ppc_function): Adjust for ppc_tc_sy. + (ppc_symbol_new_hook): Ditto. + (ppc_frob_symbol): Ditto. + (ppc_frob_section): Do not set vma for debug sections. + (ppc_fix_adjustable): Return true for debug sections. + * config/obj-coff.c: Add includes for xcoff. + (coff_frob_section): Handle dwarf section. + 2011-05-17 Nick Clifton <nickc@redhat.com> * po/fi.po: New Finnish translation. diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c index fec6589..d481026 100644 --- a/gas/config/obj-coff.c +++ b/gas/config/obj-coff.c @@ -31,6 +31,10 @@ #include "coff/pe.h" #endif +#ifdef OBJ_XCOFF +#include "coff/xcoff.h" +#endif + #define streq(a,b) (strcmp ((a), (b)) == 0) #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0) @@ -1762,8 +1766,13 @@ coff_frob_section (segT sec) #endif { symbolS *secsym = section_symbol (sec); + unsigned char sclass = C_STAT; - S_SET_STORAGE_CLASS (secsym, C_STAT); +#ifdef OBJ_XCOFF + if (bfd_get_section_flags (stdoutput, sec) & SEC_DEBUGGING) + sclass = C_DWARF; +#endif + S_SET_STORAGE_CLASS (secsym, sclass); S_SET_NUMBER_AUXILIARY (secsym, 1); SF_SET_STATICS (secsym); SA_SET_SCN_SCNLEN (secsym, size); diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index 045a8aa..9a64d4a 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -35,6 +35,11 @@ #include "coff/pe.h" #endif +#ifdef OBJ_XCOFF +#include "coff/xcoff.h" +#include "libxcoff.h" +#endif + /* This is the assembler for the PowerPC or POWER (RS/6000) chips. */ /* Tell the main code what the endianness is. */ @@ -104,6 +109,7 @@ static void ppc_ec (int); static void ppc_ef (int); static void ppc_es (int); static void ppc_csect (int); +static void ppc_dwsect (int); static void ppc_change_csect (symbolS *, offsetT); static void ppc_function (int); static void ppc_extern (int); @@ -214,6 +220,7 @@ const pseudo_typeS md_pseudo_table[] = { "bi", ppc_biei, 0 }, { "bs", ppc_bs, 0 }, { "csect", ppc_csect, 0 }, + { "dwsect", ppc_dwsect, 0 }, { "data", ppc_section, 'd' }, { "eb", ppc_eb, 0 }, { "ec", ppc_ec, 0 }, @@ -982,6 +989,28 @@ static symbolS *ppc_current_block; cause BFD to set the section number of a symbol to N_DEBUG. */ static asection *ppc_coff_debug_section; +/* Structure to set the length field of the dwarf sections. */ +struct dw_subsection { + /* Subsections are simply linked. */ + struct dw_subsection *link; + + /* The subsection number. */ + subsegT subseg; + + /* Expression to compute the length of the section. */ + expressionS end_exp; +}; + +static struct dw_section { + /* Corresponding section. */ + segT sect; + + /* Simply linked list of subsections with a label. */ + struct dw_subsection *list_subseg; + + /* The anonymous subsection. */ + struct dw_subsection *anon_subseg; +} dw_sections[XCOFF_DWSECT_NBR_NAMES]; #endif /* OBJ_XCOFF */ #ifdef TE_PE @@ -1186,7 +1215,7 @@ md_parse_option (int c, char *arg) as_bad (_("--nops needs a numeric argument")); } break; - + default: return 0; } @@ -3478,6 +3507,158 @@ ppc_change_csect (symbolS *sym, offsetT align) ppc_current_csect = sym; } +static void +ppc_change_debug_section (unsigned int idx, subsegT subseg) +{ + segT sec; + flagword oldflags; + const struct xcoff_dwsect_name *dw = &xcoff_dwsect_names[idx]; + + sec = subseg_new (dw->name, subseg); + oldflags = bfd_get_section_flags (stdoutput, sec); + if (oldflags == SEC_NO_FLAGS) + { + /* Just created section. */ + gas_assert (dw_sections[idx].sect == NULL); + + bfd_set_section_flags (stdoutput, sec, SEC_DEBUGGING); + bfd_set_section_alignment (stdoutput, sec, 0); + dw_sections[idx].sect = sec; + } + + /* Not anymore in a csect. */ + ppc_current_csect = NULL; +} + +/* The .dwsect pseudo-op. Defines a DWARF section. Syntax is: + .dwsect flag [, opt-label ] +*/ + +static void +ppc_dwsect (int ignore ATTRIBUTE_UNUSED) +{ + offsetT flag; + symbolS *opt_label; + const struct xcoff_dwsect_name *dw; + struct dw_subsection *subseg; + struct dw_section *dws; + int i; + + /* Find section. */ + flag = get_absolute_expression (); + dw = NULL; + for (i = 0; i < XCOFF_DWSECT_NBR_NAMES; i++) + if (xcoff_dwsect_names[i].flag == flag) + { + dw = &xcoff_dwsect_names[i]; + break; + } + + /* Parse opt-label. */ + if (*input_line_pointer == ',') + { + const char *label; + char c; + + ++input_line_pointer; + + label = input_line_pointer; + c = get_symbol_end (); + opt_label = symbol_find_or_make (label); + *input_line_pointer = c; + } + else + opt_label = NULL; + + demand_empty_rest_of_line (); + + /* Return now in case of unknown subsection. */ + if (dw == NULL) + { + as_bad (_("No known dwarf XCOFF section for flag 0x%08x\n"), + (unsigned)flag); + return; + } + + /* Find the subsection. */ + dws = &dw_sections[i]; + subseg = NULL; + if (opt_label != NULL && S_IS_DEFINED (opt_label)) + { + /* Sanity check (note that in theory S_GET_SEGMENT mustn't be null). */ + if (dws->sect == NULL || S_GET_SEGMENT (opt_label) != dws->sect) + { + as_bad (_("label %s was not defined in this dwarf section"), + S_GET_NAME (opt_label)); + subseg = dws->anon_subseg; + opt_label = NULL; + } + else + subseg = symbol_get_tc (opt_label)->u.dw; + } + + if (subseg != NULL) + { + /* Switch to the subsection. */ + ppc_change_debug_section (i, subseg->subseg); + } + else + { + /* Create a new dw subsection. */ + subseg = (struct dw_subsection *) + xmalloc (sizeof (struct dw_subsection)); + + if (opt_label == NULL) + { + /* The anonymous one. */ + subseg->subseg = 0; + subseg->link = NULL; + dws->anon_subseg = subseg; + } + else + { + /* A named one. */ + if (dws->list_subseg != NULL) + subseg->subseg = dws->list_subseg->subseg + 1; + else + subseg->subseg = 1; + + subseg->link = dws->list_subseg; + dws->list_subseg = subseg; + symbol_get_tc (opt_label)->u.dw = subseg; + } + + ppc_change_debug_section (i, subseg->subseg); + + if (dw->def_size) + { + /* Add the length field. */ + expressionS *exp = &subseg->end_exp; + int sz; + + if (opt_label != NULL) + symbol_set_value_now (opt_label); + + /* Add the length field. Note that according to the AIX assembler + manual, the size of the length field is 4 for powerpc32 but + 12 for powerpc64. */ + if (ppc_obj64) + { + /* Write the 64bit marker. */ + md_number_to_chars (frag_more (4), -1, 4); + } + + exp->X_op = O_subtract; + exp->X_op_symbol = symbol_temp_new_now (); + exp->X_add_symbol = symbol_temp_make (); + + sz = ppc_obj64 ? 8 : 4; + exp->X_add_number = -sz; + emit_expr (exp, sz); + } + } +} + /* This function handles the .text and .data pseudo-ops. These pseudo-ops aren't really used by XCOFF; we implement them for the convenience of people who aren't used to XCOFF. */ @@ -3865,11 +4046,9 @@ ppc_function (int ignore ATTRIBUTE_UNUSED) { /* The fifth argument is the function size. */ ++input_line_pointer; - symbol_get_tc (ext_sym)->size = symbol_new ("L0\001", - absolute_section, - (valueT) 0, - &zero_address_frag); - pseudo_set (symbol_get_tc (ext_sym)->size); + symbol_get_tc (ext_sym)->u.size = symbol_new + ("L0\001", absolute_section,(valueT) 0, &zero_address_frag); + pseudo_set (symbol_get_tc (ext_sym)->u.size); } } } @@ -4231,6 +4410,33 @@ ppc_vbyte (int dummy ATTRIBUTE_UNUSED) cons (byte_count); } +void +ppc_xcoff_end (void) +{ + int i; + + for (i = 0; i < XCOFF_DWSECT_NBR_NAMES; i++) + { + struct dw_section *dws = &dw_sections[i]; + struct dw_subsection *dwss; + + if (dws->anon_subseg) + { + dwss = dws->anon_subseg; + dwss->link = dws->list_subseg; + } + else + dwss = dws->list_subseg; + + for (; dwss != NULL; dwss = dwss->link) + if (dwss->end_exp.X_add_symbol != NULL) + { + subseg_set (dws->sect, dwss->subseg); + symbol_set_value_now (dwss->end_exp.X_add_symbol); + } + } +} + #endif /* OBJ_XCOFF */ #if defined (OBJ_XCOFF) || defined (OBJ_ELF) @@ -5057,7 +5263,8 @@ ppc_symbol_new_hook (symbolS *sym) tc->real_name = NULL; tc->subseg = 0; tc->align = 0; - tc->size = NULL; + tc->u.size = NULL; + tc->u.dw = NULL; tc->within = NULL; if (ppc_stab_symbol) @@ -5215,11 +5422,11 @@ ppc_frob_symbol (symbolS *sym) if (ppc_last_function != (symbolS *) NULL) as_bad (_("two .function pseudo-ops with no intervening .ef")); ppc_last_function = sym; - if (symbol_get_tc (sym)->size != (symbolS *) NULL) + if (symbol_get_tc (sym)->u.size != (symbolS *) NULL) { - resolve_symbol_value (symbol_get_tc (sym)->size); + resolve_symbol_value (symbol_get_tc (sym)->u.size); SA_SET_SYM_FSIZE (sym, - (long) S_GET_VALUE (symbol_get_tc (sym)->size)); + (long) S_GET_VALUE (symbol_get_tc (sym)->u.size)); } } else if (S_GET_STORAGE_CLASS (sym) == C_FCN @@ -5486,6 +5693,10 @@ ppc_frob_section (asection *sec) { static bfd_vma vma = 0; + /* Dwarf sections start at 0. */ + if (bfd_get_section_flags (NULL, sec) & SEC_DEBUGGING) + return; + vma = md_section_align (sec, vma); bfd_set_section_vma (stdoutput, sec, vma); vma += bfd_section_size (stdoutput, sec); @@ -5581,6 +5792,10 @@ ppc_fix_adjustable (fixS *fix) if (symseg == absolute_section) return 0; + /* Always adjust symbols in debugging sections. */ + if (bfd_get_section_flags (stdoutput, symseg) & SEC_DEBUGGING) + return 1; + if (ppc_toc_csect != (symbolS *) NULL && fix->fx_addsy != ppc_toc_csect && symseg == data_section diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h index 08f0aee..9706f6f 100644 --- a/gas/config/tc-ppc.h +++ b/gas/config/tc-ppc.h @@ -129,26 +129,31 @@ struct ppc_tc_sy { /* We keep a few linked lists of symbols. */ symbolS *next; + /* The real name, if the symbol was renamed. */ + char *real_name; /* Non-zero if the symbol should be output. The RS/6000 assembler only outputs symbols that are external or are mentioned in a .globl or .lglobl statement. */ - int output; + unsigned char output; /* The symbol class. */ - int symbol_class; - /* The real name, if the symbol was renamed. */ - char *real_name; + short symbol_class; + /* For a csect or common symbol, the alignment to use. */ + unsigned char align; /* For a csect symbol, the subsegment we are using. This is zero for symbols that are not csects. */ subsegT subseg; - /* For a csect or common symbol, the alignment to use. */ - int align; - /* For a function symbol, a symbol whose value is the size. The - field is NULL if there is no size. */ - symbolS *size; /* For a csect symbol, the last symbol which has been defined in this csect, or NULL if none have been defined so far. For a .bs symbol, the referenced csect symbol. */ symbolS *within; + union + { + /* For a function symbol, a symbol whose value is the size. The + field is NULL if there is no size. */ + symbolS *size; + /* For a dwarf symbol, the corresponding dwarf subsection. */ + struct dw_subsection *dw; + } u; }; #define TC_SYMFIELD_TYPE struct ppc_tc_sy @@ -193,12 +198,15 @@ extern void ppc_adjust_symtab (void); do { \ if (SF_GET_GET_SEGMENT (dest)) \ S_SET_SEGMENT (dest, S_GET_SEGMENT (src)); \ - symbol_get_tc (dest)->size = symbol_get_tc (src)->size; \ + symbol_get_tc (dest)->u = symbol_get_tc (src)->u; \ symbol_get_tc (dest)->align = symbol_get_tc (src)->align; \ symbol_get_tc (dest)->symbol_class = symbol_get_tc (src)->symbol_class; \ symbol_get_tc (dest)->within = symbol_get_tc (src)->within; \ } while (0) +extern void ppc_xcoff_end (void); +#define md_end ppc_xcoff_end + #endif /* OBJ_XCOFF */ extern const char ppc_symbol_chars[]; diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 3bc3582..499bb04 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2011-05-18 Tristan Gingold <gingold@adacore.com> + + * gas/ppc/xcoff-dwsect-1-32.d: New test. + * gas/ppc/xcoff-dwsect-1-64.d: Ditto. + * gas/ppc/xcoff-dwsect-1.s: New file. + * gas/ppc/aix.exp (do_align_test): Add tests. + 2011-05-16 Hans-Peter Nilsson <hp@axis.com> * gas/cris/rd-brokw-pic-1.d, gas/cris/rd-brokw-pic-2.d, diff --git a/gas/testsuite/gas/ppc/aix.exp b/gas/testsuite/gas/ppc/aix.exp index 917f0d9..6dcfc4e 100644 --- a/gas/testsuite/gas/ppc/aix.exp +++ b/gas/testsuite/gas/ppc/aix.exp @@ -67,4 +67,7 @@ if [istarget powerpc-ibm-aix*] then { run_dump_test "xcoff-branch-1-64" run_list_test "xcoff-ref-1" + + run_dump_test "xcoff-dwsect-1-32" + run_dump_test "xcoff-dwsect-1-64" } diff --git a/gas/testsuite/gas/ppc/xcoff-dwsect-1-32.d b/gas/testsuite/gas/ppc/xcoff-dwsect-1-32.d new file mode 100644 index 0000000..a03cf42 --- /dev/null +++ b/gas/testsuite/gas/ppc/xcoff-dwsect-1-32.d @@ -0,0 +1,9 @@ +#as: -a32 +#source: xcoff-dwsect-1.s +#objdump: -j .dwinfo -s +#name: XCOFF dwsect test 1 (32-bit) + +dump.o: file format aixcoff-rs6000 + +Contents of section \.dwinfo: + 0000 00000006 00020001 00040000 00020003 ................ diff --git a/gas/testsuite/gas/ppc/xcoff-dwsect-1-64.d b/gas/testsuite/gas/ppc/xcoff-dwsect-1-64.d new file mode 100644 index 0000000..e415a12 --- /dev/null +++ b/gas/testsuite/gas/ppc/xcoff-dwsect-1-64.d @@ -0,0 +1,10 @@ +#as: -a64 +#source: xcoff-dwsect-1.s +#objdump: -j .dwinfo -s +#name: XCOFF dwsect test 1 (64-bit) + +dump.o: file format aix.*coff64-rs6000 + +Contents of section \.dwinfo: + 0000 ffffffff 00000000 00000006 00020001 ................ + 0010 0004ffff ffff0000 00000000 00020003 ................ diff --git a/gas/testsuite/gas/ppc/xcoff-dwsect-1.s b/gas/testsuite/gas/ppc/xcoff-dwsect-1.s new file mode 100644 index 0000000..493f212 --- /dev/null +++ b/gas/testsuite/gas/ppc/xcoff-dwsect-1.s @@ -0,0 +1,8 @@ + .dwsect 0x10000,Ldwinfo_0 + .short 2 + .dwsect 0x10000,Ldwinfo_1 + .short 3 + .dwsect 0x10000,Ldwinfo_0 + .short 1 + .short 4 + |