expr.c (__): Undefine before defining.
as.c (got_sig): Don't return anything; return type might be void.
Whitespace/comment cleanup in frags.c.
Some patches for `-pedantic' or `-fno-common' compilation.
(Some of these changes are from Michael Meissner; see change log.)
+Thu May 27 13:02:15 1993 Ken Raeburn (raeburn@cambridge.cygnus.com)
+
+ * frags.c (zero_address_frag, bss_address_frag): These are
+ external.
+
+ * tc.h (md_reloc_size): This is const.
+ * config/tc-{a29k,h8300,h8500,i386,i860,i960,m68k,ns32k,z8k}.c
+ (md_reloc_size): Now const.
+
+ * config/aout_gnu.h (enum machine_type, enum reloc_type): Delete
+ trailing commas.
+ * as.h (enum _segT): Ditto.
+
+ * struc-symbol.h (N_TYPE_seg): This should be const.
+
+Thu May 27 11:43:59 1993 Michael Meissner (meissner@osf.org)
+
+ * config/obj-ecoff.c (add_file): Cast file_name to char * in
+ listing_source_file call.
+
+ * config/obj-elf.c (elf_stab_symbol_string): Cast first argument
+ of subseg_new call to eliminate const attribute.
+ (obj_elf_stab): Ditto.
+ (obj_symbol_new_hook): Cast first argument of bzero call to char *.
+
+ * read.c (s_align_bytes): Properly record alignment.
+
+ * expr.c (__): Undefine __ macro before use, since OSF/1 uses it
+ for the prototype/no prototype macro.
+
+ * as.c (got_sig): Don't do return ((SIGTY) 0), SIGTY might well be
+ void.
+
+ * as.h (relax_stateT enum): Delete trailing comma.
+
Thu May 27 11:07:50 1993 Ian Lance Taylor (ian@cygnus.com)
* app.c (do_scrub_begin): Let line_comment_chars override
--- /dev/null
+/* ELF object file format
+ Copyright (C) 1992, 1993 Free Software Foundation, Inc.
+
+ This file is part of GAS, the GNU Assembler.
+
+ GAS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2,
+ or (at your option) any later version.
+
+ GAS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ the GNU General Public License for more details.
+
+ 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. */
+
+/* HP PA-RISC support was contributed by the Center for Software Science
+ at the University of Utah. */
+
+#include "as.h"
+#include "aout/stab_gnu.h"
+#include "obstack.h"
+
+static void obj_elf_stab PARAMS ((int what));
+static void obj_elf_line PARAMS ((void));
+static void obj_elf_desc PARAMS ((void));
+static void obj_elf_version PARAMS ((void));
+static void obj_elf_section PARAMS ((int));
+static void obj_elf_size PARAMS ((void));
+static void obj_elf_type PARAMS ((void));
+static void obj_elf_ident PARAMS ((void));
+
+const pseudo_typeS obj_pseudo_table[] = {
+ { "ident", obj_elf_ident, 0 },
+ { "section", obj_elf_section, 0 },
+ { "size", obj_elf_size, 0 },
+ { "type", obj_elf_type, 0 },
+ { "version", obj_elf_version, 0 },
+
+ /* These are used for stabs-in-elf configurations. */
+ { "desc", obj_elf_desc, 0 },
+ { "line", obj_elf_line, 0 },
+ { "stabd", obj_elf_stab, 'd' },
+ { "stabn", obj_elf_stab, 'n' },
+ { "stabs", obj_elf_stab, 's' },
+ /* This is used on Solaris 2.x on SPARC, but not supported yet. */
+ { "xstabs", s_ignore, 0 },
+
+ { NULL} /* end sentinel */
+};
+
+static void
+obj_elf_section (xxx)
+ int xxx;
+{
+ char *string;
+ asection *sec;
+
+ /* Initialize this with inclusive-or of all flags that can be cleared
+ by attributes, but not set by them. Also include flags that won't
+ get set properly in the assembler, but which the user/compiler
+ shouldn't be expected to set. */
+ flagword flags = SEC_READONLY | SEC_ALLOC | SEC_RELOC;
+ /* Initialize this with the default flags to be used if none are
+ specified. */
+ flagword default_flags = SEC_ALLOC | SEC_RELOC;
+
+ string = demand_copy_C_string (&xxx);
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ flags = default_flags;
+ while (*input_line_pointer == ',')
+ {
+ flagword bit;
+ int len, inv;
+ char *p, oldp;
+
+ input_line_pointer++;
+ if (*input_line_pointer != '#')
+ {
+ as_bad ("unrecognized syntax in .section command");
+ ignore_rest_of_line ();
+ break;
+ }
+ input_line_pointer++;
+
+#define CHECK(X,BIT,NEG) \
+ if (!strncmp(X,input_line_pointer,len = sizeof(X) - 1)) { \
+ bit = BIT; inv = NEG; goto match; }
+
+ CHECK ("write", SEC_READONLY, 1);
+ CHECK ("alloc", SEC_ALLOC, 0);
+#undef CHECK
+
+ p = input_line_pointer;
+ while (!is_end_of_line[*p] && *p != 0 && *p != ',')
+ p++;
+ *p = 0;
+ oldp = *p;
+ as_bad ("unrecognized section attribute `%s' ignored",
+ input_line_pointer);
+ *p = oldp;
+ continue;
+
+ match:
+ if (inv)
+ flags &= ~bit;
+ else
+ flags |= bit;
+ input_line_pointer += len;
+ }
+ demand_empty_rest_of_line ();
+
+ sec = bfd_get_section_by_name (stdoutput, string);
+ if (sec == 0)
+ {
+ sec = bfd_make_section_old_way (stdoutput, string);
+ bfd_set_section_flags (stdoutput, sec,
+ /* @@ What should the flags be?? */
+ flags);
+ sec->output_section = sec;
+ }
+ subseg_change (sec, 0);
+}
+
+#if 0
+/* pa-spaces.c -- Space/subspace support for the HP PA-RISC version of GAS */
+
+/* for space, subspace, and symbol maintenance on HP 9000 Series 800 */
+
+space_dict_chainS *space_dict_root;
+space_dict_chainS *space_dict_last;
+
+space_dict_chainS *current_space;
+subspace_dict_chainS *current_subspace;
+#endif
+
+symbolS *start_symbol_root;
+symbolS *start_symbol_last;
+
+#if 0 /* I really don't think this belongs in this file. */
+void pa_spaces_begin()
+{
+ space_dict_chainS *space;
+ int i;
+ subsegT now_subseg = now_subseg;
+
+ space_dict_root = NULL;
+ space_dict_last = NULL;
+
+ start_symbol_root = NULL;
+ start_symbol_last = NULL;
+
+ /* create default space and subspace dictionaries */
+
+ i = 0;
+ while ( pa_def_spaces[i].name ) {
+ if ( pa_def_spaces[i].alias )
+ pa_def_spaces[i].segment = subseg_new(pa_def_spaces[i].alias,0);
+ else
+ pa_def_spaces[i].segment = bfd_make_section_old_way(stdoutput,pa_def_spaces[i].name);
+
+ create_new_space(pa_def_spaces[i].name,pa_def_spaces[i].spnum,
+ pa_def_spaces[i].loadable,pa_def_spaces[i].defined,
+ pa_def_spaces[i].private,pa_def_spaces[i].sort,0,
+ pa_def_spaces[i].segment);
+ i++;
+ }
+
+ i = 0;
+ while ( pa_def_subspaces[i].name ) {
+ space = pa_segment_to_space(pa_def_spaces[pa_def_subspaces[i].def_space_index].segment);
+ if ( space ) {
+ create_new_subspace(space,
+ pa_def_subspaces[i].name,pa_def_subspaces[i].defined,
+ pa_def_subspaces[i].loadable,
+ pa_def_subspaces[i].code_only,pa_def_subspaces[i].common,
+ pa_def_subspaces[i].dup_common,pa_def_subspaces[i].zero,
+ pa_def_subspaces[i].sort,pa_def_subspaces[i].access,
+ pa_def_subspaces[i].space_index,
+ pa_def_subspaces[i].alignment,
+ pa_def_subspaces[i].quadrant,
+ pa_def_spaces[pa_def_subspaces[i].def_space_index].segment);
+ subseg_new(pa_def_subspaces[i].name,pa_def_subspaces[i].subsegment);
+ }
+ else
+ as_fatal("Internal error: space missing for subspace \"%s\"\n",
+ pa_def_subspaces[i].name);
+ i++;
+ }
+}
+
+space_dict_chainS *create_new_space(name,spnum,loadable,defined,private,sort,defined_in_file,seg)
+ char *name;
+ int spnum;
+ char loadable;
+ char defined;
+ char private;
+ char sort;
+ char defined_in_file;
+ asection * seg;
+
+{
+ Elf_Internal_Shdr *new_space;
+ space_dict_chainS *chain_entry;
+
+ new_space = (Elf_Internal_Shdr *)xmalloc(sizeof(Elf_Internal_Shdr));
+ if ( !new_space )
+ as_fatal("Out of memory: could not allocate new Elf_Internal_Shdr: %s\n",name);
+
+ /*
+ new_space->space_number = spnum;
+ new_space->is_loadable = loadable & 1;
+ new_space->is_defined = defined & 1;
+ new_space->is_private = private & 1;
+ new_space->sort_key = sort & 0xff;
+
+ new_space->loader_fix_index = ~0;
+ new_space->loader_fix_quantity = 0;
+ new_space->init_pointer_index = ~0;
+ new_space->init_pointer_quantity = 0;
+ new_space->subspace_quantity = 0;
+ */
+
+ chain_entry = (space_dict_chainS *)xmalloc(sizeof(space_dict_chainS));
+ if ( !chain_entry )
+ as_fatal("Out of memory: could not allocate new space chain entry: %s\n",name);
+
+ SPACE_NAME(chain_entry) = (char *)xmalloc(strlen(name)+1);
+ strcpy(SPACE_NAME(chain_entry),name);
+
+ chain_entry->sd_entry = new_space;
+ chain_entry->sd_defined = defined_in_file;
+ chain_entry->sd_seg = seg;
+ chain_entry->sd_last_subseg = -1;
+ chain_entry->sd_next = NULL;
+
+ SPACE_SPNUM(chain_entry) = spnum;
+ SPACE_LOADABLE(chain_entry) = loadable & 1;
+ SPACE_DEFINED(chain_entry) = defined & 1;
+ SPACE_PRIVATE(chain_entry) = private & 1;
+ SPACE_SORT(chain_entry) = sort & 0xff;
+
+ /* find spot for the new space based on its sort key */
+
+ if ( !space_dict_last )
+ space_dict_last = chain_entry;
+
+ if ( space_dict_root == NULL ) /* if root is null, it is very easy */
+ space_dict_root = chain_entry;
+ else
+ {
+ space_dict_chainS *sdcP;
+ space_dict_chainS *last_sdcP;
+
+ sdcP = space_dict_root;
+ last_sdcP = NULL;
+
+ while ( sdcP ) {
+ if ( SPACE_SORT(sdcP) < SPACE_SORT(chain_entry) ) {
+ last_sdcP = sdcP;
+ sdcP = sdcP->sd_next;
+ }
+ else if ( SPACE_SORT(sdcP) == SPACE_SORT(chain_entry) ) {
+ last_sdcP = sdcP;
+ sdcP = sdcP->sd_next;
+ }
+ else if ( SPACE_SORT(sdcP) > SPACE_SORT(chain_entry) ) {
+ break;
+ }
+ }
+
+ if ( last_sdcP ) {
+ chain_entry->sd_next = sdcP;
+ last_sdcP->sd_next = chain_entry;
+ }
+ else {
+ space_dict_root = chain_entry;
+ chain_entry->sd_next = sdcP;
+ }
+
+ if ( chain_entry->sd_next == NULL )
+ space_dict_last = chain_entry;
+ }
+
+ return chain_entry;
+}
+
+subspace_dict_chainS
+*create_new_subspace(space,name,defined,loadable,code_only,common,dup_common,
+ is_zero,sort,access,space_index,alignment,quadrant,seg)
+ space_dict_chainS *space;
+ char *name;
+ char defined,loadable,code_only,common,dup_common,is_zero;
+ char sort;
+ int access;
+ int space_index;
+ int alignment;
+ int quadrant;
+ asection * seg;
+{
+ Elf_Internal_Shdr * new_subspace;
+ subspace_dict_chainS * chain_entry;
+ symbolS * start_symbol;
+
+ new_subspace = (Elf_Internal_Shdr *)xmalloc(sizeof(Elf_Internal_Shdr));
+ if ( !new_subspace )
+ as_fatal("Out of memory: could not allocate new Elf_Internal_Shdr: %s\n",
+ name);
+
+ /*
+ new_subspace->space_index = space_index;
+ new_subspace->fixup_request_index = ~0;
+ */
+
+ chain_entry = (subspace_dict_chainS *)xmalloc(sizeof(subspace_dict_chainS));
+ if ( !chain_entry )
+ as_fatal("Out of memory: could not allocate new subspace chain entry: %s\n",name);
+
+ chain_entry->ssd_entry = new_subspace;
+ SUBSPACE_NAME(chain_entry) = (char *)xmalloc(strlen(name)+1);
+ strcpy(SUBSPACE_NAME(chain_entry),name);
+
+ SUBSPACE_ACCESS(chain_entry) = access & 0x7f;
+ SUBSPACE_LOADABLE(chain_entry) = loadable & 1;
+ SUBSPACE_COMMON(chain_entry) = common & 1;
+ SUBSPACE_DUP_COMM(chain_entry) = dup_common & 1;
+ SUBSPACE_SORT(chain_entry) = sort & 0xff;
+ SET_SUBSPACE_CODE_ONLY(chain_entry,code_only & 1);
+ SUBSPACE_ALIGN(chain_entry) = alignment & 0xffff;
+ SUBSPACE_QUADRANT(chain_entry) = quadrant & 0x3;
+ SUBSPACE_SUBSPACE_START(chain_entry) = pa_subspace_start(space,quadrant);
+
+ chain_entry->ssd_defined = defined;
+ chain_entry->ssd_space_number = space_index;
+ chain_entry->ssd_subseg = pa_next_subseg(space);
+ chain_entry->ssd_seg = seg;
+ SUBSPACE_ZERO(chain_entry) = is_zero;
+ chain_entry->ssd_last_align = 1;
+ chain_entry->ssd_next = NULL;
+
+ /* find spot for the new subspace based on its sort key */
+
+ if ( space->sd_subspaces == NULL ) /* if root is null, it is very easy */
+ space->sd_subspaces = chain_entry;
+ else
+ {
+ subspace_dict_chainS *ssdcP;
+ subspace_dict_chainS *last_ssdcP;
+
+ ssdcP = space->sd_subspaces;
+ last_ssdcP = NULL;
+
+ while ( ssdcP ) {
+ if ( SUBSPACE_SORT(ssdcP) < SUBSPACE_SORT(chain_entry) ) {
+ last_ssdcP = ssdcP;
+ ssdcP = ssdcP->ssd_next;
+ }
+ else if ( SUBSPACE_SORT(ssdcP) == SUBSPACE_SORT(chain_entry) ) {
+ last_ssdcP = ssdcP;
+ ssdcP = ssdcP->ssd_next;
+ }
+ else if ( SUBSPACE_SORT(ssdcP) > SUBSPACE_SORT(chain_entry) ) {
+ break;
+ }
+ }
+
+ if ( last_ssdcP ) {
+ chain_entry->ssd_next = ssdcP;
+ last_ssdcP->ssd_next = chain_entry;
+ }
+ else {
+ space->sd_subspaces = chain_entry;
+ chain_entry->ssd_next = ssdcP;
+ }
+ }
+
+ start_symbol = pa_set_start_symbol(seg,space->sd_last_subseg);
+ chain_entry->ssd_start_sym = start_symbol;
+ return chain_entry;
+
+}
+
+subspace_dict_chainS
+*update_subspace(name,defined,loadable,code_only,common,dup_common,sort,zero,
+ access,space_index,alignment,quadrant,subseg)
+ char *name;
+ char defined,loadable,code_only,common,dup_common,zero;
+ char sort;
+ int access;
+ int space_index;
+ int alignment;
+ int quadrant;
+ subsegT subseg;
+{
+ subspace_dict_chainS *chain_entry;
+ subspace_dict_chainS *is_defined_subspace();
+
+ if ( (chain_entry = is_defined_subspace(name,subseg)) ) {
+
+ SUBSPACE_ACCESS(chain_entry) = access & 0x7f;
+ SUBSPACE_LOADABLE(chain_entry) = loadable & 1;
+ SUBSPACE_COMMON(chain_entry) = common & 1;
+ SUBSPACE_DUP_COMM(chain_entry) = dup_common & 1;
+ SET_SUBSPACE_CODE_ONLY(chain_entry,code_only & 1);
+ SUBSPACE_SORT(chain_entry) = sort & 0xff;
+ /* chain_entry->ssd_entry->space_index = space_index; */
+ SUBSPACE_ALIGN(chain_entry) = alignment & 0xffff;
+ SUBSPACE_QUADRANT(chain_entry) = quadrant & 0x3;
+
+ chain_entry->ssd_defined = defined;
+ chain_entry->ssd_space_number = space_index;
+ SUBSPACE_ZERO(chain_entry) = zero;
+ }
+ else
+ chain_entry = NULL;
+
+ return chain_entry;
+
+}
+
+space_dict_chainS *is_defined_space(name)
+ char *name;
+{
+ space_dict_chainS *spaceCh;
+
+ for (spaceCh = space_dict_root;spaceCh;spaceCh=spaceCh->sd_next ) {
+ if ( strcmp(SPACE_NAME(spaceCh),name) == 0 ) {
+ return spaceCh;
+ }
+ }
+
+ return NULL;
+}
+
+space_dict_chainS *pa_segment_to_space(seg)
+ asection * seg;
+{
+ space_dict_chainS *spaceCh;
+
+ for (spaceCh = space_dict_root;spaceCh;spaceCh=spaceCh->sd_next ) {
+ if ( spaceCh->sd_seg == seg ) {
+ return spaceCh;
+ }
+ }
+
+ return NULL;
+}
+
+subspace_dict_chainS *is_defined_subspace(name,subseg)
+ char *name;
+ subsegT subseg;
+{
+ space_dict_chainS *spaceCh;
+ subspace_dict_chainS *subspCh;
+
+ for ( spaceCh = space_dict_root; spaceCh; spaceCh = spaceCh->sd_next ) {
+ for ( subspCh = spaceCh->sd_subspaces; subspCh; subspCh=subspCh->ssd_next ) {
+ /*
+ if ( strcmp(SUBSPACE_NAME(subspCh),name) == 0 &&
+ subspCh->ssd_subseg == subseg ) {
+ */
+ if ( strcmp(SUBSPACE_NAME(subspCh),name) == 0 ) {
+ return subspCh;
+ }
+ }
+ }
+ return NULL;
+}
+
+subspace_dict_chainS *pa_subsegment_to_subspace(seg,subseg)
+ asection * seg;
+ subsegT subseg;
+{
+ space_dict_chainS *spaceCh;
+ subspace_dict_chainS *subspCh;
+
+ for ( spaceCh = space_dict_root; spaceCh; spaceCh = spaceCh->sd_next ) {
+ if ( spaceCh->sd_seg == seg ) {
+ for (subspCh = spaceCh->sd_subspaces;subspCh;subspCh=subspCh->ssd_next ) {
+ if ( subspCh->ssd_subseg == (int)subseg ) {
+ return subspCh;
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+space_dict_chainS *pa_find_space_by_number(number)
+ int number;
+{
+ space_dict_chainS *spaceCh;
+
+ for (spaceCh = space_dict_root;spaceCh;spaceCh=spaceCh->sd_next ) {
+ if ( SPACE_SPNUM(spaceCh) == number ) {
+ return spaceCh;
+ }
+ }
+
+ return NULL;
+}
+
+unsigned int pa_subspace_start(space,quadrant)
+ space_dict_chainS *space;
+ int quadrant;
+{
+ if ( (strcasecmp(SPACE_NAME(space),"$PRIVATE$") == 0) &&
+ quadrant == 1 ) {
+ return 0x40000000;
+ }
+ else if ( space->sd_seg == data_section && quadrant == 1 ) { /* in case name is */
+ /* already converted */
+ /* to a space dict- */
+ /* ionary index */
+ return 0x40000000;
+ }
+ else
+ return 0;
+}
+
+int pa_next_subseg(space)
+ space_dict_chainS *space;
+{
+
+ space->sd_last_subseg++;
+ return space->sd_last_subseg;
+}
+
+int is_last_defined_subspace(ssd)
+ subspace_dict_chainS *ssd;
+{
+
+ for ( ;ssd; ssd = ssd->ssd_next ) {
+ if ( ssd->ssd_defined )
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+symbolS *pa_get_start_symbol(seg,subseg)
+ asection * seg;
+ subsegT subseg;
+{
+ symbolS *start_symbol;
+ subspace_dict_chainS *ssd;
+
+ start_symbol = NULL;
+
+ /* each time a new space is created, build a symbol called LS$START_seg_subseg$ */
+ /* where <space-name> is the name of the space */
+ /* the start symbol will be SS_LOCAL and ST_CODE */
+
+ if ( seg == bfd_make_section_old_way ( stdoutput, ".text" ) ||
+ seg == bfd_make_section_old_way ( stdoutput, ".data" ) ||
+ seg == bfd_make_section_old_way ( stdoutput, GDB_DEBUG_SPACE_NAME ) ) {
+ ssd = pa_subsegment_to_subspace(seg,subseg);
+ if ( ssd ) {
+ start_symbol = ssd->ssd_start_sym;
+ }
+ else
+ as_fatal("Internal error: missing subspace for (seg,subseg)=('%s',%d)",
+ seg->name,subseg);
+ }
+ else
+ as_fatal("Internal error: attempt to find start symbol for unloadable segment: '%s'",
+ seg->name);
+
+ return start_symbol;
+}
+
+/*
+ Function to define a symbol whose address is the beginning of a subspace.
+ This function assumes the symbol is to be defined for the current subspace.
+ */
+
+symbolS *pa_set_start_symbol(seg,subseg)
+ asection * seg;
+ subsegT subseg;
+{
+ symbolS *start_symbol;
+ subspace_dict_chainS *ssd;
+ char *symbol_name;
+
+ symbol_name = (char *)xmalloc(strlen("LS$START__000000$")+strlen(seg->name)+1);
+
+ sprintf(symbol_name,"LS$START_%s_%03d$",seg->name,subseg);
+
+ start_symbol
+ = symbol_new(symbol_name,seg,0,frag_now); /* XXX: not sure if value s.b. 0 or frag s.b. NULL */
+
+ start_symbol->bsym->flags = BSF_LOCAL; /* XXX: isn't there a macro defined for this? */
+
+ /* each time a new space is created, build a symbol called LS$START_seg_subseg$ */
+ /* where <space-name> is the name of the space */
+ /* the start symbol will be SS_LOCAL and ST_CODE */
+ /* This function assumes that (seg,subseg) is a new subsegment(subspace) */
+
+ if ( seg == bfd_make_section_old_way ( stdoutput, ".text" ) ||
+ seg == bfd_make_section_old_way ( stdoutput, ".data" ) ||
+ seg == bfd_make_section_old_way ( stdoutput, GDB_DEBUG_SPACE_NAME ) ) {
+ ssd = pa_subsegment_to_subspace(seg,subseg);
+ if ( ssd ) {
+ ssd->ssd_start_sym = start_symbol;
+ }
+ else
+ as_fatal("Internal error: missing subspace for (seg,subseg)=('%s',%d)",
+ seg,subseg);
+ }
+ else
+ as_fatal("Internal error: attempt to define start symbol for unloadable segment: '%s'",
+ seg->name);
+
+ return start_symbol;
+}
+#endif
+
+int
+obj_elf_frob_symbol (sym, punt)
+ symbolS *sym;
+ int *punt;
+{
+
+ /* If this is a local symbol, are there any relocations for */
+ /* which need this symbol? */
+
+ /* To find this out, we examine all relocations in all bfd */
+ /* sections that have relocations. If there is one that */
+ /* references this symbol, we need to keep this symbol. In */
+ /* this case, we return a true status. In all other cases, we */
+ /* return a false status. */
+
+ if ( S_IS_LOCAL(sym) ) {
+ asymbol *bsym = sym->bsym;
+ bfd *abfd = bsym->the_bfd;
+ asection *bsec;
+
+ for ( bsec = abfd->sections; bsec; bsec = bsec->next ) {
+ struct reloc_cache_entry **rlocs = bsec->orelocation;
+ int rcnt = bsec->reloc_count;
+
+ if ( rlocs ) {
+ int i;
+
+ for ( i = 0; i < rcnt; i++ ) {
+ if ( rlocs[i]->sym_ptr_ptr
+ && rlocs[i]->sym_ptr_ptr[0] == bsym )
+ return 1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+static void obj_elf_line() {
+ /* Assume delimiter is part of expression.
+ BSD4.2 as fails with delightful bug, so we
+ are not being incompatible here. */
+ new_logical_line((char *)NULL, (int)(get_absolute_expression()));
+ demand_empty_rest_of_line();
+} /* obj_elf_line() */
+
+/*
+ * stab()
+ *
+ * Handle .stabX directives, which used to be open-coded.
+ * So much creeping featurism overloaded the semantics that we decided
+ * to put all .stabX thinking in one place. Here.
+ *
+ * We try to make any .stabX directive legal. Other people's AS will often
+ * do assembly-time consistency checks: eg assigning meaning to n_type bits
+ * and "protecting" you from setting them to certain values. (They also zero
+ * certain bits before emitting symbols. Tut tut.)
+ *
+ * If an expression is not absolute we either gripe or use the relocation
+ * information. Other people's assemblers silently forget information they
+ * don't need and invent information they need that you didn't supply.
+ *
+ * .stabX directives always make a symbol table entry. It may be junk if
+ * the rest of your .stabX directive is malformed.
+ */
+
+/*
+ * pa_stab_symbol_string()
+ *
+ * Build a string dictionary entry for a .stabX symbol.
+ * The symbol is added to the .stabstr section.
+ *
+ */
+
+static unsigned int gdb_string_index = 0;
+
+static unsigned int
+elf_stab_symbol_string(string)
+ char *string;
+{
+ asection *save_seg;
+ asection *seg;
+ subsegT save_subseg;
+ unsigned int length;
+ unsigned int old_gdb_string_index;
+ char *clengthP;
+ int i;
+ char c;
+
+ old_gdb_string_index = 0;
+ length = strlen(string);
+ clengthP = (char *)&length;
+ if ( length > 0 ) { /* Ordinary case. */
+ save_seg = now_seg;
+ save_subseg = now_subseg;
+
+ /* Create the stab sections, if they are not already created. */
+ seg = bfd_get_section_by_name(stdoutput,".stabstr");
+ if ( seg == 0 ) {
+ seg = bfd_make_section_old_way(stdoutput,".stabstr");
+ bfd_set_section_flags (stdoutput,
+ seg,
+ SEC_READONLY | SEC_ALLOC | SEC_LOAD );
+ }
+ subseg_new((char *) seg->name,save_subseg);
+ old_gdb_string_index = gdb_string_index;
+ i = 0;
+ while ( (c = *string++) )
+ {
+ i++;
+ gdb_string_index++;
+ FRAG_APPEND_1_CHAR( c );
+ }
+ {
+ FRAG_APPEND_1_CHAR( (char)0 );
+ i++;
+ gdb_string_index++;
+ }
+ while ( i%4 != 0 ) {
+ FRAG_APPEND_1_CHAR( (char)0 );
+ i++;
+ gdb_string_index++;
+ }
+ subseg_new((char *) save_seg->name,save_subseg);
+ }
+
+ return old_gdb_string_index;
+}
+
+unsigned int
+elf_stab_symbol(symbolP,stab_type)
+ symbolS *symbolP;
+ int stab_type;
+{
+ unsigned int length;
+ int i;
+ char c;
+ char *toP;
+
+ /* the string index portion of the stab */
+
+ toP = frag_more( sizeof(long) +
+ sizeof(S_GET_TYPE(symbolP)) +
+ sizeof(S_GET_OTHER(symbolP)) +
+ sizeof(S_GET_DESC(symbolP)));
+ md_number_to_chars(toP,symbolP->sy_name_offset,sizeof(long));
+ md_number_to_chars(toP,
+ S_GET_TYPE(symbolP),
+ sizeof(S_GET_TYPE(symbolP)));
+ md_number_to_chars(toP + sizeof(S_GET_TYPE(symbolP)),
+ S_GET_OTHER(symbolP),
+ sizeof(S_GET_OTHER(symbolP)));
+ md_number_to_chars(toP + sizeof(S_GET_TYPE(symbolP))
+ + sizeof(S_GET_OTHER(symbolP)),
+ S_GET_DESC(symbolP),
+ sizeof(S_GET_DESC(symbolP)));
+
+ /* n_value has to be relocated */
+
+ /* Don't bother relocating if we're only adding in a constant. */
+
+ if ((stab_type == 's' || stab_type == 'n') && symbolP->sy_forward == 0)
+ S_SET_VALUE(symbolP,S_GET_VALUE(symbolP->sy_forward));
+
+ toP = frag_more(4);
+ md_number_to_chars(toP, S_GET_VALUE(symbolP),
+ sizeof(S_GET_VALUE(symbolP)));
+
+#if 0
+ if ( (stab_type == 's' || stab_type == 'n') && symbolP->sy_forward )
+ {
+ i = S_GET_TYPE(symbolP) & N_TYPE;
+ fix_new_hppa(frag_now, /* which frag */
+ toP-frag_now->fr_literal, /* where */
+ 4, /* size */
+ symbolP->sy_forward, /* addr of symbol for this stab */
+ (asymbol *)NULL,
+ 0,
+ i == N_UNDF || i == N_ABS, /* 1 if internal relocation */
+ R_HPPA, /* reloc type */
+ e_fsel, /* fixup field = F% */
+ 32,
+ 0, /* arg_reloc descriptor */
+ (char *)0
+ );
+ }
+ else if ( stab_type == 'd' )
+ {
+ fix_new_hppa (frag_now, /* which frag */
+ toP-frag_now->fr_literal, /* where */
+ 4, /* size */
+ symbolP, /* addr of symbol for this stab */
+ (asymbol *)NULL,
+ 0,
+ 0,
+ R_HPPA, /* reloc type */
+ e_fsel, /* fixup field = F% */
+ 32,
+ 0, /* arg_reloc descriptor */
+ (char *)0
+ );
+ }
+#else
+ /* What needs to replace the above code? */
+ abort ();
+#endif
+}
+
+static void obj_elf_stab(what)
+ int what;
+{
+ extern int listing;
+
+ symbolS * symbolP = 0;
+ char * string;
+ int saved_type = 0;
+ int length;
+ int goof = 0;
+ long longint;
+ asection *saved_seg = now_seg;
+ asection *seg;
+ subsegT subseg = now_subseg;
+
+ seg = bfd_get_section_by_name(stdoutput,".stab");
+ if ( seg == 0 )
+ {
+ seg = bfd_make_section_old_way(stdoutput,".stab");
+ bfd_set_section_flags (stdoutput,
+ seg,
+ SEC_READONLY | SEC_ALLOC | SEC_LOAD | SEC_RELOC);
+ }
+
+ /*
+ * Enter with input_line_pointer pointing past .stabX and any following
+ * whitespace.
+ */
+ if (what == 's') {
+ string = demand_copy_C_string(& length);
+ SKIP_WHITESPACE();
+ if (* input_line_pointer == ',')
+ input_line_pointer ++;
+ else
+ {
+ as_bad("I need a comma after symbol's name");
+ goof = 1;
+ }
+ }
+ else
+ string = "";
+
+ /*
+ * Input_line_pointer->after ','. String->symbol name.
+ */
+ if (! goof)
+ {
+ symbolP = symbol_new(string, &bfd_und_section, 0, (struct frag *)0);
+
+ /* enter the string in the .stab string table (section .stabstr) */
+ symbolP->sy_name_offset = elf_stab_symbol_string(string);
+
+ switch (what)
+ {
+ case 'd':
+ S_SET_NAME(symbolP, NULL); /* .stabd feature. */
+ S_SET_VALUE(symbolP, obstack_next_free(&frags) - frag_now->fr_literal);
+ S_SET_SEGMENT(symbolP, now_seg);
+ symbolP->sy_frag = frag_now;
+ break;
+
+ case 'n':
+ symbolP->sy_frag = &zero_address_frag;
+ break;
+
+ case 's':
+ symbolP->sy_frag = & zero_address_frag;
+ break;
+
+ default:
+ BAD_CASE(what);
+ break;
+ }
+
+ if (get_absolute_expression_and_terminator(&longint) == ',')
+ {
+ saved_type = longint;
+ S_SET_TYPE (symbolP, saved_type);
+ }
+ else
+ {
+ as_bad("I want a comma after the n_type expression");
+ goof = 1;
+ input_line_pointer --; /* Backup over a non-',' char. */
+ }
+ }
+
+ if (!goof)
+ {
+ if (get_absolute_expression_and_terminator(&longint) == ',')
+ S_SET_OTHER(symbolP, longint);
+ else
+ {
+ as_bad("I want a comma after the n_other expression");
+ goof = 1;
+ input_line_pointer--; /* Backup over a non-',' char. */
+ }
+ }
+
+ if (!goof)
+ {
+ S_SET_DESC(symbolP, get_absolute_expression());
+ if (what == 's' || what == 'n')
+ {
+ if (*input_line_pointer != ',')
+ {
+ as_bad("I want a comma after the n_desc expression");
+ goof = 1;
+ }
+ else
+ {
+ input_line_pointer++;
+ }
+ }
+ }
+
+ if ( !goof ) {
+ if ( what=='s' || what=='n' ) {
+ pseudo_set(symbolP);
+ S_SET_TYPE (symbolP, saved_type);
+ }
+ /* Emit the stab symbol. */
+ subseg_new((char *) seg->name,subseg);
+ elf_stab_symbol(symbolP, what);
+ subseg_new((char *) saved_seg->name,subseg);
+
+ if ( what=='s' || what=='n' && symbolP->sy_forward == NULL ) {
+ /* symbol is not needed in the regular symbol table */
+ symbol_remove(symbolP,&symbol_rootP,&symbol_lastP);
+ }
+
+ }
+
+#ifndef NO_LISTING
+ if (listing && !goof)
+ switch (S_GET_TYPE (symbolP))
+ {
+ case N_SLINE:
+ listing_source_line (S_GET_DESC (symbolP));
+ break;
+ case N_SO:
+ case N_SOL:
+ listing_source_file (string);
+ break;
+ }
+#endif
+
+ if (goof)
+ ignore_rest_of_line();
+ else
+ demand_empty_rest_of_line ();
+} /* obj_elf_stab() */
+
+static void obj_elf_desc() {
+ char *name;
+ char c;
+ char *p;
+ symbolS *symbolP;
+ int temp;
+
+ /*
+ * Frob invented at RMS' request. Set the n_desc of a symbol.
+ */
+ name = input_line_pointer;
+ c = get_symbol_end();
+ p = input_line_pointer;
+ * p = c;
+ SKIP_WHITESPACE();
+ if (*input_line_pointer != ',') {
+ *p = 0;
+ as_bad("Expected comma after name \"%s\"", name);
+ *p = c;
+ ignore_rest_of_line();
+ } else {
+ input_line_pointer ++;
+ temp = get_absolute_expression();
+ *p = 0;
+ symbolP = symbol_find_or_make(name);
+ *p = c;
+ S_SET_DESC(symbolP,temp);
+ }
+ demand_empty_rest_of_line();
+} /* obj_elf_desc() */
+
+void obj_read_begin_hook()
+{
+}
+
+void obj_symbol_new_hook(symbolP)
+symbolS *symbolP;
+{
+ elf_symbol_type *esym = (elf_symbol_type *)symbolP;
+
+ /* There is an Elf_Internal_Sym and an Elf_External_Sym. For now,
+ just zero them out. */
+
+ bzero((char *) &esym->internal_elf_sym,sizeof(Elf_Internal_Sym));
+ bzero((char *) &esym->native_elf_sym,sizeof(Elf_External_Sym));
+}
+
+static void obj_elf_version()
+{
+ char *name;
+ unsigned int c;
+ char ch;
+ char *p;
+ int temp;
+ symbolS * symbolP;
+ asection *seg = now_seg;
+ subsegT subseg = now_subseg;
+ Elf_Internal_Note i_note;
+ Elf_External_Note e_note;
+ asection *note_secp = (asection *)NULL;
+ int i, len;
+
+ SKIP_WHITESPACE();
+ if (* input_line_pointer == '\"') {
+ ++input_line_pointer; /* -> 1st char of string. */
+ name = input_line_pointer;
+
+ while ( is_a_char(c = next_char_of_string()) )
+ ;
+ c = *input_line_pointer;
+ *input_line_pointer = '\0';
+ *(input_line_pointer-1) = '\0';
+ *input_line_pointer = c;
+
+ /* create the .note section if this is the first version string */
+
+ note_secp = bfd_get_section_by_name(stdoutput,".note");
+ if ( note_secp == (asection *)NULL ) {
+ note_secp = bfd_make_section_old_way(stdoutput,".note");
+ bfd_set_section_flags(stdoutput,
+ note_secp,
+ SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS);
+ }
+
+ /* process the version string */
+
+ subseg_new((char *)note_secp->name, 0);
+ len = strlen(name);
+
+ i_note.namesz = ((len + 1) + 3) & ~3; /* round this to word boundary */
+ i_note.descsz = 0; /* no description */
+ i_note.type = NT_VERSION;
+ p = frag_more(sizeof(e_note.namesz));
+ md_number_to_chars(p, i_note.namesz, 4);
+ p = frag_more(sizeof(e_note.descsz));
+ md_number_to_chars(p, i_note.descsz, 4);
+ p = frag_more(sizeof(e_note.type));
+ md_number_to_chars(p, i_note.type, 4);
+
+ for ( i = 0; i < len; i++ ) {
+ ch = *(name + i);
+ {
+ FRAG_APPEND_1_CHAR( ch );
+ }
+ }
+ frag_align(2,0);
+
+ subseg_new((char *)seg->name,subseg);
+ }
+ else {
+ as_bad( "Expected \"-ed string" );
+ }
+ demand_empty_rest_of_line();
+}
+
+static void
+obj_elf_size ()
+{
+ char *name = input_line_pointer;
+ char c = get_symbol_end ();
+ char *p;
+ expressionS exp;
+ segT sec;
+ symbolS *sym;
+
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ *p = 0;
+ as_bad ("expected comma after name `%s' in .size directive", name);
+ *p = c;
+ ignore_rest_of_line ();
+ return;
+ }
+ input_line_pointer++;
+ sec = expression (&exp);
+ if (sec == absent_section)
+ {
+ as_bad ("missing expression in .size directive");
+ exp.X_seg = absolute_section;
+ exp.X_add_number = 0;
+ }
+ *p = 0;
+ sym = symbol_find_or_make (name);
+ *p = c;
+ if (sec == absolute_section)
+ S_SET_SIZE (sym, exp.X_add_number);
+ else
+ as_tsktsk (".size not yet supported, ignored");
+ demand_empty_rest_of_line ();
+}
+
+static void
+obj_elf_type ()
+{
+ char *name = input_line_pointer;
+ char c = get_symbol_end ();
+ char *p;
+ int type;
+ symbolS *sym;
+
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != ',')
+ {
+ as_bad ("expected comma after name in .type directive");
+ egress:
+ ignore_rest_of_line ();
+ return;
+ }
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
+ if (*input_line_pointer != '#')
+ {
+ as_bad ("expected `#' after comma in .type directive");
+ goto egress;
+ }
+ input_line_pointer++;
+ if (!strncmp ("function", input_line_pointer, sizeof ("function") - 1))
+ {
+ type = BSF_FUNCTION;
+ input_line_pointer += sizeof ("function") - 1;
+ }
+ else
+ {
+ as_bad ("unrecognized symbol type, ignored");
+ goto egress;
+ }
+ demand_empty_rest_of_line ();
+ *p = 0;
+ sym = symbol_find_or_make (name);
+ sym->bsym->flags = type;
+}
+
+static void
+obj_elf_ident ()
+{
+ int xxx;
+ char * string;
+
+ string = demand_copy_C_string (&xxx);
+ as_tsktsk (".ident not supported, ignoring");
+}
int md_long_jump_size = 4;
#if defined(BFD_HEADERS)
#ifdef RELSZ
-int md_reloc_size = RELSZ; /* Coff headers */
+const int md_reloc_size = RELSZ; /* Coff headers */
#else
-int md_reloc_size = 12; /* something else headers */
+const int md_reloc_size = 12; /* something else headers */
#endif
#else
-int md_reloc_size = 12; /* Not bfdized*/
+const int md_reloc_size = 12; /* Not bfdized*/
#endif
/* This array holds the chars that always start a comment. If the
{0, 0, 0}
};
-int md_reloc_size;
+const int md_reloc_size;
const char EXP_CHARS[] = "eE";
#include <ctype.h>
#include "as.h"
-#include "read.h"
#include "obstack.h"
#include "opcode/i386.h"
/* OPERANDS gives the number of given operands. */
unsigned int operands;
- /* REG_OPERANDS, DISP_OPERANDS, MEM_OPERANDS, IMM_OPERANDS give the number of
- given register, displacement, memory operands and immediate operands. */
+ /* REG_OPERANDS, DISP_OPERANDS, MEM_OPERANDS, IMM_OPERANDS give the number
+ of given register, displacement, memory operands and immediate
+ operands. */
unsigned int reg_operands, disp_operands, mem_operands, imm_operands;
/* TYPES [i] is the type (see above #defines) which tells us how to
- search through DISPS [i] & IMMS [i] & REGS [i] for the required
- operand. */
+ search through DISPS [i] & IMMS [i] & REGS [i] for the required
+ operand. */
unsigned int types[MAX_OPERANDS];
/* Displacements (if given) for each operand. */
reg_entry *regs[MAX_OPERANDS];
/* BASE_REG, INDEX_REG, and LOG2_SCALE_FACTOR are used to encode
- the base index byte below. */
+ the base index byte below. */
reg_entry *base_reg;
reg_entry *index_reg;
unsigned int log2_scale_factor;
/* SEG gives the seg_entry of this insn. It is equal to zero unless
- an explicit segment override is given. */
+ an explicit segment override is given. */
const seg_entry *seg; /* segment for memory operands (if given) */
/* PREFIX holds all the given prefix opcodes (usually null).
- PREFIXES is the size of PREFIX. */
+ PREFIXES is the size of PREFIX. */
/* richfix: really unsigned? */
unsigned char prefix[MAX_PREFIXES];
unsigned int prefixes;
- /* RM and IB are the modrm byte and the base index byte where the addressing
- modes of this insn are encoded. */
+ /* RM and IB are the modrm byte and the base index byte where the
+ addressing modes of this insn are encoded. */
modrm_byte rm;
base_index_byte bi;
/* This array holds the chars that always start a comment. If the
pre-processor is disabled, these aren't very useful */
+#ifdef TE_I386AIX
+const char comment_chars[] = "#/";
+#else
const char comment_chars[] = "#";
+#endif
/* This array holds the chars that only start a comment at the beginning of
a line. If the line seems to have the form '# 123 filename'
const relax_typeS md_relax_table[] =
{
-/*
- The fields are:
- 1) most positive reach of this state,
- 2) most negative reach of this state,
- 3) how many bytes this mode will add to the size of the current frag
- 4) which index into the table to try if we can't fit into this one.
- */
+/* The fields are:
+ 1) most positive reach of this state,
+ 2) most negative reach of this state,
+ 3) how many bytes this mode will add to the size of the current frag
+ 4) which index into the table to try if we can't fit into this one.
+ */
{1, 1, 0, 0},
{1, 1, 0, 0},
{1, 1, 0, 0},
{1, 1, 0, 0},
/* For now we don't use word displacement jumps: they may be
- untrustworthy. */
+ untrustworthy. */
{127 + 1, -128 + 1, 0, ENCODE_RELAX_STATE (COND_JUMP, DWORD)},
/* word conditionals add 3 bytes to frag:
- 2 opcode prefix; 1 displacement bytes */
+ 2 opcode prefix; 1 displacement bytes */
{32767 + 2, -32768 + 2, 3, ENCODE_RELAX_STATE (COND_JUMP, DWORD)},
/* dword conditionals adds 4 bytes to frag:
- 1 opcode prefix; 3 displacement bytes */
+ 1 opcode prefix; 3 displacement bytes */
{0, 0, 4, 0},
{1, 1, 0, 0},
{127 + 1, -128 + 1, 0, ENCODE_RELAX_STATE (UNCOND_JUMP, DWORD)},
/* word jmp adds 2 bytes to frag:
- 1 opcode prefix; 1 displacement bytes */
+ 1 opcode prefix; 1 displacement bytes */
{32767 + 2, -32768 + 2, 2, ENCODE_RELAX_STATE (UNCOND_JUMP, DWORD)},
/* dword jmp adds 3 bytes to frag:
- 0 opcode prefix; 3 displacement bytes */
+ 0 opcode prefix; 3 displacement bytes */
{0, 0, 3, 0},
{1, 1, 0, 0},
};
-#if __STDC__ == 1
-
-static char *output_invalid (int c);
-static int fits_in_signed_byte (long num);
-static int fits_in_signed_word (long num);
-static int fits_in_unsigned_byte (long num);
-static int fits_in_unsigned_word (long num);
-static int i386_operand (char *operand_string);
-static int smallest_imm_type (long num);
-static reg_entry *parse_register (char *reg_string);
-static unsigned long mode_from_disp_size (unsigned long t);
-static unsigned long opcode_suffix_to_type (unsigned long s);
-static void s_bss (void);
-
-#else /* not __STDC__ */
-
-static char *output_invalid ();
-static int fits_in_signed_byte ();
-static int fits_in_signed_word ();
-static int fits_in_unsigned_byte ();
-static int fits_in_unsigned_word ();
-static int i386_operand ();
-static int smallest_imm_type ();
-static reg_entry *parse_register ();
-static unsigned long mode_from_disp_size ();
-static unsigned long opcode_suffix_to_type ();
-static void s_bss ();
-
-#endif /* not __STDC__ */
+static char *output_invalid PARAMS ((int c));
+static int i386_operand PARAMS ((char *operand_string));
+static reg_entry *parse_register PARAMS ((char *reg_string));
+#ifndef I386COFF
+static void s_bss PARAMS ((void));
+#endif
+static unsigned long
+mode_from_disp_size (t)
+ unsigned long t;
+{
+ return ((t & (Disp8))
+ ? 1
+ : ((t & (Disp32)) ? 2 : 0));
+} /* mode_from_disp_size() */
+
+/* convert opcode suffix ('b' 'w' 'l' typically) into type specifyer */
+
+static unsigned long
+opcode_suffix_to_type (s)
+ unsigned long s;
+{
+ return (s == BYTE_OPCODE_SUFFIX
+ ? Byte : (s == WORD_OPCODE_SUFFIX
+ ? Word : DWord));
+} /* opcode_suffix_to_type() */
+
+static int
+fits_in_signed_byte (num)
+ long num;
+{
+ return ((num >= -128) && (num <= 127));
+} /* fits_in_signed_byte() */
+
+static int
+fits_in_unsigned_byte (num)
+ long num;
+{
+ return ((num & 0xff) == num);
+} /* fits_in_unsigned_byte() */
+
+static int
+fits_in_unsigned_word (num)
+ long num;
+{
+ return ((num & 0xffff) == num);
+} /* fits_in_unsigned_word() */
+
+static int
+fits_in_signed_word (num)
+ long num;
+{
+ return ((-32768 <= num) && (num <= 32767));
+} /* fits_in_signed_word() */
+
+static int
+smallest_imm_type (num)
+ long num;
+{
+ return ((num == 1)
+ ? (Imm1 | Imm8 | Imm8S | Imm16 | Imm32)
+ : (fits_in_signed_byte (num)
+ ? (Imm8S | Imm8 | Imm16 | Imm32)
+ : (fits_in_unsigned_byte (num)
+ ? (Imm8 | Imm16 | Imm32)
+ : ((fits_in_signed_word (num) || fits_in_unsigned_word (num))
+ ? (Imm16 | Imm32)
+ : (Imm32)))));
+} /* smallest_imm_type() */
/* Ignore certain directives generated by gcc. This probably should
not be here. */
const pseudo_typeS md_pseudo_table[] =
{
+#ifndef I386COFF
{"bss", s_bss, 0},
+#endif
+#if !defined (TE_LINUX) && !defined (TE_386BSD)
{"align", s_align_bytes, 0},
+#else
+ {"align", s_align_ptwo, 0},
+#endif
{"ffloat", float_cons, 'f'},
{"dfloat", float_cons, 'd'},
{"tfloat", float_cons, 'x'},
{"value", cons, 2},
+ {"noopt", s_ignore, 0},
+ {"optim", s_ignore, 0},
{0, 0, 0}
};
else
{
/* different name --> ship out current template list;
- add to hash table; & begin anew */
- /* Note: end must be set before start! since obstack_next_free changes
- upon opstack_finish */
+ add to hash table; & begin anew */
+ /* Note: end must be set before start! since obstack_next_free
+ changes upon opstack_finish */
core_optab->end = (template *) obstack_next_free (&o);
core_optab->start = (template *) obstack_finish (&o);
hash_err = hash_insert (op_hash, prev_name, (char *) core_optab);
#endif /* DEBUG386 */
\f
-/*
- This is the guts of the machine-dependent assembler. LINE points to a
- machine dependent instruction. This funciton is supposed to emit
- the frags/bytes it assembles to.
- */
+#ifdef BFD_ASSEMBLER
+static bfd_reloc_code_real_type
+reloc (size, pcrel)
+ int size;
+ int pcrel;
+{
+ if (pcrel)
+ switch (size)
+ {
+ case 1: return BFD_RELOC_8_PCREL;
+ case 2: return BFD_RELOC_16_PCREL;
+ case 4: return BFD_RELOC_32_PCREL;
+ }
+ else
+ switch (size)
+ {
+ case 1: return BFD_RELOC_8;
+ case 2: return BFD_RELOC_16;
+ case 4: return BFD_RELOC_32;
+ }
+ abort ();
+}
+#endif
+
+/* This is the guts of the machine-dependent assembler. LINE points to a
+ machine dependent instruction. This funciton is supposed to emit
+ the frags/bytes it assembles to. */
void
md_assemble (line)
char *line;
save_stack_p = save_stack; /* reset stack pointer */
/* Fist parse an opcode & call i386_operand for the operands.
- We assume that the scrubber has arranged it so that line[0] is the valid
- start of a (possibly prefixed) opcode. */
+ We assume that the scrubber has arranged it so that line[0] is the valid
+ start of a (possibly prefixed) opcode. */
{
register char *l = line; /* Fast place to put LINE. */
}
/* Lookup insn in hash; try intel & att naming conventions if appropriate;
- that is: we only use the opcode suffix 'b' 'w' or 'l' if we need to. */
+ that is: we only use the opcode suffix 'b' 'w' or 'l' if we need to. */
current_templates = (templates *) hash_find (op_hash, token_start);
if (!current_templates)
{
#define MATCH(overlap,given_type) \
(overlap && \
- (overlap & (JumpAbsolute|BaseIndex|Mem8)) \
- == (given_type & (JumpAbsolute|BaseIndex|Mem8)))
+ (((overlap & (JumpAbsolute|BaseIndex|Mem8)) \
+ == (given_type & (JumpAbsolute|BaseIndex|Mem8))) \
+ || (overlap == InOutPortReg)))
+
/* If m0 and m1 are register matches they must be consistent
with the expected operand types t0 and t1.
unsigned int fake_zero_displacement = 0;
unsigned int o = (i.types[0] & Mem) ? 0 : ((i.types[1] & Mem) ? 1 : 2);
- /* Encode memory operand into modrm byte and base index byte. */
+ /* Encode memory operand into modrm byte and base index
+ byte. */
if (i.base_reg == esp && !i.index_reg)
{
- /* <disp>(%esp) becomes two byte modrm with no index register. */
+ /* <disp>(%esp) becomes two byte modrm with no index
+ register. */
i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
i.rm.mode = mode_from_disp_size (i.types[o]);
i.bi.base = ESP_REG_NUM;
{
if (!(i.types[o] & Disp))
{
- /* Must fake a zero byte displacement.
- There is no direct way to code '(%ebp)' directly. */
+ /* Must fake a zero byte displacement. There is
+ no direct way to code '(%ebp)' directly. */
fake_zero_displacement = 1;
/* fake_zero_displacement code does not set this. */
i.types[o] |= Disp8;
holds the correct displacement size. */
exp = &disp_expressions[i.disp_operands++];
i.disps[o] = exp;
- exp->X_seg = SEG_ABSOLUTE;
+ exp->X_seg = absolute_section;
exp->X_add_number = 0;
exp->X_add_symbol = (symbolS *) 0;
exp->X_subtract_symbol = (symbolS *) 0;
if (t->opcode_modifier & Jump)
{
int n = i.disps[0]->X_add_number;
+ segT seg;
- switch (i.disps[0]->X_seg)
+ seg = i.disps[0]->X_seg;
+
+ if (seg == absolute_section)
{
- case SEG_ABSOLUTE:
if (fits_in_signed_byte (n))
{
p = frag_more (2);
p[0] = t->base_opcode;
p[1] = n;
-#if 0 /* leave out 16 bit jumps - pace */
}
+#if 0 /* leave out 16 bit jumps - pace */
else if (fits_in_signed_word (n))
{
p = frag_more (4);
p[0] = WORD_PREFIX_OPCODE;
p[1] = t->base_opcode;
md_number_to_chars (&p[2], n, 2);
-#endif
}
+#endif
else
{ /* It's an absolute dword displacement. */
if (t->base_opcode == JUMP_PC_RELATIVE)
md_number_to_chars (&p[2], n, 4);
}
}
- break;
- default:
+ }
+ else
+ {
/* It's a symbol; end frag & setup for relax.
- Make sure there are 6 chars left in the current frag; if not
- we'll have to start a new one. */
- /* I caught it failing with obstack_room == 6,
- so I changed to <= pace */
+ Make sure there are more than 6 chars left in the current frag;
+ if not we'll have to start a new one. */
if (obstack_room (&frags) <= 6)
{
frag_wane (frag_now);
: ENCODE_RELAX_STATE (COND_JUMP, BYTE)),
i.disps[0]->X_add_symbol,
n, p);
- break;
}
}
else if (t->opcode_modifier & (JumpByte | JumpDword))
}
p = frag_more (size);
- switch (i.disps[0]->X_seg)
+ if (i.disps[0]->X_seg == absolute_section)
{
- case SEG_ABSOLUTE:
md_number_to_chars (p, n, size);
if (size == 1 && !fits_in_signed_byte (n))
{
as_bad ("loop/jecx only takes byte displacement; %d shortened to %d",
n, *p);
}
- break;
- default:
+ }
+ else
+ {
fix_new (frag_now, p - frag_now->fr_literal, size,
i.disps[0]->X_add_symbol, i.disps[0]->X_subtract_symbol,
i.disps[0]->X_add_number, 1, NO_RELOC);
- break;
}
}
else if (t->opcode_modifier & JumpInterSegment)
{
p = frag_more (1 + 2 + 4); /* 1 opcode; 2 segment; 4 offset */
p[0] = t->base_opcode;
- if (i.imms[1]->X_seg == SEG_ABSOLUTE)
+ if (i.imms[1]->X_seg == absolute_section)
md_number_to_chars (p + 1, i.imms[1]->X_add_number, 4);
else
fix_new (frag_now, p + 1 - frag_now->fr_literal, 4,
i.imms[1]->X_add_symbol,
i.imms[1]->X_subtract_symbol,
i.imms[1]->X_add_number, 0, NO_RELOC);
- if (i.imms[0]->X_seg != SEG_ABSOLUTE)
+ if (i.imms[0]->X_seg != absolute_section)
as_bad ("can't handle non absolute segment in long call/jmp");
md_number_to_chars (p + 5, i.imms[0]->X_add_number, 2);
}
{
if (i.disps[n])
{
- if (i.disps[n]->X_seg == SEG_ABSOLUTE)
+ if (i.disps[n]->X_seg == absolute_section)
{
if (i.types[n] & (Disp8 | Abs8))
{
}
}
else
- { /* not SEG_ABSOLUTE */
+ { /* not absolute_section */
/* need a 32-bit fixup (don't support 8bit non-absolute disps) */
p = frag_more (4);
fix_new (frag_now, p - frag_now->fr_literal, 4,
{
if (i.imms[n])
{
- if (i.imms[n]->X_seg == SEG_ABSOLUTE)
+ if (i.imms[n]->X_seg == absolute_section)
{
if (i.types[n] & (Imm8 | Imm8S))
{
}
}
else
- { /* not SEG_ABSOLUTE */
+ { /* not absolute_section */
/* need a 32-bit fixup (don't support 8bit non-absolute ims) */
/* try to support other sizes ... */
int size;
else if (*op_string == IMMEDIATE_PREFIX)
{ /* ... or an immediate */
char *save_input_line_pointer;
- segT exp_seg = SEG_GOOF;
+ segT exp_seg = 0;
expressionS *exp;
if (i.imm_operands == MAX_IMMEDIATE_OPERANDS)
exp_seg = expression (exp);
input_line_pointer = save_input_line_pointer;
- switch (exp_seg)
+ if (exp_seg == absent_section)
{
- case SEG_ABSENT: /* missing or bad expr becomes absolute 0 */
+ /* missing or bad expr becomes absolute 0 */
as_bad ("missing or invalid immediate expression '%s' taken as 0",
operand_string);
- exp->X_seg = SEG_ABSOLUTE;
+ exp->X_seg = absolute_section;
exp->X_add_number = 0;
exp->X_add_symbol = (symbolS *) 0;
exp->X_subtract_symbol = (symbolS *) 0;
i.types[this_operand] |= Imm;
- break;
- case SEG_ABSOLUTE:
+ }
+ else if (exp_seg == absolute_section)
+ {
i.types[this_operand] |= smallest_imm_type (exp->X_add_number);
- break;
- case SEG_TEXT:
- case SEG_DATA:
- case SEG_BSS:
- case SEG_UNKNOWN:
- i.types[this_operand] |= Imm32; /* this is an address ==> 32bit */
- break;
- default:
+ }
+#ifndef I386COFF
+ else if (exp_seg != text_section
+ && exp_seg != data_section
+ && exp_seg != bss_section
+ && exp_seg != undefined_section
+#ifdef BFD_ASSEMBLER
+ && ! bfd_is_com_section (exp_seg)
+#endif
+ )
+ {
seg_unimplemented:
as_bad ("Unimplemented segment type %d in parse_operand", exp_seg);
return 0;
}
+#endif
+ else
+ {
+ /* this is an address ==> 32bit */
+ i.types[this_operand] |= Imm32;
+ }
/* shorten this type of this operand if the instruction wants
- * fewer bits than are present in the immediate. The bit field
- * code can put out 'andb $0xffffff, %al', for example. pace
- * also 'movw $foo,(%eax)'
- */
+ * fewer bits than are present in the immediate. The bit field
+ * code can put out 'andb $0xffffff, %al', for example. pace
+ * also 'movw $foo,(%eax)'
+ */
switch (i.suffix)
{
case WORD_OPCODE_SUFFIX:
i.types[this_operand] |= Mem32;
}
- /* Check for base index form. We detect the base index form by
- looking for an ')' at the end of the operand, searching
- for the '(' matching it, and finding a REGISTER_PREFIX or ','
- after it. */
+ /* Check for base index form. We detect the base index form by
+ looking for an ')' at the end of the operand, searching
+ for the '(' matching it, and finding a REGISTER_PREFIX or ','
+ after it. */
base_string = end_of_operand_string - 1;
found_base_index_form = 0;
if (*base_string == ')')
{
unsigned int parens_balenced = 1;
- /* We've already checked that the number of left & right ()'s are equal,
- so this loop will not be infinite. */
+ /* We've already checked that the number of left & right ()'s are
+ equal, so this loop will not be infinite. */
do
{
base_string--;
}
/* If we can't parse a base index register expression, we've found
- a pure displacement expression. We set up displacement_string_start
- and displacement_string_end for the code below. */
+ a pure displacement expression. We set up displacement_string_start
+ and displacement_string_end for the code below. */
if (!found_base_index_form)
{
displacement_string_start = op_string;
}
/* If there's an expression begining the operand, parse it,
- assuming displacement_string_start and displacement_string_end
- are meaningful. */
+ assuming displacement_string_start and displacement_string_end
+ are meaningful. */
if (displacement_string_start)
{
register expressionS *exp;
- segT exp_seg = SEG_GOOF;
+ segT exp_seg = 0;
char *save_input_line_pointer;
exp = &disp_expressions[i.disp_operands];
i.disps[this_operand] = exp;
as_bad ("Ignoring junk '%s' after expression", input_line_pointer);
RESTORE_END_STRING (displacement_string_end);
input_line_pointer = save_input_line_pointer;
- switch (exp_seg)
+ if (exp_seg == absent_section)
{
- case SEG_ABSENT:
/* missing expr becomes absolute 0 */
as_bad ("missing or invalid displacement '%s' taken as 0",
operand_string);
i.types[this_operand] |= (Disp | Abs);
- exp->X_seg = SEG_ABSOLUTE;
+ exp->X_seg = absolute_section;
exp->X_add_number = 0;
exp->X_add_symbol = (symbolS *) 0;
exp->X_subtract_symbol = (symbolS *) 0;
- break;
- case SEG_ABSOLUTE:
+ }
+ else if (exp_seg == absolute_section)
+ {
i.types[this_operand] |= SMALLEST_DISP_TYPE (exp->X_add_number);
- break;
- case SEG_TEXT:
- case SEG_DATA:
- case SEG_BSS:
- case SEG_UNKNOWN: /* must be 32 bit displacement (i.e. address) */
+ }
+ else if (exp_seg == text_section
+ || exp_seg == data_section
+ || exp_seg == bss_section
+ || exp_seg == undefined_section)
+ {
i.types[this_operand] |= Disp32;
- break;
- default:
+ }
+ else
+ {
+#ifdef I386COFF
+ i.types[this_operand] |= Disp32;
+#else
goto seg_unimplemented;
+#endif
}
}
return 0;
}
/*
- * special case for (%dx) while doing input/output op
- */
+ * special case for (%dx) while doing input/output op
+ */
if ((i.base_reg &&
(i.base_reg->reg_type == (Reg16 | InOutPortReg)) &&
(i.index_reg == 0)))
- return 1;
+ {
+ i.types[this_operand] |= InOutPortReg;
+ return 1;
+ }
if ((i.base_reg && (i.base_reg->reg_type & Reg32) == 0) ||
(i.index_reg && (i.index_reg->reg_type & Reg32) == 0))
{
* Out: Any fixSs and constants are set up.
* Caller will turn frag into a ".space 0".
*/
+#ifndef BFD_ASSEMBLER
void
md_convert_frag (headers, fragP)
object_headers *headers;
register fragS *fragP;
+#else
+void
+md_convert_frag (abfd, sec, fragP)
+ bfd *abfd;
+ segT sec;
+ register fragS *fragP;
+#endif
{
register unsigned char *opcode;
unsigned char *where_to_put_displacement = NULL;
int md_short_jump_size = 2; /* size of byte displacement jmp */
int md_long_jump_size = 5; /* size of dword displacement jmp */
-int md_reloc_size = 8; /* Size of relocation record */
+const int md_reloc_size = 8; /* Size of relocation record */
void
md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
the same (little-endian) format, so we don't need to care about which
we are handling. */
-void
-md_apply_fix (fixP, value)
+static void
+md_apply_fix_1 (fixP, value)
fixS *fixP; /* The fix we're to put in */
long value; /* The value of the bits. */
{
}
}
+#ifdef BFD_ASSEMBLER
+int
+md_apply_fix (fixP, valp)
+ fixS *fixP;
+ long *valp;
+{
+ md_apply_fix_1 (fixP, *valp);
+ return 1;
+}
+#else
+void
+md_apply_fix (fixP, val)
+ fixS *fixP;
+ long val;
+{
+ md_apply_fix_1 (fixP, val);
+}
+#endif
+
long /* Knows about the byte order in a word. */
md_chars_to_number (con, nbytes)
unsigned char con[]; /* Low order byte 1st. */
return retval;
}
-/* Not needed for coff since relocation structure does not
- contain bitfields. */
-#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
-#ifdef comment
-/* Output relocation information in the target's format. */
-void
-md_ri_to_chars (the_bytes, ri)
- char *the_bytes;
- struct reloc_info_generic *ri;
-{
- /* this is easy */
- md_number_to_chars (the_bytes, ri->r_address, 4);
- /* now the fun stuff */
- the_bytes[6] = (ri->r_symbolnum >> 16) & 0x0ff;
- the_bytes[5] = (ri->r_symbolnum >> 8) & 0x0ff;
- the_bytes[4] = ri->r_symbolnum & 0x0ff;
- the_bytes[7] = (((ri->r_extern << 3) & 0x08) | ((ri->r_length << 1) & 0x06) |
- ((ri->r_pcrel << 0) & 0x01)) & 0x0F;
-}
-
-#endif /* comment */
-
-void
-tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
- char *where;
- fixS *fixP;
- relax_addressT segment_address_in_file;
-{
- /*
- * In: length of relocation (or of address) in chars: 1, 2 or 4.
- * Out: GNU LD relocation length code: 0, 1, or 2.
- */
-
- static unsigned char nbytes_r_length[] =
- {42, 0, 1, 42, 2};
- long r_symbolnum;
-
- know (fixP->fx_addsy != NULL);
-
- md_number_to_chars (where,
- fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
- 4);
-
- r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
- ? S_GET_TYPE (fixP->fx_addsy)
- : fixP->fx_addsy->sy_number);
-
- where[6] = (r_symbolnum >> 16) & 0x0ff;
- where[5] = (r_symbolnum >> 8) & 0x0ff;
- where[4] = r_symbolnum & 0x0ff;
- where[7] = ((((!S_IS_DEFINED (fixP->fx_addsy)) << 3) & 0x08)
- | ((nbytes_r_length[fixP->fx_size] << 1) & 0x06)
- | (((fixP->fx_pcrel << 0) & 0x01) & 0x0f));
-
- return;
-} /* tc_aout_fix_to_chars() */
-
-#endif /* OBJ_AOUT or OBJ_BOUT */
\f
#define MAX_LITTLENUMS 6
md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE));
litP += sizeof (LITTLENUM_TYPE);
}
- return ""; /* Someone should teach Dean about null pointers */
+ return 0;
}
\f
char output_invalid_buf[8];
return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
}
-/* these were macros, but I don't trust macros that eval their
- arguments more than once. Besides, gcc can static inline them.
- xoxorich. */
+#ifndef I386COFF
-static unsigned long
-mode_from_disp_size (t)
- unsigned long t;
+static void
+s_bss ()
{
- return ((t & (Disp8))
- ? 1
- : ((t & (Disp32)) ? 2 : 0));
-} /* mode_from_disp_size() */
+ register int temp;
-/* convert opcode suffix ('b' 'w' 'l' typically) into type specifyer */
+ temp = get_absolute_expression ();
+#ifdef BFD_ASSEMBLER
+ subseg_set (bss_section, (subsegT) temp);
+#else
+ subseg_new (bss_section, (subsegT) temp);
+#endif
+ demand_empty_rest_of_line ();
+}
-static unsigned long
-opcode_suffix_to_type (s)
- unsigned long s;
-{
- return (s == BYTE_OPCODE_SUFFIX
- ? Byte : (s == WORD_OPCODE_SUFFIX
- ? Word : DWord));
-} /* opcode_suffix_to_type() */
+#endif
-static int
-fits_in_signed_byte (num)
- long num;
-{
- return ((num >= -128) && (num <= 127));
-} /* fits_in_signed_byte() */
-static int
-fits_in_unsigned_byte (num)
- long num;
-{
- return ((num & 0xff) == num);
-} /* fits_in_unsigned_byte() */
+#ifdef BFD_ASSEMBLER
-static int
-fits_in_unsigned_word (num)
- long num;
+arelent *
+tc_gen_reloc (section, fixp)
+ asection *section;
+ fixS *fixp;
{
- return ((num & 0xffff) == num);
-} /* fits_in_unsigned_word() */
+ arelent *reloc;
+ bfd_reloc_code_real_type code;
-static int
-fits_in_signed_word (num)
- long num;
-{
- return ((-32768 <= num) && (num <= 32767));
-} /* fits_in_signed_word() */
+#define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
+ switch (F (fixp->fx_size, fixp->fx_pcrel))
+ {
+#define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
+ MAP (1, 0, BFD_RELOC_8);
+ MAP (2, 0, BFD_RELOC_16);
+ MAP (4, 0, BFD_RELOC_32);
+ MAP (1, 1, BFD_RELOC_8_PCREL);
+ MAP (2, 1, BFD_RELOC_16_PCREL);
+ MAP (4, 1, BFD_RELOC_32_PCREL);
+ default:
+ abort ();
+ }
-static int
-smallest_imm_type (num)
- long num;
-{
- return ((num == 1)
- ? (Imm1 | Imm8 | Imm8S | Imm16 | Imm32)
- : (fits_in_signed_byte (num)
- ? (Imm8S | Imm8 | Imm16 | Imm32)
- : (fits_in_unsigned_byte (num)
- ? (Imm8 | Imm16 | Imm32)
- : ((fits_in_signed_word (num) || fits_in_unsigned_word (num))
- ? (Imm16 | Imm32)
- : (Imm32)))));
-} /* smallest_imm_type() */
+ reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
+ assert (reloc != 0);
+ reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ if (fixp->fx_pcrel)
+ reloc->addend = fixp->fx_addnumber;
+ else
+ reloc->addend = 0;
-static void
-s_bss ()
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
+ assert (reloc->howto != 0);
+
+ return reloc;
+}
+
+#else /* ! BFD_ASSEMBLER */
+
+#if (defined(OBJ_AOUT) | defined(OBJ_BOUT))
+void
+tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
+ char *where;
+ fixS *fixP;
+ relax_addressT segment_address_in_file;
{
- register int temp;
+ /*
+ * In: length of relocation (or of address) in chars: 1, 2 or 4.
+ * Out: GNU LD relocation length code: 0, 1, or 2.
+ */
- temp = get_absolute_expression ();
- subseg_new (SEG_BSS, (subsegT) temp);
- demand_empty_rest_of_line ();
+ static unsigned char nbytes_r_length[] =
+ {42, 0, 1, 42, 2};
+ long r_symbolnum;
+
+ know (fixP->fx_addsy != NULL);
+
+ md_number_to_chars (where,
+ fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
+ 4);
+
+ r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
+ ? S_GET_TYPE (fixP->fx_addsy)
+ : fixP->fx_addsy->sy_number);
+
+ where[6] = (r_symbolnum >> 16) & 0x0ff;
+ where[5] = (r_symbolnum >> 8) & 0x0ff;
+ where[4] = r_symbolnum & 0x0ff;
+ where[7] = ((((!S_IS_DEFINED (fixP->fx_addsy)) << 3) & 0x08)
+ | ((nbytes_r_length[fixP->fx_size] << 1) & 0x06)
+ | (((fixP->fx_pcrel << 0) & 0x01) & 0x0f));
}
+#endif /* OBJ_AOUT or OBJ_BOUT */
-#ifdef I386COFF
+#if defined (I386COFF)
short
tc_coff_fix2rtype (fixP)
}
-#endif
+int
+tc_coff_sizemachdep (frag)
+ fragS *frag;
+{
+ if (frag->fr_next)
+ return (frag->fr_next->fr_address - frag->fr_address);
+ else
+ return 0;
+}
+
+#endif /* I386COFF */
+
+#endif /* BFD_ASSEMBLER? */
/* end of tc-i386.c */
included by one source file per executable. */
#include "opcode/m68k.h"
+#ifndef BFD_ASSEMBLER
#ifdef TE_SUN
/* This variable contains the value to write out at the beginning of
the a.out file. The 2<<16 means that this is a 68020 file instead
#else
long omagic = OMAGIC;
#endif
+#endif
/* This array holds the chars that always start a comment. If the
pre-processor is disabled, these aren't very useful */
-const char comment_chars[] = "|";
+CONST char comment_chars[] = "|";
/* This array holds the chars that only start a comment at the beginning of
a line. If the line seems to have the form '# 123 filename'
first line of the input file. This is because the compiler outputs
#NO_APP at the beginning of its output. */
/* Also note that comments like this one will always work. */
-const char line_comment_chars[] = "#";
+CONST char line_comment_chars[] = "#";
-const char line_separator_chars[] = "";
+CONST char line_separator_chars[] = "";
/* Chars that can be used to separate mant from exp in floating point nums */
-const char EXP_CHARS[] = "eE";
+CONST char EXP_CHARS[] = "eE";
-/* Chars that mean this number is a floating point constant */
-/* As in 0f12.456 */
-/* or 0d1.2345e12 */
+/* Chars that mean this number is a floating point constant, as
+ in "0f12.456" or "0d1.2345e12". */
-const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
+CONST char FLT_CHARS[] = "rRsSfFdDxXeEpP";
/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
changed in read.c . Ideally it shouldn't have to know about it at all,
- but nothing is ideal around here.
- */
+ but nothing is ideal around here. */
-int md_reloc_size = 8; /* Size of relocation record */
+const int md_reloc_size = 8; /* Size of relocation record */
/* Its an arbitrary name: This means I don't approve of it */
/* See flames below */
static struct m68k_it the_ins; /* the instruction being assembled */
+#define seg(exp) ((exp)->e_exp.X_seg)
+#define adds(exp) ((exp)->e_exp.X_add_symbol)
+#define subs(exp) ((exp)->e_exp.X_subtract_symbol)
+#define offs(exp) ((exp)->e_exp.X_add_number)
+
/* Macros for adding things to the m68k_it struct */
#define addword(w) the_ins.opcode[the_ins.numo++]=(w)
/* The numo+1 kludge is so we can hit the low order byte of the prev word.
Blecch. */
-#define add_fix(width,exp,pc_rel) \
-{\
- the_ins.reloc[the_ins.nrel].n= (((width)=='B') \
- ? (the_ins.numo*2-1) \
- : (((width)=='b') \
- ? ((the_ins.numo-1)*2) \
- : (the_ins.numo*2)));\
- the_ins.reloc[the_ins.nrel].add=adds((exp));\
- the_ins.reloc[the_ins.nrel].sub=subs((exp));\
- the_ins.reloc[the_ins.nrel].off=offs((exp));\
- the_ins.reloc[the_ins.nrel].wid=width;\
- the_ins.reloc[the_ins.nrel++].pcrel=pc_rel;\
+static void
+add_fix (width, exp, pc_rel)
+ char width;
+ struct m68k_exp *exp;
+ int pc_rel;
+{
+ the_ins.reloc[the_ins.nrel].n = (((width)=='B')
+ ? (the_ins.numo*2-1)
+ : (((width)=='b')
+ ? ((the_ins.numo-1)*2)
+ : (the_ins.numo*2)));
+ the_ins.reloc[the_ins.nrel].add = adds((exp));
+ the_ins.reloc[the_ins.nrel].sub = subs((exp));
+ the_ins.reloc[the_ins.nrel].off = offs((exp));
+ the_ins.reloc[the_ins.nrel].wid = width;
+ the_ins.reloc[the_ins.nrel++].pcrel = pc_rel;
}
-#define add_frag(add,off,type) \
-{\
- the_ins.fragb[the_ins.nfrag].fragoff=the_ins.numo;\
- the_ins.fragb[the_ins.nfrag].fadd=add;\
- the_ins.fragb[the_ins.nfrag].foff=off;\
- the_ins.fragb[the_ins.nfrag++].fragty=type;\
+static void
+add_frag(add,off,type)
+ symbolS *add;
+ long off;
+ int type;
+{
+ the_ins.fragb[the_ins.nfrag].fragoff=the_ins.numo;
+ the_ins.fragb[the_ins.nfrag].fadd=add;
+ the_ins.fragb[the_ins.nfrag].foff=off;
+ the_ins.fragb[the_ins.nfrag++].fragty=type;
}
#define isvar(exp) ((exp) && (adds(exp) || subs(exp)))
-#define seg(exp) ((exp)->e_exp.X_seg)
-#define adds(exp) ((exp)->e_exp.X_add_symbol)
-#define subs(exp) ((exp)->e_exp.X_subtract_symbol)
-#define offs(exp) ((exp)->e_exp.X_add_number)
-
-
struct m68k_incant
{
char *m_operands;
#define gettwo(x) (((x)->m_opcode)&0xffff)
-#if __STDC__ == 1
-
-static char *crack_operand (char *str, struct m68k_op *opP);
-static int get_num (struct m68k_exp *exp, int ok);
-static int get_regs (int i, char *str, struct m68k_op *opP);
-static int reverse_16_bits (int in);
-static int reverse_8_bits (int in);
-static int try_index (char **s, struct m68k_op *opP);
-static void install_gen_operand (int mode, int val);
-static void install_operand (int mode, int val);
-static void s_bss (void);
-static void s_data1 (void);
-static void s_data2 (void);
-static void s_even (void);
-static void s_proc (void);
-
-#else /* not __STDC__ */
-
-static char *crack_operand ();
-static int get_num ();
-static int get_regs ();
-static int reverse_16_bits ();
-static int reverse_8_bits ();
-static int try_index ();
-static void install_gen_operand ();
-static void install_operand ();
-static void s_bss ();
-void s_align_bytes ();
-static void s_data1 ();
-static void s_data2 ();
-static void s_even ();
-static void s_proc ();
-
-#endif /* not __STDC__ */
-
-static int current_architecture = 0;
+static char *crack_operand PARAMS ((char *str, struct m68k_op *opP));
+static int get_num PARAMS ((struct m68k_exp *exp, int ok));
+static int get_regs PARAMS ((int i, char *str, struct m68k_op *opP));
+static int reverse_16_bits PARAMS ((int in));
+static int reverse_8_bits PARAMS ((int in));
+static int try_index PARAMS ((char **s, struct m68k_op *opP));
+static void install_gen_operand PARAMS ((int mode, int val));
+static void install_operand PARAMS ((int mode, int val));
+static void s_bss PARAMS ((void));
+static void s_data1 PARAMS ((void));
+static void s_data2 PARAMS ((void));
+static void s_even PARAMS ((void));
+static void s_proc PARAMS ((void));
+
+static int current_architecture;
/* BCC68000 is for patching in an extra jmp instruction for long offsets
on the 68000. The 68000 doesn't support long branches with branchs */
/* This table desribes how you change sizes for the various types of variable
size expressions. This version only supports two kinds. */
-/* Note that calls to frag_var need to specify the maximum expansion needed */
-/* This is currently 10 bytes for DBCC */
+/* Note that calls to frag_var need to specify the maximum expansion
+ needed; this is currently 10 bytes for DBCC. */
/* The fields are:
How far Forward this mode will reach:
How many bytes this mode will add to the size of the frag
Which mode to go to if the offset won't fit in this one
*/
-const relax_typeS
- md_relax_table[] =
+CONST relax_typeS md_relax_table[] =
{
{1, 1, 0, 0}, /* First entries aren't used */
{1, 1, 0, 0}, /* For no good reason except */
function to call to execute this pseudo-op
Integer arg to pass to the function
*/
-const pseudo_typeS md_pseudo_table[] =
+CONST pseudo_typeS md_pseudo_table[] =
{
{"data1", s_data1, 0},
{"data2", s_data2, 0},
*/
extern void obj_coff_section ();
-const pseudo_typeS mote_pseudo_table[] =
+CONST pseudo_typeS mote_pseudo_table[] =
{
{"dc.l", cons, 4},
0,
};
-/* #define isbyte(x) ((x)>=-128 && (x)<=127) */
-/* #define isword(x) ((x)>=-32768 && (x)<=32767) */
-
#define issbyte(x) ((x)>=-128 && (x)<=127)
#define isubyte(x) ((x)>=0 && (x)<=255)
#define issword(x) ((x)>=-32768 && (x)<=32767)
symbolP = symbol_find (start);
*p = c;
- if (symbolP && S_GET_SEGMENT (symbolP) == SEG_REGISTER)
+ if (symbolP && S_GET_SEGMENT (symbolP) == reg_section)
{
*ccp = p;
return S_GET_VALUE (symbolP);
#ifndef MIT_SYNTAX_ONLY
/* The operand has no '@'. Try to parse it using
- Motorola syntax. */
+ Motorola syntax. */
/* Logic of the parsing switch(*str):
case opP->mode =
---- -----------
break;
}
}
- /* if(str[-3]==':') {
- int siz;
-
- switch(str[-2]) {
- case 'b':
- case 'B':
- siz=1;
- break;
- case 'w':
- case 'W':
- siz=2;
- break;
- case 'l':
- case 'L':
- siz=3;
- break;
- default:
- opP->error="Specified size isn't :w or :l";
- return FAIL;
- }
- opP->con1=add_exp(beg_str,str-4);
- opP->con1->e_siz=siz;
- } else */
- opP->con1 = add_exp (beg_str, str - 2);
+#if 0
+ if (str[-3]==':')
+ {
+ int siz;
+
+ switch (str[-2])
+ {
+ case 'b':
+ case 'B':
+ siz=1;
+ break;
+ case 'w':
+ case 'W':
+ siz=2;
+ break;
+ case 'l':
+ case 'L':
+ siz=3;
+ break;
+ default:
+ opP->error="Specified size isn't :w or :l";
+ return FAIL;
+ }
+ opP->con1=add_exp(beg_str,str-4);
+ opP->con1->e_siz=siz;
+ }
+ else
+#endif
+ opP->con1 = add_exp (beg_str, str - 2);
/* Should be offset,reg */
if (str[-1] == ',')
{
} /* m68k_ip_op() */
-#ifdef M68KCOFF
+#if defined (M68KCOFF) && !defined (BFD_ASSEMBLER)
short
tc_coff_fix2rtype (fixP)
#endif
+#ifdef BFD_ASSEMBLER
+
+arelent *
+tc_gen_reloc (section, fixp)
+ asection *section;
+ fixS *fixp;
+{
+ arelent *reloc;
+ bfd_reloc_code_real_type code;
+
+#define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
+ switch (F (fixp->fx_size, fixp->fx_pcrel))
+ {
+#define MAP(SZ,PCREL,TYPE) case F(SZ,PCREL): code = (TYPE); break
+ MAP (1, 0, BFD_RELOC_8);
+ MAP (2, 0, BFD_RELOC_16);
+ MAP (4, 0, BFD_RELOC_32);
+ MAP (1, 1, BFD_RELOC_8_PCREL);
+ MAP (2, 1, BFD_RELOC_16_PCREL);
+ MAP (4, 1, BFD_RELOC_32_PCREL);
+ default:
+ abort ();
+ }
+
+ reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
+ assert (reloc != 0);
+ reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+ if (fixp->fx_pcrel)
+ reloc->addend = fixp->fx_addnumber;
+ else
+ reloc->addend = 0;
+
+ reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
+ assert (reloc->howto != 0);
+
+ return reloc;
+}
+
+#endif /* BFD_ASSEMBLER */
+
#ifdef TEST1 /* TEST1 tests m68k_ip_op(), which parses operands */
main ()
{
#endif
-static struct hash_control *op_hash = NULL; /* handle of the OPCODE hash table
- NULL means any use before m68k_ip_begin()
- will crash */
+/* Handle of the OPCODE hash table. NULL means any use before
+ m68k_ip_begin() will crash. */
+static struct hash_control *op_hash;
\f
/*
/* We've got the operands. Find an opcode that'll accept them */
for (losing = 0;;)
{
- /* if we didn't get the right number of ops,
- or we have no common model with this pattern
- then reject this pattern. */
+ /* If we didn't get the right number of ops, or we have no
+ common model with this pattern then reject this pattern. */
if (opsfound != opcode->m_opnum
|| ((opcode->m_arch & current_architecture) == 0))
for (s = opcode->m_operands, opP = &the_ins.operands[0]; *s && !losing; s += 2, opP++)
{
/* Warning: this switch is huge! */
- /* I've tried to organize the cases into this order:
- non-alpha first, then alpha by letter. lower-case goes directly
- before uppercase counterpart. */
- /* Code with multiple case ...: gets sorted by the lowest case ...
- it belongs to. I hope this makes sense. */
+ /* I've tried to organize the cases into this order:
+ non-alpha first, then alpha by letter. Lower-case
+ goes directly before uppercase counterpart. */
+ /* Code with multiple case ...: gets sorted by the lowest
+ case ... it belongs to. I hope this makes sense. */
switch (*s)
{
case '!':
{
long t;
- t = get_num (opP->con1, 80);
- if (!issbyte (t) || isvar (opP->con1))
+ t = get_num (opP->con1, 0);
+ if (!issbyte (t)
+ || isvar (opP->con1)
+ || seg (opP->con1) != absolute_section)
losing++;
}
break;
default:
{
int got_one = 0, idx;
- const static struct
+ CONST static struct
{
int arch;
- const char *name;
+ CONST char *name;
}
archs[] =
{
if (strchr ("bwl", s[1]))
nextword = get_num (opP->con1, 80);
else
- nextword = nextword = get_num (opP->con1, 0);
+ nextword = get_num (opP->con1, 0);
if (isvar (opP->con1))
add_fix (s[1], opP->con1, 0);
switch (s[1])
break;
} /* Its BIG */
#else
- if (seg (opP->con1) != SEG_BIG)
+ if (seg (opP->con1) != big_section)
{
abort ();
}
nextword = 0;
baseo = get_num (opP->con1, 80);
outro = get_num (opP->con2, 80);
- /* Figure out the 'addressing mode' */
- /* Also turn on the BASE_DISABLE bit, if needed */
+ /* Figure out the `addressing mode'.
+ Also turn on the BASE_DISABLE bit, if needed. */
if (opP->reg == PC || opP->reg == ZPC)
{
tmpreg = 0x3b;/* 7.3 */
as_fatal ("failed sanity check.");
}
/* IF its simple,
- GET US OUT OF HERE! */
+ GET US OUT OF HERE! */
/* Must be INDEX, with an index
- register. Address register
- cannot be ZERO-PC, and either
- :b was forced, or we know
- it will fit */
+ register. Address register
+ cannot be ZERO-PC, and either
+ :b was forced, or we know
+ it will fit */
if (opP->mode == AINDX
&& opP->reg != FAIL
&& opP->reg != ZPC
else
nextword |= 0x40; /* No index reg */
- /* It aint simple */
+ /* It isn't simple. */
nextword |= 0x100;
- /* If the guy specified a width, we assume that
- it is wide enough. Maybe it isn't. If so, we lose
- */
+ /* If the guy specified a width, we assume that it is
+ wide enough. Maybe it isn't. If so, we lose. */
switch (siz1)
{
case 0:
on 68010 and 68000 */
if (isvar (opP->con1)
&& !subs (opP->con1)
- && seg (opP->con1) == SEG_TEXT
- && now_seg == SEG_TEXT
+ && seg (opP->con1) == text_section
+ && now_seg == text_section
&& cpu_of_arch (current_architecture) >= m68020
&& !flagseen['S']
&& !strchr ("~%&$?", s[0]))
case 'w':
if (isvar (opP->con1))
{
+#if 1
/* check for DBcc instruction */
if ((the_ins.opcode[0] & 0xf0f8) == 0x50c8)
{
add_frag (adds (opP->con1), offs (opP->con1), TAB (DBCC, SZ_UNDEF));
break;
}
-
+#endif
/* Don't ask! */
opP->con1->e_exp.X_add_number += 2;
add_fix ('w', opP->con1, 1);
{
char buf[100];
int i;
+symbolS *s;
#ifdef REGISTER_PREFIX
buf[0] = REGISTER_PREFIX;
regname = buf;
#endif
- symbol_table_insert (symbol_new (regname, SEG_REGISTER, regnum, &zero_address_frag));
+ symbol_table_insert (s = symbol_new (regname, reg_section, regnum, &zero_address_frag));
+
+verify_symbol_chain_2 (s);
for (i = 0; regname[i]; i++)
buf[i] = islower (regname[i]) ? toupper (regname[i]) : regname[i];
buf[i] = '\0';
- symbol_table_insert (symbol_new (buf, SEG_REGISTER, regnum, &zero_address_frag));
+ symbol_table_insert (s = symbol_new (buf, reg_section, regnum, &zero_address_frag));
+verify_symbol_chain_2 (s);
}
-static const struct
+struct init_entry
{
char *name;
int number;
- }
+ };
-init_table[] =
+static CONST struct init_entry init_table[] =
{
"d0", DATA0,
"d1", DATA1,
}
if (the_ins.nfrag == 0)
- { /* No frag hacking involved; just put it out */
+ {
+ /* No frag hacking involved; just put it out */
toP = frag_more (2 * the_ins.numo);
fromP = &the_ins.opcode[0];
for (m = the_ins.numo; m; --m)
n = 4;
break;
default:
- as_fatal ("Don't know how to figure width of %c in md_assemble()", the_ins.reloc[m].wid);
+ as_fatal ("Don't know how to figure width of %c in md_assemble()",
+ the_ins.reloc[m].wid);
}
fix_new (frag_now,
}
for (m = 0; m < the_ins.nrel; m++)
{
- if ((the_ins.reloc[m].n) >= 2 * shorts_this_frag /* 2*the_ins.fragb[n].fragoff */ )
+ if ((the_ins.reloc[m].n) >= 2 * shorts_this_frag)
{
- the_ins.reloc[m].n -= 2 * shorts_this_frag /* 2*the_ins.fragb[n].fragoff */ ;
+ the_ins.reloc[m].n -= 2 * shorts_this_frag;
break;
}
wid = the_ins.reloc[m].wid;
the_ins.reloc[m].pcrel,
NO_RELOC);
}
- /* know(the_ins.fragb[n].fadd); */
- (void) frag_var (rs_machine_dependent, 10, 0, (relax_substateT) (the_ins.fragb[n].fragty),
- the_ins.fragb[n].fadd, the_ins.fragb[n].foff, to_beg_P);
+ (void) frag_var (rs_machine_dependent, 10, 0,
+ (relax_substateT) (the_ins.fragb[n].fragty),
+ the_ins.fragb[n].fadd, the_ins.fragb[n].foff, to_beg_P);
}
n = (the_ins.numo - the_ins.fragb[n - 1].fragoff);
shorts_this_frag = 0;
wid = (wid == 'b') ? 1 : (wid == 'w') ? 2 : (wid == 'l') ? 4 : 4000;
fix_new (frag_now,
- (the_ins.reloc[m].n + toP - frag_now->fr_literal) - /* the_ins.numo */ shorts_this_frag * 2,
+ (the_ins.reloc[m].n + toP - frag_now->fr_literal) - shorts_this_frag * 2,
wid,
the_ins.reloc[m].add,
the_ins.reloc[m].sub,
my lord ghod hath spoken, so we do it this way. Excuse the ugly var
names. */
- register const struct m68k_opcode *ins;
+ register CONST struct m68k_opcode *ins;
register struct m68k_incant *hack, *slak;
register char *retval = 0; /* empty string, or error msg text */
register unsigned int i;
md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
litP += sizeof (LITTLENUM_TYPE);
}
- return ""; /* Someone should teach Dean about null pointers */
+ return 0;
}
/* Turn an integer of n bytes (in val) into a stream of bytes appropriate
}
}
-void
-md_apply_fix (fixP, val)
+static void
+md_apply_fix_2 (fixP, val)
fixS *fixP;
long val;
{
+ unsigned long upper_limit;
+ long lower_limit;
+
#ifdef IBM_COMPILER_SUX
/* This is unnecessary but it convinces the native rs6000
compiler to generate the code we want. */
{
case 1:
*buf++ = val;
+ upper_limit = 0x7f;
+ lower_limit = -0x80;
break;
case 2:
*buf++ = (val >> 8);
*buf++ = val;
+ upper_limit = 0x7fff;
+ lower_limit = -0x8000;
break;
case 4:
*buf++ = (val >> 24);
*buf++ = (val >> 16);
*buf++ = (val >> 8);
*buf++ = val;
+ upper_limit = 0x7fffffff;
+ lower_limit = -0x80000000;
break;
default:
BAD_CASE (fixP->fx_size);
}
+
+ /* For non-pc-relative values, it's conceivable we might get something
+ like "0xff" for a byte field. So extend the upper part of the range
+ to accept such numbers. We arbitrarily disallow "-0xff" or "0xff+0xff",
+ so that we can do any range checking at all. */
+ if (!fixP->fx_pcrel)
+ upper_limit = upper_limit * 2 + 1;
+
+ if ((unsigned) val > upper_limit && (val > 0 || val < lower_limit))
+ as_bad ("value out of range");
}
+#ifdef BFD_ASSEMBLER
+int
+md_apply_fix (fixP, valp)
+ fixS *fixP;
+ long *valp;
+{
+ md_apply_fix_2 (fixP, *valp);
+ return 1;
+}
+#else
+void md_apply_fix (fixP, val)
+ fixS *fixP;
+ long val;
+{
+ md_apply_fix_2 (fixP, val);
+}
+#endif
/* *fragP has been relaxed to its final size, and now needs to have
the bytes inside it modified to conform to the new size There is UGLY
MAGIC here. ..
*/
void
-md_convert_frag (headers, fragP)
- object_headers *headers;
+md_convert_frag_1 (fragP)
register fragS *fragP;
{
long disp;
{
fragP->fr_opcode[0] = 0x4E;
fragP->fr_opcode[1] = 0xB9; /* JBSR with ABSL LONG offset */
- subseg_change (SEG_TEXT, 0);
+ subseg_change (text_section, 0); /* @@ */
fix_new (fragP,
fragP->fr_fix,
{
fragP->fr_opcode[0] = 0x4E;
fragP->fr_opcode[1] = 0xF9; /* JMP with ABSL LONG offset */
- subseg_change (SEG_TEXT, 0);
+ subseg_change (text_section, 0); /* @@ */
fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, fragP->fr_offset, 0,
NO_RELOC);
fragP->fr_fix += 4;
*buffer_address++ = 0x4e; /* put in jmp long (0x4ef9) */
*buffer_address++ = 0xf9;
fragP->fr_fix += 2; /* account for jmp instruction */
- subseg_change (SEG_TEXT, 0);
+ subseg_change (text_section, 0);
fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0,
fragP->fr_offset, 0,
NO_RELOC);
*buffer_address++ = 0xf9;
fragP->fr_fix += 6; /* account for bra/jmp instructions */
- subseg_change (SEG_TEXT, 0);
+ subseg_change (text_section, 0);
fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0,
- fragP->fr_offset, 0,
- NO_RELOC);
+ fragP->fr_offset, 0, NO_RELOC);
fragP->fr_fix += 4;
ext = 0;
break;
/* The thing to do here is force it to ABSOLUTE LONG, since
PCREL is really trying to shorten an ABSOLUTE address anyway */
/* JF FOO This code has not been tested */
- subseg_change (SEG_TEXT, 0);
- fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC);
+ subseg_change (text_section, 0);
+ fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, fragP->fr_offset,
+ 0, NO_RELOC);
if ((fragP->fr_opcode[1] & 0x3F) != 0x3A)
as_bad ("Internal error (long PC-relative operand) for insn 0x%04lx at 0x%lx",
fragP->fr_opcode[0], fragP->fr_address);
fragP->fr_opcode[1] &= ~0x3F;
fragP->fr_opcode[1] |= 0x39; /* Mode 7.1 */
fragP->fr_fix += 4;
- /* md_number_to_chars(buffer_address,
- (long)(fragP->fr_symbol->sy_value + fragP->fr_offset),
- 4); */
ext = 0;
break;
case TAB (PCLEA, SHORT):
- subseg_change (SEG_TEXT, 0);
- fix_new (fragP, (int) (fragP->fr_fix), 2, fragP->fr_symbol, (symbolS *) 0, fragP->fr_offset, 1,
- NO_RELOC);
+ subseg_change (text_section, 0);
+ fix_new (fragP, (int) (fragP->fr_fix), 2, fragP->fr_symbol,
+ (symbolS *) 0, fragP->fr_offset, 1, NO_RELOC);
fragP->fr_opcode[1] &= ~0x3F;
fragP->fr_opcode[1] |= 0x3A;
ext = 2;
break;
case TAB (PCLEA, LONG):
- subseg_change (SEG_TEXT, 0);
- fix_new (fragP, (int) (fragP->fr_fix) + 2, 4, fragP->fr_symbol, (symbolS *) 0, fragP->fr_offset + 2, 1,
- NO_RELOC);
+ subseg_change (text_section, 0);
+ fix_new (fragP, (int) (fragP->fr_fix) + 2, 4, fragP->fr_symbol,
+ (symbolS *) 0, fragP->fr_offset + 2, 1, NO_RELOC);
*buffer_address++ = 0x01;
*buffer_address++ = 0x70;
fragP->fr_fix += 2;
- /* buffer_address+=2; */
ext = 4;
break;
-
- } /* switch on subtype */
+ }
if (ext)
{
md_number_to_chars (buffer_address, (long) disp, (int) ext);
fragP->fr_fix += ext;
- /* H_SET_TEXT_SIZE(headers, H_GET_TEXT_SIZE(headers) + ext); */
- } /* if extending */
+ }
+}
- return;
-} /* md_convert_frag() */
+#ifndef BFD_ASSEMBLER
+
+void
+md_convert_frag (headers, fragP)
+ object_headers *headers;
+ fragS *fragP;
+{
+ md_convert_frag_1 (fragP);
+}
+
+#else
+
+void
+md_convert_frag (abfd, sec, fragP)
+ bfd *abfd;
+ asection sec;
+ fragS *fragP;
+{
+ md_convert_frag_1 (fragP);
+}
+#endif
/* Force truly undefined symbols to their maximum size, and generally set up
the frag list to be relaxed
{
fragP->fr_opcode[0] = 0x4E;
fragP->fr_opcode[1] = 0xB9; /* JBSR with ABSL LONG offset */
- subseg_change (SEG_TEXT, 0);
+ subseg_change (text_section, 0);
fix_new (fragP, fragP->fr_fix, 4,
fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC);
fragP->fr_fix += 4;
{
fragP->fr_opcode[0] = 0x4E;
fragP->fr_opcode[1] = 0xF9; /* JMP with ABSL LONG offset */
- subseg_change (SEG_TEXT, 0);
+ subseg_change (text_section, 0);
fix_new (fragP, fragP->fr_fix, 4,
fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC);
fragP->fr_fix += 4;
buffer_address[0] = 0x4e; /* put in jmp long (0x4ef9) */
buffer_address[1] = 0xf8;
fragP->fr_fix += 2; /* account for jmp instruction */
- subseg_change (SEG_TEXT, 0);
+ subseg_change (text_section, 0);
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, 0,
fragP->fr_offset, 0, NO_RELOC);
fragP->fr_fix += 2;
buffer_address[0] = 0x4e; /* put in jmp long (0x4ef9) */
buffer_address[1] = 0xf9;
fragP->fr_fix += 2; /* account for jmp instruction */
- subseg_change (SEG_TEXT, 0);
+ subseg_change (text_section, 0);
fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0,
fragP->fr_offset, 0, NO_RELOC);
fragP->fr_fix += 4;
buffer_address[4] = 0x4e; /* Put in Jump Word */
buffer_address[5] = 0xf8;
fragP->fr_fix += 6; /* account for bra/jmp instruction */
- subseg_change (SEG_TEXT, 0);
+ subseg_change (text_section, 0);
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, 0,
buffer_address[4] = 0x4e; /* put in jmp long (0x4ef9) */
buffer_address[5] = 0xf9;
fragP->fr_fix += 6; /* account for bra/jmp instruction */
- subseg_change (SEG_TEXT, 0);
+ subseg_change (text_section, 0);
fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0,
fragP->fr_offset, 0, NO_RELOC);
fragP->fr_fix += 4;
#endif /* comment */
+#ifndef BFD_ASSEMBLER
void
tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
char *where;
(((!S_IS_DEFINED (fixP->fx_addsy)) << 4) & 0x10));
return;
-} /* tc_aout_fix_to_chars() */
+}
+#endif
#endif /* OBJ_AOUT or OBJ_BOUT */
#ifndef WORKING_DOT_WORD
-const int md_short_jump_size = 4;
-const int md_long_jump_size = 6;
+CONST int md_short_jump_size = 4;
+CONST int md_long_jump_size = 6;
void
md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
#else
char *save_in;
char c_save;
+ segT section;
if (!exp)
{
}
if (!exp->e_beg || !exp->e_end)
{
- seg (exp) = SEG_ABSOLUTE;
+ seg (exp) = absolute_section;
adds (exp) = 0;
subs (exp) = 0;
offs (exp) = (ok == 10) ? 1 : 0;
exp->e_end[1] = '\0';
save_in = input_line_pointer;
input_line_pointer = exp->e_beg;
- switch (expression (&(exp->e_exp)))
+ section = expression (&exp->e_exp);
+ if (section == pass1_section)
{
- case SEG_PASS1:
- seg (exp) = SEG_ABSOLUTE;
+ seg (exp) = absolute_section;
adds (exp) = 0;
subs (exp) = 0;
offs (exp) = (ok == 10) ? 1 : 0;
as_warn ("Unknown expression: '%s' defaulting to %d", exp->e_beg, offs (exp));
- break;
-
- case SEG_ABSENT:
+ }
+ else if (section == absent_section)
+ {
/* Do the same thing the VAX asm does */
- seg (exp) = SEG_ABSOLUTE;
+ seg (exp) = absolute_section;
adds (exp) = 0;
subs (exp) = 0;
offs (exp) = 0;
as_warn ("expression out of range: defaulting to 1");
offs (exp) = 1;
}
- break;
- case SEG_ABSOLUTE:
+ }
+ else if (section == absolute_section)
+ {
switch (ok)
{
case 10:
default:
break;
}
- break;
- case SEG_BIG:
+ }
+ else if (section == big_section)
+ {
if (offs (exp) < 0 /* flonum */
&& (ok == 80 /* no bignums */
|| (ok > 10 /* small-int ranges including 0 ok */
LITTLENUM_TYPE words[6];
gen_to_words (words, 2, 8L); /* These numbers are magic! */
- seg (exp) = SEG_ABSOLUTE;
+ seg (exp) = absolute_section;
adds (exp) = 0;
subs (exp) = 0;
offs (exp) = words[1] | (words[0] << 16);
}
else if (ok != 0)
{
- seg (exp) = SEG_ABSOLUTE;
+ seg (exp) = absolute_section;
adds (exp) = 0;
subs (exp) = 0;
offs (exp) = (ok == 10) ? 1 : 0;
as_warn ("Can't deal with expression \"%s\": defaulting to %ld", exp->e_beg, offs (exp));
}
- break;
- default:
- case SEG_TEXT:
- case SEG_DATA:
- case SEG_BSS:
- case SEG_UNKNOWN:
- case SEG_DIFFERENCE:
+ }
+ else
+ {
if (ok >= 10 && ok <= 70)
{
- seg (exp) = SEG_ABSOLUTE;
+ seg (exp) = absolute_section;
adds (exp) = 0;
subs (exp) = 0;
offs (exp) = (ok == 10) ? 1 : 0;
as_warn ("Can't deal with expression \"%s\": defaulting to %ld", exp->e_beg, offs (exp));
}
- break;
-
-
}
+
if (input_line_pointer != exp->e_end + 1)
as_bad ("Ignoring junk after expression");
exp->e_end[1] = c_save;
}
return offs (exp);
#endif
-} /* get_num() */
+}
/* These are the back-ends for the various machine dependent pseudo-ops. */
void demand_empty_rest_of_line (); /* Hate those extra verbose names */
static void
s_data1 ()
{
- subseg_new (SEG_DATA, 1);
+ subseg_new (data_section, 1);
demand_empty_rest_of_line ();
-} /* s_data1() */
+}
static void
s_data2 ()
{
- subseg_new (SEG_DATA, 2);
+ subseg_new (data_section, 2);
demand_empty_rest_of_line ();
-} /* s_data2() */
+}
static void
s_bss ()
{
/* We don't support putting frags in the BSS segment, we fake it
- by marking in_bss, then looking at s_skip for clues */
+ by marking in_bss, then looking at s_skip for clues. */
- subseg_new (SEG_BSS, 0);
+ subseg_new (bss_section, 0);
demand_empty_rest_of_line ();
-} /* s_bss() */
+}
static void
s_even ()
if (!need_pass_2) /* Never make frag if expect extra pass. */
frag_align (temp, (int) temp_fill);
demand_empty_rest_of_line ();
-} /* s_even() */
+}
static void
s_proc ()
{
demand_empty_rest_of_line ();
-} /* s_proc() */
+}
/* s_space is defined in read.c .skip is simply an alias to it. */
return (fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address);
}
+#ifndef BFD_ASSEMBLER
void
tc_coff_symbol_emit_hook ()
{
default:
abort ();
}
-
}
+#endif
/* end of tc-m68k.c */
expressionP->X_seg = absolute_section;
break;
+ case '+':
+ operand (expressionP);
+ break;
+
case '~':
case '-':
- case '+':
{
/* unary operator: hope for SEG_ABSOLUTE */
segT opseg = operand (expressionP);
if (expressionP->X_subtract_symbol == expressionP->X_add_symbol
|| (expressionP->X_subtract_symbol
&& expressionP->X_add_symbol
- && expressionP->X_subtract_symbol->sy_frag == expressionP->X_add_symbol->sy_frag
- && S_GET_VALUE (expressionP->X_subtract_symbol) == S_GET_VALUE (expressionP->X_add_symbol)))
+ && (expressionP->X_subtract_symbol->sy_frag
+ == expressionP->X_add_symbol->sy_frag)
+ && (S_GET_VALUE (expressionP->X_subtract_symbol)
+ == S_GET_VALUE (expressionP->X_add_symbol))))
{
expressionP->X_subtract_symbol = NULL;
expressionP->X_add_symbol = NULL;
{
segT return_value;
#ifndef MANY_SEGMENTS
- assert ((*symbol_1_PP) == NULL \
- || (S_GET_SEGMENT (*symbol_1_PP) == text_section) \
- || (S_GET_SEGMENT (*symbol_1_PP) == data_section) \
- || (S_GET_SEGMENT (*symbol_1_PP) == bss_section) \
- || (!S_IS_DEFINED (*symbol_1_PP)));
- assert (symbol_2_P == NULL \
- || (S_GET_SEGMENT (symbol_2_P) == text_section) \
- || (S_GET_SEGMENT (symbol_2_P) == data_section) \
- || (S_GET_SEGMENT (symbol_2_P) == bss_section) \
+#ifndef OBJ_ECOFF
+ int test = ((*symbol_1_PP) == NULL
+ || (S_GET_SEGMENT (*symbol_1_PP) == text_section)
+ || (S_GET_SEGMENT (*symbol_1_PP) == data_section)
+ || (S_GET_SEGMENT (*symbol_1_PP) == bss_section)
+ || (!S_IS_DEFINED (*symbol_1_PP)));
+ assert (test);
+ test = (symbol_2_P == NULL
+ || (S_GET_SEGMENT (symbol_2_P) == text_section)
+ || (S_GET_SEGMENT (symbol_2_P) == data_section)
+ || (S_GET_SEGMENT (symbol_2_P) == bss_section)
|| (!S_IS_DEFINED (symbol_2_P)));
+ assert (test);
+#endif
#endif
if (*symbol_1_PP)
{
}
}
#ifndef MANY_SEGMENTS
- assert (return_value == absolute_section \
- || return_value == text_section \
- || return_value == data_section \
- || return_value == bss_section \
- || return_value == undefined_section \
+#ifndef OBJ_ECOFF
+ test = (return_value == absolute_section
+ || return_value == text_section
+ || return_value == data_section
+ || return_value == bss_section
+ || return_value == undefined_section
|| return_value == pass1_section);
+ assert (test);
+#endif
#endif
know ((*symbol_1_PP) == NULL
|| (S_GET_SEGMENT (*symbol_1_PP) == return_value));
operatorT;
+#undef __
#define __ O_illegal
static const operatorT op_encoding[256] =
segT seg1;
segT seg2;
#ifndef MANY_SEGMENTS
-
+#ifndef OBJ_ECOFF
know (resultP->X_seg == data_section || resultP->X_seg == text_section || resultP->X_seg == bss_section || resultP->X_seg == undefined_section || resultP->X_seg == diff_section || resultP->X_seg == absolute_section || resultP->X_seg == pass1_section || resultP->X_seg == reg_section);
know (right.X_seg == data_section || right.X_seg == text_section || right.X_seg == bss_section || right.X_seg == undefined_section || right.X_seg == diff_section || right.X_seg == absolute_section || right.X_seg == pass1_section);
+#endif
#endif
clean_up_expression (&right);
clean_up_expression (resultP);
know (seg2 != absolute_section);
know (resultP->X_subtract_symbol);
#ifndef MANY_SEGMENTS
+#ifndef OBJ_ECOFF
know (seg1 == text_section || seg1 == data_section || seg1 == bss_section);
know (seg2 == text_section || seg2 == data_section || seg2 == bss_section);
+#endif
#endif
know (resultP->X_add_symbol);
know (resultP->X_subtract_symbol);
if (temp && !need_pass_2)
frag_align (temp, (int) temp_fill);
+ record_alignment (now_seg, temp);
+
demand_empty_rest_of_line ();
} /* s_align_bytes() */