You should have received a copy of the GNU General Public
License along with GAS; see the file COPYING. If not, write
- to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+ to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define OBJ_HEADER "obj-elf.h"
#include "as.h"
#ifndef ECOFF_DEBUGGING
#define ECOFF_DEBUGGING 0
+#else
+#define NEED_ECOFF_DEBUG
#endif
-#if ECOFF_DEBUGGING
+#ifdef NEED_ECOFF_DEBUG
#include "ecoff.h"
#endif
#include "elf/mips.h"
#endif
-#if ECOFF_DEBUGGING
+#ifdef NEED_ECOFF_DEBUG
static boolean elf_get_extr PARAMS ((asymbol *, EXTR *));
static void elf_set_index PARAMS ((asymbol *, bfd_size_type));
#endif
{"local", obj_elf_local, 0},
{"previous", obj_elf_previous, 0},
{"section", obj_elf_section, 0},
+ {"section.s", obj_elf_section, 0},
+ {"sect", obj_elf_section, 0},
+ {"sect.s", obj_elf_section, 0},
{"size", obj_elf_size, 0},
{"type", obj_elf_type, 0},
{"version", obj_elf_version, 0},
static const pseudo_typeS ecoff_debug_pseudo_table[] =
{
+#ifdef NEED_ECOFF_DEBUG
/* COFF style debugging information for ECOFF. .ln is not used; .loc
is used instead. */
{ "def", ecoff_directive_def, 0 },
{ "loc", ecoff_directive_loc, 0 },
{ "mask", ecoff_directive_mask, 0 },
+ /* Other ECOFF directives. */
+ { "extern", ecoff_directive_extern, 0 },
+
/* These are used on Irix. I don't know how to implement them. */
{ "alias", s_ignore, 0 },
{ "bgnb", s_ignore, 0 },
{ "noalias", s_ignore, 0 },
{ "verstamp", s_ignore, 0 },
{ "vreg", s_ignore, 0 },
+#endif
{NULL} /* end sentinel */
};
/* allocate_bss: */
old_sec = now_seg;
old_subsec = now_subseg;
- align = temp;
+ if (temp)
+ {
+ /* convert to a power of 2 alignment */
+ for (align = 0; (temp & 1) == 0; temp >>= 1, ++align);
+ if (temp != 1)
+ {
+ as_bad ("Common alignment not a power of 2");
+ ignore_rest_of_line ();
+ return;
+ }
+ }
+ else
+ align = 0;
record_alignment (bss_section, align);
subseg_set (bss_section, 0);
if (align)
pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
(char *) 0);
*pfrag = 0;
+ S_SET_SIZE (symbolP, size);
S_SET_SEGMENT (symbolP, bss_section);
S_CLEAR_EXTERNAL (symbolP);
subseg_set (old_sec, old_subsec);
md_flush_pending_output ();
#endif
+ if (flag_mri)
+ {
+ char type;
+
+ previous_section = now_seg;
+ previous_subsection = now_subseg;
+
+ s_mri_sect (&type);
+
+#ifdef md_elf_section_change_hook
+ md_elf_section_change_hook ();
+#endif
+
+ return;
+ }
+
/* Get name of section. */
SKIP_WHITESPACE ();
if (*input_line_pointer == '"')
attr |= SHF_EXECINSTR;
break;
default:
- as_warn ("Bad .section directive: want a,w,x in string");
- ignore_rest_of_line ();
- return;
+ {
+ char *bad_msg = "Bad .section directive: want a,w,x in string";
+#ifdef md_elf_section_letter
+ int md_attr = md_elf_section_letter (*input_line_pointer, &bad_msg);
+ if (md_attr)
+ attr |= md_attr;
+ else
+#endif
+ {
+ as_warn (bad_msg);
+ ignore_rest_of_line ();
+ return;
+ }
+ }
}
++input_line_pointer;
}
}
else
{
- as_warn ("Unrecognized section type");
- ignore_rest_of_line ();
+#ifdef md_elf_section_type
+ int md_type = md_elf_section_type (&input_line_pointer);
+ if (md_type)
+ type = md_type;
+ else
+#endif
+ {
+ as_warn ("Unrecognized section type");
+ ignore_rest_of_line ();
+ }
}
}
}
}
else
{
- as_warn ("Unrecognized section attribute");
- ignore_rest_of_line ();
- return;
+#ifdef md_elf_section_word
+ int md_attr = md_elf_section_word (&input_line_pointer);
+ if (md_attr)
+ attr |= md_attr;
+ else
+#endif
+ {
+ as_warn ("Unrecognized section attribute");
+ ignore_rest_of_line ();
+ return;
+ }
}
SKIP_WHITESPACE ();
}
flags |= SEC_ALLOC;
flags &=~ SEC_LOAD;
}
+
+#ifdef md_elf_section_flags
+ flags = md_elf_section_flags (flags, attr, type);
+#endif
}
bfd_set_section_flags (stdoutput, sec, flags);
void
obj_read_begin_hook ()
{
+#ifdef NEED_ECOFF_DEBUG
if (ECOFF_DEBUGGING)
ecoff_read_begin_hook ();
+#endif
}
void
{
symbolP->sy_obj = 0;
+#ifdef NEED_ECOFF_DEBUG
if (ECOFF_DEBUGGING)
ecoff_symbol_new_hook (symbolP);
+#endif
}
void
bfd_h_put_32 (abfd, (bfd_vma) strsz, (bfd_byte *) p + 8);
}
-/* #ifdef ECOFF_DEBUGGING */
+#ifdef NEED_ECOFF_DEBUG
/* This function is called by the ECOFF code. It is supposed to
record the external symbol information so that the backend can
{
}
-/* #endif /* ECOFF_DEBUGGING */
+#endif /* NEED_ECOFF_DEBUG */
void
elf_frob_symbol (symp, puntp)
symbolS *symp;
int *puntp;
{
+#ifdef NEED_ECOFF_DEBUG
if (ECOFF_DEBUGGING)
ecoff_frob_symbol (symp);
+#endif
if (symp->sy_obj)
{
as_bad (".size expression too complicated to fix up");
break;
}
+ free (symp->sy_obj);
+ symp->sy_obj = 0;
}
- free (symp->sy_obj);
- symp->sy_obj = 0;
/* Double check weak symbols. */
if (symp->bsym->flags & BSF_WEAK)
elf_tc_final_processing ();
#endif
+#ifdef NEED_ECOFF_DEBUG
if (ECOFF_DEBUGGING)
/* Generate the ECOFF debugging information. */
{
as_fatal ("Could not write .mdebug section: %s",
bfd_errmsg (bfd_get_error ()));
}
+#endif /* NEED_ECOFF_DEBUG */
}
const struct format_ops elf_format_ops =
elf_s_get_size, elf_s_set_size,
elf_s_get_align, elf_s_set_align,
elf_copy_symbol_attributes,
-#ifdef ECOFF_DEBUGGING
+#ifdef NEED_ECOFF_DEBUG
ecoff_generate_asm_lineno,
+ ecoff_stab,
#else
0,
-#endif
0, /* process_stab */
+#endif
elf_sec_sym_ok_for_reloc,
elf_pop_insert,
+#ifdef NEED_ECOFF_DEBUG
elf_ecoff_set_ext,
+#else
+ 0,
+#endif
obj_read_begin_hook,
obj_symbol_new_hook,
};
#define MAP(str,reloc) { str, sizeof(str)-1, reloc }
static struct map_bfd mapping[] = {
- MAP ("got", BFD_RELOC_PPC_TOC16),
MAP ("l", BFD_RELOC_LO16),
MAP ("h", BFD_RELOC_HI16),
MAP ("ha", BFD_RELOC_HI16_S),
MAP ("brtaken", BFD_RELOC_PPC_B16_BRTAKEN),
MAP ("brntaken", BFD_RELOC_PPC_B16_BRNTAKEN),
+ MAP ("got", BFD_RELOC_16_GOTOFF),
MAP ("got@l", BFD_RELOC_LO16_GOTOFF),
MAP ("got@h", BFD_RELOC_HI16_GOTOFF),
MAP ("got@ha", BFD_RELOC_HI16_S_GOTOFF),
MAP ("sectoff@l", BFD_RELOC_LO16_BASEREL),
MAP ("sectoff@h", BFD_RELOC_HI16_BASEREL),
MAP ("sectoff@ha", BFD_RELOC_HI16_S_BASEREL),
+ MAP ("xgot", BFD_RELOC_PPC_TOC16),
{ (char *)0, 0, BFD_RELOC_UNUSED }
};
md_assemble (complete);
}
\f
+/* For ELF, add support for SHF_EXCLUDE and SHT_ORDERED */
+
+int
+ppc_section_letter (letter, ptr_msg)
+ int letter;
+ char **ptr_msg;
+{
+ if (letter == 'e')
+ return SHF_EXCLUDE;
+
+ *ptr_msg = "Bad .section directive: want a,w,x,e in string";
+ return 0;
+}
+
+int
+ppc_section_word (ptr_str)
+ char **ptr_str;
+{
+ if (strncmp (*ptr_str, "exclude", sizeof ("exclude")-1) == 0)
+ {
+ *ptr_str += sizeof ("exclude")-1;
+ return SHF_EXCLUDE;
+ }
+
+ return 0;
+}
+
+int
+ppc_section_type (ptr_str)
+ char **ptr_str;
+{
+ if (strncmp (*ptr_str, "ordered", sizeof ("ordered")-1) == 0)
+ {
+ *ptr_str += sizeof ("ordered")-1;
+ return SHT_ORDERED;
+ }
+
+ return 0;
+}
+
+int
+ppc_section_flags (flags, attr, type)
+ int flags;
+ int attr;
+ int type;
+{
+ if (type == SHT_ORDERED)
+ flags |= SEC_ALLOC | SEC_LOAD | SEC_SORT_ENTRIES;
+
+ if (attr & SHF_EXCLUDE)
+ flags |= SEC_EXCLUDE;
+
+ return flags;
+}
+
+\f
/* Pseudo-op handling. */
/* The .byte pseudo-op. This is similar to the normal .byte
case BFD_RELOC_LO16:
case BFD_RELOC_HI16:
case BFD_RELOC_HI16_S:
- case BFD_RELOC_PPC_TOC16:
case BFD_RELOC_16:
case BFD_RELOC_GPREL16:
case BFD_RELOC_16_GOT_PCREL:
+ case BFD_RELOC_16_GOTOFF:
+ case BFD_RELOC_LO16_GOTOFF:
+ case BFD_RELOC_HI16_GOTOFF:
+ case BFD_RELOC_HI16_S_GOTOFF:
+ case BFD_RELOC_PPC_TOC16:
if (fixp->fx_pcrel)
abort ();
#endif
/* If OBJ_COFF is defined, and TE_PE is not defined, we are assembling
- XCOFF for AIX. If TE_PE is defined, we are assembling COFF for
- Windows NT. */
+ XCOFF for AIX or PowerMac. If TE_PE is defined, we are assembling
+ COFF for Windows NT. */
#ifdef OBJ_COFF
#ifndef TE_PE
#endif
#endif
+/* PowerMac has a BFD slightly different from AIX's. */
+#ifdef TE_POWERMAC
+#ifdef TARGET_FORMAT
+#undef TARGET_FORMAT
+#endif
+#define TARGET_FORMAT "xcoff-powermac"
+#endif
+
#ifdef OBJ_ELF
#define TARGET_FORMAT (target_big_endian ? "elf32-powerpc" : "elf32-powerpcle")
#endif
#define tc_frob_symbol(sym, punt) punt = ppc_frob_symbol (sym)
extern int ppc_frob_symbol PARAMS ((struct symbol *));
+/* Finish up the entire symtab. */
+#define tc_adjust_symtab() ppc_adjust_symtab ()
+extern void ppc_adjust_symtab PARAMS ((void));
+
/* Niclas Andersson <nican@ida.liu.se> says this is needed. */
#define SUB_SEGMENT_ALIGN(SEG) 2
-/* Finish up the file. */
-#define tc_frob_file() ppc_frob_file ()
-extern void ppc_frob_file PARAMS ((void));
-
#endif /* OBJ_XCOFF */
#ifdef OBJ_ELF
|| ((FIXP)->fx_addsy && !(FIXP)->fx_subsy && (FIXP)->fx_addsy->bsym \
&& (FIXP)->fx_addsy->bsym->section != SEC))
+/* Support for SHF_EXCLUDE and SHT_ORDERED */
+extern int ppc_section_letter PARAMS ((int, char **));
+extern int ppc_section_type PARAMS ((char **));
+extern int ppc_section_word PARAMS ((char **));
+extern int ppc_section_flags PARAMS ((int, int, int));
+
+#define md_elf_section_letter(LETTER, PTR_MSG) ppc_section_letter (LETTER, PTR_MSG)
+#define md_elf_section_type(PTR_STR) ppc_section_type (PTR_STR)
+#define md_elf_section_word(PTR_STR) ppc_section_word (PTR_STR)
+#define md_elf_section_flags(FLAGS, ATTR, TYPE) ppc_section_flags (FLAGS, ATTR, TYPE)
#endif /* OBJ_ELF */
/* call md_apply_fix3 with segment instead of md_apply_fix */
#define MD_PCREL_FROM_SECTION(FIXP, SEC) md_pcrel_from_section(FIXP, SEC)
#define md_operand(x)
+