aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog22
-rw-r--r--gas/config/obj-coff.c11
-rw-r--r--gas/config/tc-ppc.c235
-rw-r--r--gas/config/tc-ppc.h28
-rw-r--r--gas/testsuite/ChangeLog7
-rw-r--r--gas/testsuite/gas/ppc/aix.exp3
-rw-r--r--gas/testsuite/gas/ppc/xcoff-dwsect-1-32.d9
-rw-r--r--gas/testsuite/gas/ppc/xcoff-dwsect-1-64.d10
-rw-r--r--gas/testsuite/gas/ppc/xcoff-dwsect-1.s8
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
+