From: Ken Raeburn Date: Thu, 27 May 1993 19:42:23 +0000 (+0000) Subject: read.c (s_align_bytes): Properly record alignment. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=49864cfa6cfbd8c2a337765346dfda2597e6b8ac;p=binutils-gdb.git read.c (s_align_bytes): Properly record alignment. 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.) --- diff --git a/gas/ChangeLog b/gas/ChangeLog index 7c039b9e46c..0329af13dcf 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,38 @@ +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 diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c new file mode 100644 index 00000000000..e122d37b46e --- /dev/null +++ b/gas/config/obj-elf.c @@ -0,0 +1,1189 @@ +/* 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 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 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"); +} diff --git a/gas/config/tc-a29k.c b/gas/config/tc-a29k.c index dd13b62c6f0..0a9c22af61d 100644 --- a/gas/config/tc-a29k.c +++ b/gas/config/tc-a29k.c @@ -98,12 +98,12 @@ int md_short_jump_size = 4; 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 diff --git a/gas/config/tc-h8500.c b/gas/config/tc-h8500.c index 4cd741d65b4..0379f7176cf 100644 --- a/gas/config/tc-h8500.c +++ b/gas/config/tc-h8500.c @@ -58,7 +58,7 @@ const pseudo_typeS md_pseudo_table[] = {0, 0, 0} }; -int md_reloc_size; +const int md_reloc_size; const char EXP_CHARS[] = "eE"; diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 0a6b57302b3..0f5d2186ed3 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -27,7 +27,6 @@ #include #include "as.h" -#include "read.h" #include "obstack.h" #include "opcode/i386.h" @@ -46,13 +45,14 @@ typedef struct /* 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. */ @@ -65,23 +65,23 @@ typedef struct 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; @@ -91,7 +91,11 @@ i386_insn; /* 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' @@ -176,70 +180,108 @@ static int this_operand; /* current operand we are working on */ 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. */ @@ -252,12 +294,20 @@ dummy () 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} }; @@ -305,9 +355,9 @@ md_begin () 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); @@ -554,11 +604,33 @@ pt (t) #endif /* DEBUG386 */ -/* - 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; @@ -576,8 +648,8 @@ md_assemble (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. */ @@ -646,7 +718,7 @@ md_assemble (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) { @@ -786,8 +858,10 @@ md_assemble (line) #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. @@ -1090,11 +1164,13 @@ md_assemble (line) 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) { - /* (%esp) becomes two byte modrm with no index register. */ + /* (%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; @@ -1105,8 +1181,8 @@ md_assemble (line) { 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; @@ -1173,7 +1249,7 @@ md_assemble (line) 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; @@ -1256,25 +1332,27 @@ md_assemble (line) 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) @@ -1293,13 +1371,12 @@ md_assemble (line) 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); @@ -1315,7 +1392,6 @@ md_assemble (line) : ENCODE_RELAX_STATE (COND_JUMP, BYTE)), i.disps[0]->X_add_symbol, n, p); - break; } } else if (t->opcode_modifier & (JumpByte | JumpDword)) @@ -1336,35 +1412,34 @@ md_assemble (line) } 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); } @@ -1430,7 +1505,7 @@ md_assemble (line) { 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)) { @@ -1449,7 +1524,7 @@ md_assemble (line) } } 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, @@ -1469,7 +1544,7 @@ md_assemble (line) { 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)) { @@ -1488,7 +1563,7 @@ md_assemble (line) } } 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; @@ -1600,7 +1675,7 @@ i386_operand (operand_string) 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) @@ -1616,36 +1691,46 @@ i386_operand (operand_string) 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: @@ -1686,17 +1771,17 @@ i386_operand (operand_string) 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--; @@ -1712,8 +1797,8 @@ i386_operand (operand_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; @@ -1829,12 +1914,12 @@ i386_operand (operand_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; @@ -1847,29 +1932,35 @@ i386_operand (operand_string) 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 } } @@ -1881,12 +1972,15 @@ i386_operand (operand_string) 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)) { @@ -1975,10 +2069,18 @@ md_estimate_size_before_relax (fragP, segment) * 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; @@ -2049,7 +2151,7 @@ md_convert_frag (headers, fragP) 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) @@ -2135,8 +2237,8 @@ md_number_to_chars (con, value, nbytes) 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. */ { @@ -2162,6 +2264,25 @@ md_apply_fix (fixP, value) } } +#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. */ @@ -2176,64 +2297,6 @@ md_chars_to_number (con, nbytes) 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 */ #define MAX_LITTLENUMS 6 @@ -2286,7 +2349,7 @@ md_atof (type, litP, sizeP) md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE)); litP += sizeof (LITTLENUM_TYPE); } - return ""; /* Someone should teach Dean about null pointers */ + return 0; } char output_invalid_buf[8]; @@ -2362,85 +2425,103 @@ md_pcrel_from (fixP) 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) @@ -2457,6 +2538,18 @@ 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 */ diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c index 965a6fb55c5..f916fa72ed5 100644 --- a/gas/config/tc-m68k.c +++ b/gas/config/tc-m68k.c @@ -40,6 +40,7 @@ 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 @@ -49,10 +50,11 @@ long omagic = 2 << 16 | OMAGIC; /* Magic byte for header file */ #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' @@ -61,25 +63,23 @@ const char comment_chars[] = "|"; 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 */ @@ -349,6 +349,11 @@ struct m68k_it 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) @@ -373,36 +378,38 @@ static struct m68k_it the_ins; /* the instruction being assembled */ /* 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; @@ -419,42 +426,21 @@ struct m68k_incant #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 */ @@ -462,8 +448,8 @@ static int current_architecture = 0; /* 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: @@ -471,8 +457,7 @@ static int current_architecture = 0; 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 */ @@ -522,7 +507,7 @@ const relax_typeS 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}, @@ -542,7 +527,7 @@ const pseudo_typeS md_pseudo_table[] = */ extern void obj_coff_section (); -const pseudo_typeS mote_pseudo_table[] = +CONST pseudo_typeS mote_pseudo_table[] = { {"dc.l", cons, 4}, @@ -564,9 +549,6 @@ const pseudo_typeS mote_pseudo_table[] = 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) @@ -639,7 +621,7 @@ m68k_reg_parse (ccp) 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); @@ -938,7 +920,7 @@ m68k_ip_op (str, opP) #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 = ---- ----------- @@ -1257,30 +1239,35 @@ m68k_ip_op (str, opP) 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] == ',') { @@ -1412,7 +1399,7 @@ m68k_ip_op (str, opP) } /* m68k_ip_op() */ -#ifdef M68KCOFF +#if defined (M68KCOFF) && !defined (BFD_ASSEMBLER) short tc_coff_fix2rtype (fixP) @@ -1431,6 +1418,47 @@ 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 () { @@ -1460,9 +1488,9 @@ 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; /* @@ -1614,9 +1642,8 @@ m68k_ip (instring) /* 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)) @@ -1629,11 +1656,11 @@ m68k_ip (instring) 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 '!': @@ -1854,8 +1881,10 @@ m68k_ip (instring) { 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; @@ -2032,10 +2061,10 @@ m68k_ip (instring) default: { int got_one = 0, idx; - const static struct + CONST static struct { int arch; - const char *name; + CONST char *name; } archs[] = { @@ -2113,7 +2142,7 @@ m68k_ip (instring) 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]) @@ -2170,7 +2199,7 @@ m68k_ip (instring) break; } /* Its BIG */ #else - if (seg (opP->con1) != SEG_BIG) + if (seg (opP->con1) != big_section) { abort (); } @@ -2278,8 +2307,8 @@ m68k_ip (instring) 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 */ @@ -2321,13 +2350,13 @@ m68k_ip (instring) 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 @@ -2345,11 +2374,10 @@ m68k_ip (instring) 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: @@ -2460,8 +2488,8 @@ m68k_ip (instring) 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])) @@ -2615,6 +2643,7 @@ m68k_ip (instring) case 'w': if (isvar (opP->con1)) { +#if 1 /* check for DBcc instruction */ if ((the_ins.opcode[0] & 0xf0f8) == 0x50c8) { @@ -2623,7 +2652,7 @@ m68k_ip (instring) 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); @@ -3342,6 +3371,7 @@ insert_reg (regname, regnum) { char buf[100]; int i; +symbolS *s; #ifdef REGISTER_PREFIX buf[0] = REGISTER_PREFIX; @@ -3349,22 +3379,25 @@ insert_reg (regname, regnum) 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, @@ -3582,7 +3615,8 @@ md_assemble (str) } 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) @@ -3612,7 +3646,8 @@ md_assemble (str) 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, @@ -3648,9 +3683,9 @@ md_assemble (str) } 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; @@ -3668,9 +3703,9 @@ md_assemble (str) 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; @@ -3696,7 +3731,7 @@ md_assemble (str) 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, @@ -3733,7 +3768,7 @@ md_begin () 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; @@ -3894,7 +3929,7 @@ md_atof (type, litP, sizeP) 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 @@ -3930,11 +3965,14 @@ md_number_to_chars (buf, val, n) } } -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. */ @@ -3948,30 +3986,62 @@ md_apply_fix (fixP, val) { 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; @@ -4023,7 +4093,7 @@ md_convert_frag (headers, fragP) { 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, @@ -4041,7 +4111,7 @@ md_convert_frag (headers, fragP) { 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; @@ -4070,7 +4140,7 @@ md_convert_frag (headers, fragP) *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); @@ -4089,10 +4159,9 @@ md_convert_frag (headers, fragP) *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; @@ -4111,49 +4180,64 @@ md_convert_frag (headers, fragP) /* 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 @@ -4188,7 +4272,7 @@ md_estimate_size_before_relax (fragP, segment) { 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; @@ -4198,7 +4282,7 @@ md_estimate_size_before_relax (fragP, segment) { 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; @@ -4270,7 +4354,7 @@ md_estimate_size_before_relax (fragP, segment) 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; @@ -4282,7 +4366,7 @@ md_estimate_size_before_relax (fragP, segment) 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; @@ -4313,7 +4397,7 @@ md_estimate_size_before_relax (fragP, segment) 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, @@ -4327,7 +4411,7 @@ md_estimate_size_before_relax (fragP, segment) 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; @@ -4406,6 +4490,7 @@ md_ri_to_chars (the_bytes, ri) #endif /* comment */ +#ifndef BFD_ASSEMBLER void tc_aout_fix_to_chars (where, fixP, segment_address_in_file) char *where; @@ -4438,13 +4523,14 @@ tc_aout_fix_to_chars (where, fixP, segment_address_in_file) (((!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) @@ -4524,6 +4610,7 @@ get_num (exp, ok) #else char *save_in; char c_save; + segT section; if (!exp) { @@ -4532,7 +4619,7 @@ get_num (exp, ok) } 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; @@ -4573,19 +4660,19 @@ get_num (exp, ok) 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; @@ -4594,8 +4681,9 @@ get_num (exp, ok) 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: @@ -4640,8 +4728,9 @@ get_num (exp, ok) 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 */ @@ -4654,38 +4743,32 @@ get_num (exp, 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; @@ -4706,7 +4789,7 @@ get_num (exp, ok) } 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 */ @@ -4714,26 +4797,26 @@ 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 () @@ -4746,13 +4829,13 @@ 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. */ @@ -5030,6 +5113,7 @@ md_pcrel_from (fixP) return (fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address); } +#ifndef BFD_ASSEMBLER void tc_coff_symbol_emit_hook () { @@ -5050,7 +5134,7 @@ tc_coff_sizemachdep (frag) default: abort (); } - } +#endif /* end of tc-m68k.c */ diff --git a/gas/expr.c b/gas/expr.c index bc083748ccd..ede4e904137 100644 --- a/gas/expr.c +++ b/gas/expr.c @@ -506,9 +506,12 @@ operand (expressionP) expressionP->X_seg = absolute_section; break; + case '+': + operand (expressionP); + break; + case '~': case '-': - case '+': { /* unary operator: hope for SEG_ABSOLUTE */ segT opseg = operand (expressionP); @@ -677,8 +680,10 @@ clean_up_expression (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; @@ -721,16 +726,20 @@ expr_part (symbol_1_PP, symbol_2_P) { 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) { @@ -785,12 +794,15 @@ expr_part (symbol_1_PP, symbol_2_P) } } #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)); @@ -836,6 +848,7 @@ typedef enum operatorT; +#undef __ #define __ O_illegal static const operatorT op_encoding[256] = @@ -975,10 +988,11 @@ expr (rank, resultP) 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); @@ -1000,8 +1014,10 @@ expr (rank, 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); diff --git a/gas/read.c b/gas/read.c index 78061ef3411..d50ed86147a 100644 --- a/gas/read.c +++ b/gas/read.c @@ -722,6 +722,8 @@ s_align_bytes (arg) if (temp && !need_pass_2) frag_align (temp, (int) temp_fill); + record_alignment (now_seg, temp); + demand_empty_rest_of_line (); } /* s_align_bytes() */