2011-05-18  Tristan Gingold  <gingold@adacore.com>

	* libxcoff.h (struct xcoff_dwsect_name): New type.
	(XCOFF_DWSECT_NBR_NAMES): New macro.
	(xcoff_dwsect_names): Declare.
	* coffcode.h (sec_to_styp_flags): Handle xcoff dwarf sections.
	(styp_to_sec_flags): Ditto.
	(coff_new_section_hook): Ditto.
	(coff_slurp_symbol_table): Handle C_DWARF and C_INFO.
	* coff-rs6000.c (xcoff_dwsect_name): New variable.

gas
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.

gas/testsuite
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.
This commit is contained in:
Tristan Gingold 2011-05-18 07:58:36 +00:00
parent cef6e90a3e
commit 85645aed85
13 changed files with 392 additions and 23 deletions

View file

@ -1,3 +1,14 @@
2011-05-18 Tristan Gingold <gingold@adacore.com>
* libxcoff.h (struct xcoff_dwsect_name): New type.
(XCOFF_DWSECT_NBR_NAMES): New macro.
(xcoff_dwsect_names): Declare.
* coffcode.h (sec_to_styp_flags): Handle xcoff dwarf sections.
(styp_to_sec_flags): Ditto.
(coff_new_section_hook): Ditto.
(coff_slurp_symbol_table): Handle C_DWARF and C_INFO.
* coff-rs6000.c (xcoff_dwsect_name): New variable.
2011-05-17 Tomohiro Kashiwada <kikairoya@gmail.com>
PR ld/12759

View file

@ -3862,6 +3862,18 @@ static unsigned long xcoff_glink_code[9] =
0x00000000, /* traceback table */
};
/* Table to convert DWARF flags to section names. */
const struct xcoff_dwsect_name xcoff_dwsect_names[] = {
{ SSUBTYP_DWINFO, ".dwinfo", TRUE },
{ SSUBTYP_DWLINE, ".dwline", TRUE },
{ SSUBTYP_DWPBNMS, ".dwpbnms", TRUE },
{ SSUBTYP_DWPBTYP, ".dwpbtyp", TRUE },
{ SSUBTYP_DWARNGE, ".dwarnge", TRUE },
{ SSUBTYP_DWABREV, ".dwabrev", FALSE },
{ SSUBTYP_DWSTR, ".dwstr", TRUE },
{ SSUBTYP_DWRNGES, ".dwrnges", TRUE }
};
static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
{

View file

@ -581,6 +581,17 @@ sec_to_styp_flags (const char *sec_name, flagword sec_flags)
{
styp_flags = STYP_TYPCHK;
}
else if (sec_flags & SEC_DEBUGGING)
{
int i;
for (i = 0; i < XCOFF_DWSECT_NBR_NAMES; i++)
if (!strcmp (sec_name, xcoff_dwsect_names[i].name))
{
styp_flags = STYP_DWARF | xcoff_dwsect_names[i].flag;
break;
}
}
#endif
/* Try and figure out what it should be */
else if (sec_flags & SEC_CODE)
@ -776,6 +787,10 @@ styp_to_sec_flags (bfd *abfd ATTRIBUTE_UNUSED,
}
else if (styp_flags & STYP_PAD)
sec_flags = 0;
#ifdef RS6000COFF_C
else if (styp_flags & STYP_DWARF)
sec_flags |= SEC_DEBUGGING;
#endif
else if (strcmp (name, _TEXT) == 0)
{
if (sec_flags & SEC_NEVER_LOAD)
@ -1717,6 +1732,7 @@ coff_new_section_hook (bfd * abfd, asection * section)
{
combined_entry_type *native;
bfd_size_type amt;
unsigned char sclass = C_STAT;
section->alignment_power = COFF_DEFAULT_SECTION_ALIGNMENT_POWER;
@ -1724,9 +1740,22 @@ coff_new_section_hook (bfd * abfd, asection * section)
if (bfd_xcoff_text_align_power (abfd) != 0
&& strcmp (bfd_get_section_name (abfd, section), ".text") == 0)
section->alignment_power = bfd_xcoff_text_align_power (abfd);
if (bfd_xcoff_data_align_power (abfd) != 0
else if (bfd_xcoff_data_align_power (abfd) != 0
&& strcmp (bfd_get_section_name (abfd, section), ".data") == 0)
section->alignment_power = bfd_xcoff_data_align_power (abfd);
else
{
int i;
for (i = 0; i < XCOFF_DWSECT_NBR_NAMES; i++)
if (strcmp (bfd_get_section_name (abfd, section),
xcoff_dwsect_names[i].name) == 0)
{
section->alignment_power = 0;
sclass = C_DWARF;
break;
}
}
#endif
/* Set up the section symbol. */
@ -1750,7 +1779,7 @@ coff_new_section_hook (bfd * abfd, asection * section)
for n_numaux is already correct. */
native->u.syment.n_type = T_NULL;
native->u.syment.n_sclass = C_STAT;
native->u.syment.n_sclass = sclass;
coffsymbol (section->symbol)->native = native;
@ -4754,6 +4783,10 @@ coff_slurp_symbol_table (bfd * abfd)
case C_THUMBSTAT: /* Thumb static. */
case C_THUMBLABEL: /* Thumb label. */
case C_THUMBSTATFUNC:/* Thumb static function. */
#endif
#ifdef RS6000COFF_C
case C_DWARF: /* A label in a dwarf section. */
case C_INFO: /* A label in a comment section. */
#endif
case C_LABEL: /* Label. */
if (src->u.syment.n_scnum == N_DEBUG)

View file

@ -235,4 +235,26 @@ bfd_boolean xcoff_reloc_type_toc (XCOFF_RELOC_FUNCTION_ARGS);
bfd_boolean xcoff_reloc_type_ba (XCOFF_RELOC_FUNCTION_ARGS);
bfd_boolean xcoff_reloc_type_crel (XCOFF_RELOC_FUNCTION_ARGS);
/* Structure to describe dwarf sections.
Useful to convert from XCOFF section name to flag and vice-versa.
Also mark if section has a length field at the beginning. */
struct xcoff_dwsect_name {
/* A XCOFF dwarf section is identified by its name. */
unsigned int flag;
/* Corresponding XCOFF section name. */
const char *name;
/* True if size must be prepended. */
bfd_boolean def_size;
};
/* Number of entries in the array. The number is known and public so that user
can 'extend' this array by index. */
#define XCOFF_DWSECT_NBR_NAMES 8
/* The dwarf sections array. */
extern const struct xcoff_dwsect_name
xcoff_dwsect_names[XCOFF_DWSECT_NBR_NAMES];
#endif /* LIBXCOFF_H */

View file

@ -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.

View file

@ -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);

View file

@ -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

View file

@ -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[];

View file

@ -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,

View file

@ -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"
}

View file

@ -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 ................

View file

@ -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 ................

View file

@ -0,0 +1,8 @@
.dwsect 0x10000,Ldwinfo_0
.short 2
.dwsect 0x10000,Ldwinfo_1
.short 3
.dwsect 0x10000,Ldwinfo_0
.short 1
.short 4