This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Ping: RFC: add dwarf support for xcoff/AIX
- From: Tristan Gingold <gingold at adacore dot com>
- To: Richard Sandiford <rdsandiford at googlemail dot com>, Dave Korn <dave dot korn dot cygwin at gmail dot com>
- Cc: binutils <binutils at sourceware dot org>
- Date: Tue, 26 Apr 2011 09:43:35 +0200
- Subject: Ping: RFC: add dwarf support for xcoff/AIX
- References: <482268C0-87C5-466E-BB37-59F1DFB341F9@adacore.com>
Ping for:
On Apr 18, 2011, at 5:10 PM, Tristan Gingold wrote:
> Hi,
>
> this is a request for comment before formal submissions (mostly adding the ChangeLog entries).
>
> This patch adds support for dwarf sections on AIX. AIX 7 added dwarf support on xcoff, and we'd like to
> switch from stabs to dwarf on AIX.
>
> There are a few tricks:
>
> * because section names are limited to 8 characters, the standard dwarf names cannot be used. XCOFF defines
> alternate names (.dwinfo, .dwline...)
> But to simplify the interface with gdb and objdump, the xcoff back-end automatically canonicalize the names
> to the standard dwarf names. To do this I added a coff hook (expand_section_name) and a new coff macro
> (adjust_scnhdr_before_swap).
> Not sure that this conversion is a good idea, so comments are welcome here.
>
> * AIX as has a special pseudo for declaring dwarf sections: .dwsect However this pseudo does prepend the size.
> As this is very unusual (and would require more work in gcc), I choose to not implement it and to use the
> standard .section semantic (which was already present for convenience). Of course, nothing prevents from adding
> .dwsect later (the difficult part would be in gcc)
>
> * Unfortunately I don't have access to an AIX 7 machine, so I wasn't able to check wether AIX ld would accept object
> files produced by gas or not. Also, I am not sure about the behavior of csect with the dwarf sections. I will adjust
> this in case of bug reports.
>
> Tristan.
>
> diff --git a/bfd/coff-alpha.c b/bfd/coff-alpha.c
> index 12b49ac..c8284ff 100644
> --- a/bfd/coff-alpha.c
> +++ b/bfd/coff-alpha.c
> @@ -2305,7 +2305,8 @@ static const struct ecoff_backend_data alpha_ecoff_backend_data =
> alpha_ecoff_swap_filehdr_in, alpha_ecoff_swap_aouthdr_in,
> alpha_ecoff_swap_scnhdr_in, NULL,
> alpha_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
> - alpha_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
> + alpha_ecoff_mkobject_hook, coff_expand_section_name,
> + _bfd_ecoff_styp_to_sec_flags,
> _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
> NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> NULL, NULL, NULL, NULL
> diff --git a/bfd/coff-mips.c b/bfd/coff-mips.c
> index 34fda3a..1093ce6 100644
> --- a/bfd/coff-mips.c
> +++ b/bfd/coff-mips.c
> @@ -1317,7 +1317,8 @@ static const struct ecoff_backend_data mips_ecoff_backend_data =
> mips_ecoff_swap_filehdr_in, mips_ecoff_swap_aouthdr_in,
> mips_ecoff_swap_scnhdr_in, NULL,
> mips_ecoff_bad_format_hook, _bfd_ecoff_set_arch_mach_hook,
> - _bfd_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
> + _bfd_ecoff_mkobject_hook, coff_expand_section_name,
> + _bfd_ecoff_styp_to_sec_flags,
> _bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
> NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
> NULL, NULL, NULL
> diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c
> index 41bec09..14e9cf9 100644
> --- a/bfd/coff-rs6000.c
> +++ b/bfd/coff-rs6000.c
> @@ -54,6 +54,8 @@ extern unsigned int _bfd_xcoff_swap_aux_out
> (bfd *, PTR, int, int, int, int, PTR);
> static void xcoff_swap_reloc_in (bfd *, PTR, PTR);
> static unsigned int xcoff_swap_reloc_out (bfd *, PTR, PTR);
> +static void xcoff_adjust_scnhdr_before_swap
> + (bfd *, asection *, struct internal_scnhdr *);
>
> /* Forward declare xcoff_rtype2howto for coffcode.h macro. */
> void xcoff_rtype2howto (arelent *, struct internal_reloc *);
> @@ -112,6 +114,7 @@ extern int rs6000coff_core_file_failing_signal (bfd *abfd);
> #define coff_SWAP_aux_out _bfd_xcoff_swap_aux_out
> #define coff_swap_reloc_in xcoff_swap_reloc_in
> #define coff_swap_reloc_out xcoff_swap_reloc_out
> +#define coff_adjust_scnhdr_before_swap xcoff_adjust_scnhdr_before_swap
> #define NO_COFF_RELOCS
>
> #ifndef bfd_pe_print_pdata
> @@ -1126,6 +1129,55 @@ _bfd_xcoff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
>
> return NULL;
> }
> +
> +static void
> +xcoff_adjust_scnhdr_before_swap (bfd *abfd ATTRIBUTE_UNUSED,
> + asection *section,
> + struct internal_scnhdr *scnhdr)
> +{
> + const struct _bfd_xcoff_dw_section *sec;
> +
> + /* We only care about debugging sections. */
> + if ((bfd_get_section_flags (abfd, section) & SEC_DEBUGGING) == 0)
> + return;
> +
> + for (sec = _bfd_xcoff_dw_table; sec->xcoff_name; sec++)
> + if (strcmp (bfd_get_section_name (abfd, section), sec->elf_name) == 0)
> + {
> + memset (scnhdr->s_name, 0, sizeof (scnhdr->s_name));
> + strncpy (scnhdr->s_name, sec->xcoff_name, sizeof (scnhdr->s_name));
> + scnhdr->s_flags = sec->flag | STYP_DWARF;
> + return;
> + }
> +
> + /* We suppose this is a known section. */
> +}
> +
> +static bfd_boolean
> +xcoff_expand_section_name (bfd *abfd ATTRIBUTE_UNUSED,
> + struct internal_scnhdr *hdr ATTRIBUTE_UNUSED,
> + char **name,
> + flagword *flag)
> +{
> + const struct _bfd_xcoff_dw_section *sec;
> +
> + if ((hdr->s_flags & STYP_DWARF) == 0)
> + {
> + /* Not handled here. */
> + flag = SEC_NO_FLAGS;
> + *name = NULL;
> + return TRUE;
> + }
> + *flag = SEC_DEBUGGING | SEC_READONLY;
> + for (sec = _bfd_xcoff_dw_table; sec->xcoff_name; sec++)
> + if (hdr->s_flags == (long)(sec->flag | STYP_DWARF))
> + {
> + /* No need to allocate the name. */
> + *name = (char *)sec->elf_name;
> + return TRUE;
> + }
> + return TRUE;
> +}
>
>
> /* XCOFF archive support. The original version of this code was by
> Damon A. Permezel. It was enhanced to permit cross support, and
> @@ -3862,6 +3914,24 @@ static unsigned long xcoff_glink_code[9] =
> };
>
>
> +const struct _bfd_xcoff_dw_section _bfd_xcoff_dw_table[] =
> + {
> + { SSUBTYP_DWINFO, ".dwinfo", ".debug_info" },
> + { SSUBTYP_DWLINE, ".dwline", ".debug_line" },
> + { SSUBTYP_DWPBNMS, ".dwpbnms", ".debug_pubnames" },
> + { SSUBTYP_DWPBTYP, ".dwpbtyp", ".debug_pubtypes" },
> + { SSUBTYP_DWARNGE, ".dwarnge", ".debug_aranges" },
> + { SSUBTYP_DWABREV, ".dwabrev", ".debug_abbrev" },
> + { SSUBTYP_DWSTR, ".dwstr", ".debug_str" },
> + { SSUBTYP_DWRNGES, ".dwrnges", ".debug_ranges" },
> +
> + /* GNU extensions. Don't pollute the SSUBTYP_ name space,
> + use 0x47xx0000 (as 'G' is 0x47). */
> + { 0x47000000, ".dwframe", ".debug_frame" },
> + { 0x47010000, ".dwloc", ".debug_loc" },
> + { 0, NULL, NULL }
> + };
> +
> static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
> {
> { /* COFF backend, defined in libcoff.h. */
> @@ -3895,6 +3965,7 @@ static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
> coff_bad_format_hook,
> coff_set_arch_mach_hook,
> coff_mkobject_hook,
> + xcoff_expand_section_name,
> styp_to_sec_flags,
> coff_set_alignment_hook,
> coff_slurp_symbol_table,
> @@ -4148,6 +4219,7 @@ static const struct xcoff_backend_data_rec bfd_pmac_xcoff_backend_data =
> coff_bad_format_hook,
> coff_set_arch_mach_hook,
> coff_mkobject_hook,
> + xcoff_expand_section_name,
> styp_to_sec_flags,
> coff_set_alignment_hook,
> coff_slurp_symbol_table,
> diff --git a/bfd/coff-sh.c b/bfd/coff-sh.c
> index b77af7c..22db2ce 100644
> --- a/bfd/coff-sh.c
> +++ b/bfd/coff-sh.c
> @@ -3149,7 +3149,8 @@ static bfd_coff_backend_data bfd_coff_small_swap_table =
> #endif
> coff_swap_filehdr_in, coff_swap_aouthdr_in, coff_swap_scnhdr_in,
> coff_swap_reloc_in, coff_bad_format_hook, coff_set_arch_mach_hook,
> - coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook,
> + coff_mkobject_hook, coff_expand_section_name,
> + styp_to_sec_flags, coff_set_alignment_hook,
> coff_slurp_symbol_table, symname_in_debug_hook, coff_pointerize_aux_hook,
> coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
> coff_classify_symbol, coff_compute_section_file_positions,
> diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c
> index b154b67..375c242 100644
> --- a/bfd/coff64-rs6000.c
> +++ b/bfd/coff64-rs6000.c
> @@ -2617,6 +2617,7 @@ static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
> xcoff64_bad_format_hook,
> coff_set_arch_mach_hook,
> coff_mkobject_hook,
> + coff_expand_section_name,
> styp_to_sec_flags,
> coff_set_alignment_hook,
> coff_slurp_symbol_table,
> @@ -2874,6 +2875,7 @@ static const struct xcoff_backend_data_rec bfd_xcoff_aix5_backend_data =
> xcoff64_bad_format_hook,
> coff_set_arch_mach_hook,
> coff_mkobject_hook,
> + coff_expand_section_name,
> styp_to_sec_flags,
> coff_set_alignment_hook,
> coff_slurp_symbol_table,
> diff --git a/bfd/coffcode.h b/bfd/coffcode.h
> index 9db86b5..9a6146a 100644
> --- a/bfd/coffcode.h
> +++ b/bfd/coffcode.h
> @@ -1382,6 +1382,9 @@ Special entry points for gdb to swap in coff symbol table parts:
> . void * (*_bfd_coff_mkobject_hook)
> . (bfd *, void *, void *);
> .
> +. bfd_boolean (*_bfd_coff_expand_section_name)
> +. (bfd *, struct internal_scnhdr *, char **, flagword *);
> +.
> . bfd_boolean (*_bfd_styp_to_sec_flags_hook)
> . (bfd *, void *, const char *, asection *, flagword *);
> .
> @@ -1518,6 +1521,10 @@ Special entry points for gdb to swap in coff symbol table parts:
> . ((coff_backend_info (abfd)->_bfd_coff_mkobject_hook)\
> . (abfd, filehdr, aouthdr))
> .
> +.#define bfd_coff_expand_section_name(abfd, scnhdr, name_ptr, flags_ptr)\
> +. ((coff_backend_info (abfd)->_bfd_coff_expand_section_name)\
> +. (abfd, scnhdr, name_ptr, flags_ptr))
> +.
> .#define bfd_coff_styp_to_sec_flags_hook(abfd, scnhdr, name, section, flags_ptr)\
> . ((coff_backend_info (abfd)->_bfd_styp_to_sec_flags_hook)\
> . (abfd, scnhdr, name, section, flags_ptr))
> @@ -1892,6 +1899,9 @@ coff_set_alignment_hook (bfd *abfd, asection *section, void * scnhdr)
> struct internal_scnhdr *hdr = (struct internal_scnhdr *) scnhdr;
> asection *real_sec;
>
> + if (hdr->s_flags & STYP_DWARF)
> + section->alignment_power = 0;
> +
> if ((hdr->s_flags & STYP_OVRFLO) == 0)
> return;
>
> @@ -3779,6 +3789,11 @@ coff_write_object_contents (bfd * abfd)
> COFF_ENCODE_ALIGNMENT(section, current->alignment_power);
> #endif
>
> +#ifdef coff_adjust_scnhdr_before_swap
> + /* Do post-processing. */
> + coff_adjust_scnhdr_before_swap (abfd, current, §ion);
> +#endif
> +
> #ifdef COFF_IMAGE_WITH_PE
> /* Suppress output of the sections if they are null. ld
> includes the bss and data sections even if there is no size
> @@ -4752,6 +4767,9 @@ coff_slurp_symbol_table (bfd * abfd)
> case C_THUMBLABEL: /* Thumb label. */
> case C_THUMBSTATFUNC:/* Thumb static function. */
> #endif
> +#ifdef RS6000COFF_C
> + case C_DWARF: /* A label in a debugging section. */
> +#endif
> case C_LABEL: /* Label. */
> if (src->u.syment.n_scnum == N_DEBUG)
> dst->symbol.flags = BSF_DEBUGGING;
> @@ -5446,7 +5464,8 @@ static bfd_coff_backend_data bfd_coff_std_swap_table ATTRIBUTE_UNUSED =
> #endif
> coff_SWAP_filehdr_in, coff_SWAP_aouthdr_in, coff_SWAP_scnhdr_in,
> coff_SWAP_reloc_in, coff_bad_format_hook, coff_set_arch_mach_hook,
> - coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook,
> + coff_mkobject_hook, coff_expand_section_name, styp_to_sec_flags,
> + coff_set_alignment_hook,
> coff_slurp_symbol_table, symname_in_debug_hook, coff_pointerize_aux_hook,
> coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
> coff_classify_symbol, coff_compute_section_file_positions,
> diff --git a/bfd/coffgen.c b/bfd/coffgen.c
> index fc82d57..1530537 100644
> --- a/bfd/coffgen.c
> +++ b/bfd/coffgen.c
> @@ -44,20 +44,13 @@
> #include "coff/internal.h"
> #include "libcoff.h"
>
> -/* Take a section header read from a coff file (in HOST byte order),
> - and make a BFD "section" out of it. This is used by ECOFF. */
> -
> -static bfd_boolean
> -make_a_section_from_file (bfd *abfd,
> - struct internal_scnhdr *hdr,
> - unsigned int target_index)
> +bfd_boolean
> +coff_expand_section_name (bfd *abfd,
> + struct internal_scnhdr *hdr,
> + char **name,
> + flagword *flag)
> {
> - asection *return_section;
> - char *name;
> - bfd_boolean result = TRUE;
> - flagword flags;
> -
> - name = NULL;
> + flag = SEC_NO_FLAGS;
>
> /* Handle long section names as in PE. On reading, we want to
> accept long names if the format permits them at all, regardless
> @@ -90,13 +83,34 @@ make_a_section_from_file (bfd *abfd,
> strindex does not run us past the end, but right now we
> don't know the length of the string table. */
> strings += strindex;
> - name = (char *) bfd_alloc (abfd,
> + *name = (char *) bfd_alloc (abfd,
> (bfd_size_type) strlen (strings) + 1);
> - if (name == NULL)
> + if (*name == NULL)
> return FALSE;
> - strcpy (name, strings);
> + strcpy (*name, strings);
> }
> }
> + return TRUE;
> +}
> +
> +/* Take a section header read from a coff file (in HOST byte order),
> + and make a BFD "section" out of it. This is used by ECOFF. */
> +
> +static bfd_boolean
> +make_a_section_from_file (bfd *abfd,
> + struct internal_scnhdr *hdr,
> + unsigned int target_index)
> +{
> + asection *return_section;
> + char *name;
> + bfd_boolean result = TRUE;
> + flagword flags;
> +
> + name = NULL;
> + flags = SEC_NO_FLAGS;
> +
> + if (!bfd_coff_expand_section_name (abfd, hdr, &name, &flags))
> + return FALSE;
>
> if (name == NULL)
> {
> @@ -129,8 +143,9 @@ make_a_section_from_file (bfd *abfd,
> return_section->next = NULL;
> return_section->target_index = target_index;
>
> - if (! bfd_coff_styp_to_sec_flags_hook (abfd, hdr, name, return_section,
> - & flags))
> + if (flags == SEC_NO_FLAGS
> + && ! bfd_coff_styp_to_sec_flags_hook (abfd, hdr, name, return_section,
> + & flags))
> result = FALSE;
>
> return_section->flags = flags;
> diff --git a/bfd/libcoff-in.h b/bfd/libcoff-in.h
> index 9d24748..10cef08 100644
> --- a/bfd/libcoff-in.h
> +++ b/bfd/libcoff-in.h
> @@ -300,6 +300,8 @@ struct coff_link_hash_table
> #define coff_hash_table(p) ((struct coff_link_hash_table *) ((p)->hash))
>
> /* Functions in coffgen.c. */
> +extern bfd_boolean coff_expand_section_name
> + (bfd *, struct internal_scnhdr *, char **, flagword *);
> extern const bfd_target *coff_object_p
> (bfd *);
> extern struct bfd_section *coff_section_from_bfd_index
> diff --git a/bfd/libcoff.h b/bfd/libcoff.h
> index 4f73f10..a6b52fd 100644
> --- a/bfd/libcoff.h
> +++ b/bfd/libcoff.h
> @@ -304,6 +304,8 @@ struct coff_link_hash_table
> #define coff_hash_table(p) ((struct coff_link_hash_table *) ((p)->hash))
>
> /* Functions in coffgen.c. */
> +extern bfd_boolean coff_expand_section_name
> + (bfd *, struct internal_scnhdr *, char **, flagword *);
> extern const bfd_target *coff_object_p
> (bfd *);
> extern struct bfd_section *coff_section_from_bfd_index
> @@ -747,6 +749,9 @@ typedef struct
> void * (*_bfd_coff_mkobject_hook)
> (bfd *, void *, void *);
>
> + bfd_boolean (*_bfd_coff_expand_section_name)
> + (bfd *, struct internal_scnhdr *, char **, flagword *);
> +
> bfd_boolean (*_bfd_styp_to_sec_flags_hook)
> (bfd *, void *, const char *, asection *, flagword *);
>
> @@ -883,6 +888,10 @@ typedef struct
> ((coff_backend_info (abfd)->_bfd_coff_mkobject_hook)\
> (abfd, filehdr, aouthdr))
>
> +#define bfd_coff_expand_section_name(abfd, scnhdr, name_ptr, flags_ptr)\
> + ((coff_backend_info (abfd)->_bfd_coff_expand_section_name)\
> + (abfd, scnhdr, name_ptr, flags_ptr))
> +
> #define bfd_coff_styp_to_sec_flags_hook(abfd, scnhdr, name, section, flags_ptr)\
> ((coff_backend_info (abfd)->_bfd_styp_to_sec_flags_hook)\
> (abfd, scnhdr, name, section, flags_ptr))
> diff --git a/bfd/libxcoff.h b/bfd/libxcoff.h
> index 3900dd3..3daa470 100644
> --- a/bfd/libxcoff.h
> +++ b/bfd/libxcoff.h
> @@ -235,4 +235,19 @@ 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);
>
> +/* Table to translate dwarf sections. */
> +struct _bfd_xcoff_dw_section {
> + /* Type of the section (See SSUBTYPE_DW* in include/coff/xcoff.h). */
> + unsigned int flag;
> +
> + /* XCOFF section name. */
> + const char *xcoff_name;
> +
> + /* Corresponding ELF name. */
> + const char *elf_name;
> +};
> +
> +/* The table. Nul terminated. */
> +extern const struct _bfd_xcoff_dw_section _bfd_xcoff_dw_table[];
> +
> #endif /* LIBXCOFF_H */
> diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c
> index 7ff920a..b0d01fd 100644
> --- a/bfd/xcofflink.c
> +++ b/bfd/xcofflink.c
> @@ -1365,11 +1365,12 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
> If C_FILE or first time, handle special
>
> Advance esym, sym_hash, csect_hash ptrs. */
> - if (sym.n_sclass == C_FILE)
> + if (sym.n_sclass == C_FILE || sym.n_sclass == C_DWARF)
> csect = NULL;
> if (csect != NULL)
> *csect_cache = csect;
> - else if (first_csect == NULL || sym.n_sclass == C_FILE)
> + else if (first_csect == NULL
> + || sym.n_sclass == C_FILE || sym.n_sclass == C_DWARF)
> *csect_cache = coff_section_from_bfd_index (abfd, sym.n_scnum);
> else
> *csect_cache = NULL;
> @@ -2077,6 +2078,10 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
> /* Make sure that we have seen all the relocs. */
> for (o = abfd->sections; o != first_csect; o = o->next)
> {
> + /* Debugging sections have no csects. */
> + if (bfd_get_section_flags (abfd, o) & SEC_DEBUGGING)
> + continue;
> +
> /* Reset the section size and the line number count, since the
> data is now attached to the csects. Don't reset the size of
> the .debug section, since we need to read it below in
> @@ -3013,6 +3018,7 @@ xcoff_sweep (struct bfd_link_info *info)
> || o == xcoff_hash_table (info)->loader_section
> || o == xcoff_hash_table (info)->linkage_section
> || o == xcoff_hash_table (info)->descriptor_section
> + || (bfd_get_section_flags (sub, o) & SEC_DEBUGGING)
> || strcmp (o->name, ".debug") == 0)
> o->flags |= SEC_MARK;
> else
> @@ -4936,21 +4942,25 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *flinfo,
> this case, but I don't think it's worth it. */
> is = flinfo->internal_syms + r_symndx;
>
> - name = (_bfd_coff_internal_syment_name
> - (input_bfd, is, buf));
> + if (is->n_sclass != C_DWARF)
> + {
> + name = (_bfd_coff_internal_syment_name
> + (input_bfd, is, buf));
>
> - if (name == NULL)
> - return FALSE;
> + if (name == NULL)
> + return FALSE;
>
> - if (! ((*flinfo->info->callbacks->unattached_reloc)
> - (flinfo->info, name, input_bfd, o,
> - irel->r_vaddr)))
> - return FALSE;
> + if (!(*flinfo->info->callbacks->unattached_reloc)
> + (flinfo->info, name, input_bfd, o,
> + irel->r_vaddr))
> + return FALSE;
> + }
> }
> }
> }
>
> - if (xcoff_need_ldrel_p (flinfo->info, irel, h))
> + if ((o->flags & SEC_DEBUGGING) == 0
> + && xcoff_need_ldrel_p (flinfo->info, irel, h))
> {
> asection *sec;
>
> @@ -5849,8 +5859,7 @@ _bfd_xcoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
> {
> flinfo.ldsym = (xcoff_hash_table (info)->loader_section->contents
> + bfd_xcoff_ldhdrsz (abfd));
> - flinfo.ldrel = (xcoff_hash_table (info)->loader_section->contents
> - + bfd_xcoff_ldhdrsz (abfd)
> + flinfo.ldrel = (flinfo.ldsym
> + (xcoff_hash_table (info)->ldhdr.l_nsyms
> * bfd_xcoff_ldsymsz (abfd)));
> }
> @@ -6352,8 +6361,7 @@ _bfd_xcoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
> if (o)
> {
> BFD_ASSERT ((bfd_byte *) flinfo.ldrel
> - == (xcoff_hash_table (info)->loader_section->contents
> - + xcoff_hash_table (info)->ldhdr.l_impoff));
> + == (o->contents + xcoff_hash_table (info)->ldhdr.l_impoff));
> if (!bfd_set_section_contents (abfd, o->output_section, o->contents,
> (file_ptr) o->output_offset, o->size))
> goto error_return;
> diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c
> index fec6589..445a078 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 int sc = C_STAT;
>
> - S_SET_STORAGE_CLASS (secsym, C_STAT);
> +#ifdef OBJ_XCOFF
> + if (bfd_get_section_flags (stdoutput, sec) & SEC_DEBUGGING)
> + sc = C_DWARF;
> +#endif
> + S_SET_STORAGE_CLASS (secsym, sc);
> 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..439e597 100644
> --- a/gas/config/tc-ppc.c
> +++ b/gas/config/tc-ppc.c
> @@ -31,6 +31,11 @@
> #include "dwarf2dbg.h"
> #endif
>
> +#ifdef OBJ_XCOFF
> +#include "coff/xcoff.h"
> +#include "libxcoff.h"
> +#endif
> +
> #ifdef TE_PE
> #include "coff/pe.h"
> #endif
> @@ -3478,6 +3483,29 @@ ppc_change_csect (symbolS *sym, offsetT align)
> ppc_current_csect = sym;
> }
>
> +static void
> +ppc_change_debug_section (const struct _bfd_xcoff_dw_section *xsect)
> +{
> + segT sec;
> + flagword oldflags;
> +
> +#ifdef md_flush_pending_output
> + md_flush_pending_output ();
> +#endif
> +
> + sec = subseg_new (xsect->elf_name, 0);
> + oldflags = bfd_get_section_flags (stdoutput, sec);
> + if (oldflags == SEC_NO_FLAGS)
> + {
> + /* Just created section. */
> + bfd_set_section_flags (stdoutput, sec, SEC_DEBUGGING);
> + bfd_set_section_alignment (stdoutput, sec, 0);
> + }
> +
> + /* Not anymore in a csect. */
> + ppc_current_csect = NULL;
> +}
> +
> /* 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. */
> @@ -3523,6 +3551,18 @@ ppc_named_section (int ignore ATTRIBUTE_UNUSED)
> real_name = ".data[RW]";
> else
> {
> + const struct _bfd_xcoff_dw_section *xsect;
> +
> + /* Try dwarf sections. */
> + for (xsect = _bfd_xcoff_dw_table; xsect->elf_name != NULL; xsect++)
> + if (strcmp (user_name, xsect->elf_name) == 0)
> + {
> + *input_line_pointer = c;
> + demand_empty_rest_of_line ();
> + ppc_change_debug_section (xsect);
> + return;
> + }
> +
> as_bad (_("The XCOFF file format does not support arbitrary sections"));
> *input_line_pointer = c;
> ignore_rest_of_line ();
> @@ -5486,6 +5526,9 @@ ppc_frob_section (asection *sec)
> {
> static bfd_vma vma = 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 +5624,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/ld/scripttempl/aix.sc b/ld/scripttempl/aix.sc
> index d592dbe..47f385c 100644
> --- a/ld/scripttempl/aix.sc
> +++ b/ld/scripttempl/aix.sc
> @@ -58,5 +58,23 @@ SECTIONS
> .debug : {
> *(.debug)
> }
> +
> + /* DWARF 1.1 and DWARF 2 */
> + .debug_aranges 0 : ALIGN(1) { *(.debug_aranges) }
> + .debug_pubnames 0 : ALIGN(1) { *(.debug_pubnames) }
> +
> + /* DWARF 2 */
> + .debug_info 0 : ALIGN(1) { *(.debug_info) }
> + .debug_abbrev 0 : ALIGN(1) { *(.debug_abbrev) }
> + .debug_line 0 : ALIGN(1) { *(.debug_line) }
> + .debug_frame 0 : ALIGN(1) { *(.debug_frame) }
> + .debug_str 0 : ALIGN(1) { *(.debug_str) }
> + .debug_loc 0 : ALIGN(1) { *(.debug_loc) }
> + .debug_macinfo 0 : ALIGN(1) { *(.debug_macinfo) }
> +
> + /* DWARF 3 */
> + .debug_pubtypes 0 : ALIGN(1) { *(.debug_pubtypes) }
> + .debug_ranges 0 : ALIGN(1) { *(.debug_ranges) }
> +
> }
> EOF
>