Massive changes to generalize coff-bfd support enough to get 29k
authorSteve Chamberlain <sac@cygnus>
Fri, 29 Nov 1991 01:05:58 +0000 (01:05 +0000)
committerSteve Chamberlain <sac@cygnus>
Fri, 29 Nov 1991 01:05:58 +0000 (01:05 +0000)
working as well as it did before.

This means that 29k now supports multiple sections

gas/config/ebmon29k.mt
gas/config/obj-coff-bfd.c
gas/config/obj-coff-bfd.h
gas/config/tc-a29k.c
gas/config/tc-a29k.h

index 0fda48ef079f84c9198ab176e14778d0cf171476..8534848ef32b57af7126f87a7eab16b66375395f 100644 (file)
@@ -1,6 +1,7 @@
 TARG_CPU_DEPENDENTS=
 LOCAL_LOADLIBES=$(srcdir)/../bfd$(subdir)/libbfd.a
-TDEFINES=-DBFD_HEADERS
+TDEFINES=-DBFD_HEADERS -DMANY_SEGMENTS -DBFD
+
 
 
 
index d2e24e1ea29f0e2286570f65dcc8ea7b97ebf6b1..5c0cd7bc685c783d0af244db87240e33d20328aa 100755 (executable)
@@ -100,6 +100,9 @@ bfd *abfd;
 void EXFUN(bfd_as_write_hook,(struct internal_filehdr *,
                              bfd *abfd));
 
+static void EXFUN(fixup_segment,(fixS *        fixP,
+                 segT  this_segment_type));
+
 static void EXFUN(fill_section,(bfd *abfd ,
                                struct internal_filehdr *f, unsigned
                                long *));
@@ -207,7 +210,16 @@ seg_info_type seg_info_off_by_4[N_SEG] =
 {SEG_E7},
 {SEG_E8}, 
 {SEG_E9},
-{SEG_REGISTER},
+{15},
+{16},
+{17},
+{18},
+{19},
+{20},
+{21},
+{22},
+{23},
+{SEG_REGISTER},0x1111,0x2222,0x3333,0x4444
 
 };
 
@@ -267,24 +279,35 @@ static unsigned int  DEFUN(size_section,(abfd, idx),
   return size;
 }
 
-/* Count the relocations in a chain */
 
 static unsigned int DEFUN(count_entries_in_chain,(idx),
                          unsigned int idx)
 {
-  unsigned int nrelocs;
-  fixS *fixup_ptr;
+    unsigned int nrelocs;
+    fixS *fixup_ptr;
 
-  /* Count the relocations */
-  fixup_ptr = segment_info[idx].fix_root;
-  nrelocs = 0;
-  while (fixup_ptr != (fixS *)NULL) 
-      {
-       nrelocs ++ ;
-       fixup_ptr = fixup_ptr->fx_next;
+    /* Count the relocations */
+    fixup_ptr = segment_info[idx].fix_root;
+    nrelocs = 0;
+    while (fixup_ptr != (fixS *)NULL) 
+    {
+       if (TC_COUNT_RELOC(fixup_ptr)) 
+       {
+           
+#ifdef TC_A29K
 
-      }
-  return nrelocs;
+           if (fixup_ptr->fx_r_type == RELOC_CONSTH)  
+            nrelocs+=2;
+           else                                        
+            nrelocs++;         
+#else
+           nrelocs++;
+#endif
+       }
+       
+       fixup_ptr = fixup_ptr->fx_next;
+    }
+    return nrelocs;
 }
 
 /* output all the relocations for a section */
@@ -292,64 +315,97 @@ void DEFUN(do_relocs_for,(abfd, file_cursor),
           bfd *abfd AND
           unsigned long *file_cursor)
 {
-  unsigned int nrelocs;
-  arelent **reloc_ptr_vector;
-  arelent *reloc_vector;
-  asymbol **ptrs;
-  unsigned int idx;
+    unsigned int nrelocs;
+    arelent **reloc_ptr_vector;
+    arelent *reloc_vector;
+    asymbol **ptrs;
+    unsigned int idx;
   
-  asection *section = (asection *)(segment_info[idx].user_stuff);
-  unsigned int i;
-  fixS *from;
-  for (idx = SEG_E0; idx < SEG_E9; idx++) 
-  {
-    if (segment_info[idx].scnhdr.s_name[0]) 
-    {
 
-      struct external_reloc *ext_ptr;
-      struct external_reloc *external_reloc_vec;
-      unsigned int external_reloc_size;
-      fixS *   fix_ptr = segment_info[idx].fix_root;
-      nrelocs = count_entries_in_chain(idx);
-      external_reloc_size = nrelocs * RELSZ;
-      external_reloc_vec = (struct external_reloc*)alloca(external_reloc_size);
+    unsigned int i;
+    fixS *from;
+    for (idx = SEG_E0; idx < SEG_E9; idx++) 
+    {
+       if (segment_info[idx].scnhdr.s_name[0]) 
+       {
 
-      ext_ptr = external_reloc_vec;
-      
-      /* Fill in the internal coff style reloc struct from the
-        internal fix list */
-      while (fix_ptr)
-      {
-       symbolS *symbol_ptr;
-       struct internal_reloc intr;
-       
-       symbol_ptr = fix_ptr->fx_addsy;
+           struct external_reloc *ext_ptr;
+           struct external_reloc *external_reloc_vec;
+           unsigned int external_reloc_size;
+           unsigned int count = 0;
+           unsigned int base  = segment_info[idx].scnhdr.s_paddr;
+           fixS *   fix_ptr = segment_info[idx].fix_root;
+           nrelocs = count_entries_in_chain(idx);
+           external_reloc_size = nrelocs * RELSZ;
+           external_reloc_vec =
+            (struct external_reloc*)alloca(external_reloc_size);
 
-         /* If this relocation is attached to a symbol then it's ok
-            to output it */
-         intr.r_type = TC_COFF_FIX2RTYPE(fix_ptr);
-         intr.r_vaddr = fix_ptr->fx_frag->fr_address +  fix_ptr->fx_where ;
-         
-         intr.r_offset = fix_ptr->fx_offset;
-         
-       if (symbol_ptr)
-         intr.r_symndx = symbol_ptr->sy_number;
-       else
-        intr.r_symndx = -1;
        
-         (void)bfd_coff_swap_reloc_out(abfd, &intr, ext_ptr);
-         ext_ptr++;
+           
+           ext_ptr = external_reloc_vec;
+           
+           /* Fill in the internal coff style reloc struct from the
+              internal fix list */
+           while (fix_ptr)
+           {
+               symbolS *symbol_ptr;
+               struct internal_reloc intr;
+
+               /* Only output some of the relocations */
+               if (TC_COUNT_RELOC(fix_ptr))
+               {
+                   symbolS *dot;
+                   symbol_ptr = fix_ptr->fx_addsy;
+                   
+                   intr.r_type = TC_COFF_FIX2RTYPE(fix_ptr);
+                   intr.r_vaddr = base +  fix_ptr->fx_frag->fr_address +  fix_ptr->fx_where ;
+
+
+                   /* Turn the segment of the symbol into an offset
+                    */
+                   dot =
+                    segment_info[S_GET_SEGMENT(symbol_ptr)].dot;
+   
+                   if (dot)
+                   {
+                       intr.r_symndx = dot->sy_number;
+                   }
+                   else 
+                   {
+                       intr.r_symndx = symbol_ptr->sy_number;
+                   }
 
-       fix_ptr = fix_ptr->fx_next;
-      }
+               
+                   (void)bfd_coff_swap_reloc_out(abfd, &intr, ext_ptr);
+                   ext_ptr++;
+
+#if defined(TC_A29K)
+                   /* The 29k has a special kludge for the high 16 bit reloc.
+                      Two relocations are emmited, R_IHIHALF, and
+                      R_IHCONST. The second one doesn't contain a symbol,
+                      but uses the value for offset */
+               
+                   if (intr.r_type == R_IHIHALF)
+                   {
+                       /* now emit the second bit */
+                       intr.r_type = R_IHCONST;        
+                       intr.r_symndx = fix_ptr->fx_addnumber;
+                       (void)bfd_coff_swap_reloc_out(abfd,&intr,ext_ptr);
+                       ext_ptr++;
+                   }
+#endif
+               }
+               
+               fix_ptr = fix_ptr->fx_next;
+           }
       
-      /* Write out the reloc table */
-      segment_info[idx].scnhdr.s_relptr = *file_cursor;
-      segment_info[idx].scnhdr.s_nreloc = nrelocs;
-      bfd_write(external_reloc_vec, 1, external_reloc_size, abfd);
-      *file_cursor += external_reloc_size;
+           /* Write out the reloc table */
+           segment_info[idx].scnhdr.s_relptr = *file_cursor;
+           segment_info[idx].scnhdr.s_nreloc = nrelocs;
+           bfd_write(external_reloc_vec, 1, external_reloc_size, abfd);
+           *file_cursor += external_reloc_size;
+       }
     }
-  }
 }
 
 
@@ -368,6 +424,7 @@ static void DEFUN(fill_section,(abfd, filehdr, file_cursor),
   for (i = SEG_E0; i < SEG_UNKNOWN; i++) {  
       unsigned int offset = 0;
 
+
       struct internal_scnhdr *s = &( segment_info[i].scnhdr);
          
       if (s->s_name[0]) {
@@ -382,13 +439,11 @@ static void DEFUN(fill_section,(abfd, filehdr, file_cursor),
           s->s_flags |= STYP_TEXT;
          else if (strcmp(s->s_name,".data")==0)
           s->s_flags |= STYP_DATA;
-         else if (strcmp(s->s_name,".text")==0)
+         else if (strcmp(s->s_name,".bss")==0)
           s->s_flags |= STYP_BSS | STYP_NOLOAD;
 
-
          while (frag) {
              unsigned int fill_size;
-             unsigned int count;
              switch (frag->fr_type) {
                case rs_fill:
                case rs_align:
@@ -404,16 +459,17 @@ static void DEFUN(fill_section,(abfd, filehdr, file_cursor),
                  fill_size = frag->fr_var;
                  if (fill_size)        
                  {
-                   unsigned int off = frag->fr_fix;
-                   for (count = frag->fr_offset; count;  count--) 
-                   {
-                     memcpy(buffer +  frag->fr_address  + off,
-                            frag->fr_literal + frag->fr_fix,
-                            fill_size);
-                     off += fill_size;
-                     offset += fill_size;
+                     unsigned int count ;
+                     unsigned int off = frag->fr_fix;
+                     for (count = frag->fr_offset; count;  count--) 
+                     {
+                         memcpy(buffer +  frag->fr_address  + off,
+                                frag->fr_literal + frag->fr_fix,
+                                fill_size);
+                         off += fill_size;
+                         offset += fill_size;
                      
-                   }
+                     }
 
                  }
                  break;
@@ -423,14 +479,14 @@ static void DEFUN(fill_section,(abfd, filehdr, file_cursor),
              frag = frag->fr_next;
            }
 
-         /*paddr += offset; 
-          This causes problems with relocation. For the moment, all
-          sections start at 0
-          */
+
+
          bfd_write(buffer, s->s_size,1,abfd);
          *file_cursor += s->s_size;
+         paddr += s->s_size;
        }      
     }
+
 }
 
 
@@ -488,6 +544,12 @@ DEFUN(symbol_to_chars,(abfd, where, symbolP),
   {
     S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
   }
+    /* At the same time, relocate all symbols to their output value */
+
+    S_SET_VALUE(symbolP,
+               segment_info[S_GET_SEGMENT(symbolP)].scnhdr.s_paddr 
+               + S_GET_VALUE(symbolP));
+
   *where += bfd_coff_swap_sym_out(abfd, &symbolP->sy_symbol.ost_entry,
                                  *where);
        
@@ -1259,6 +1321,9 @@ static unsigned int DEFUN_VOID(tie_tags)
        symbol_next(symbolP)) 
   {
     symbolP->sy_number = symbol_number;
+
+
+
     if (SF_GET_TAGGED(symbolP)) 
     {
       SA_SET_SYM_TAGNDX
@@ -1277,102 +1342,76 @@ static void DEFUN(crawl_symbols,(headers, abfd),
           bfd *abfd)
 {
 
-  unsigned int i;      
-  unsigned int ptr = 0;
-
-
-  symbolS *symbolP;
-
-  /* Initialize the stack used to keep track of the matching .bb .be */
+    unsigned int i;    
+    unsigned int ptr = 0;
 
-  block_stack = stack_init(512, sizeof(symbolS*));
-  /* JF deal with forward references first... */
-  for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
 
-      if (symbolP->sy_forward) {
-         S_SET_VALUE(symbolP, (S_GET_VALUE(symbolP)
-                               + S_GET_VALUE(symbolP->sy_forward)
-                               + symbolP->sy_forward->sy_frag->fr_address));
-
-         if (SF_GET_GET_SEGMENT(symbolP)) {
-             S_SET_SEGMENT(symbolP, S_GET_SEGMENT(symbolP->sy_forward));
-           }                   /* forward segment also */
+    symbolS *symbolP;
 
-         symbolP->sy_forward=0;
-       }                       /* if it has a forward reference */
-    }                          /* walk the symbol chain */
+    /* Initialize the stack used to keep track of the matching .bb .be */
 
+    block_stack = stack_init(512, sizeof(symbolS*));
+    /* JF deal with forward references first... */
+    for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
 
-  /* The symbol list should be ordered according to the following sequence
-   * order :
-   * . .file symbol
-   * . debug entries for functions
-   * . fake symbols for the sections, including.text .data and .bss
-   * . defined symbols
-   * . undefined symbols
-   * But this is not mandatory. The only important point is to put the
-   * undefined symbols at the end of the list.
-   */
+           if (symbolP->sy_forward) {
+                   S_SET_VALUE(symbolP, (S_GET_VALUE(symbolP)
+                                         + S_GET_VALUE(symbolP->sy_forward)
+                                         + symbolP->sy_forward->sy_frag->fr_address));
+
+                   if (SF_GET_GET_SEGMENT(symbolP)) {
+                           S_SET_SEGMENT(symbolP, S_GET_SEGMENT(symbolP->sy_forward));
+                       }       /* forward segment also */
+
+                   symbolP->sy_forward=0;
+               }               /* if it has a forward reference */
+       }                       /* walk the symbol chain */
+
+
+    /* The symbol list should be ordered according to the following sequence
+     * order :
+     * . .file symbol
+     * . debug entries for functions
+     * . fake symbols for the sections, including.text .data and .bss
+     * . defined symbols
+     * . undefined symbols
+     * But this is not mandatory. The only important point is to put the
+     * undefined symbols at the end of the list.
+     */
 
-  if (symbol_rootP == NULL
-      || S_GET_STORAGE_CLASS(symbol_rootP) != C_FILE) {
-      c_dot_file_symbol("fake");
-    }
-  /* Is there a .file symbol ? If not insert one at the beginning. */
+    if (symbol_rootP == NULL
+       || S_GET_STORAGE_CLASS(symbol_rootP) != C_FILE) {
+           c_dot_file_symbol("fake");
+       }
+    /* Is there a .file symbol ? If not insert one at the beginning. */
 
-  /*
-   * Build up static symbols for the sections
-   */
+    /*
+     * Build up static symbols for the sections, they are filled in later
+     */
 
 
-  for (i = SEG_E0; i < SEG_E9; i++) 
-  {
-    if (segment_info[i].scnhdr.s_name[0])
+    for (i = SEG_E0; i < SEG_E9; i++) 
     {
-      segment_info[i].dot = 
-       c_section_symbol(segment_info[i].scnhdr.s_name,
-                       i,
-                       ptr,
-                       i-SEG_E0+1,
-                       segment_info[i].scnhdr.s_size,
-                       segment_info[i].scnhdr.s_paddr,
-                       0,0);
+       if (segment_info[i].scnhdr.s_name[0])
+       {
+           segment_info[i].dot = 
+            c_section_symbol(segment_info[i].scnhdr.s_name,
+                             i-SEG_E0+1);
+           
+       }
     }
-  }
-
 
-#if defined(DEBUG)
-  verify_symbol_chain(symbol_rootP, symbol_lastP);
-#endif                         /* DEBUG */
 
-  /* Take all the externals out and put them into another chain */
-headers->f_nsyms =   yank_symbols();
-  /* Take the externals and glue them onto the end.*/
- headers->f_nsyms +=  glue_symbols();
+    /* Take all the externals out and put them into another chain */
+    headers->f_nsyms =   yank_symbols();
+    /* Take the externals and glue them onto the end.*/
   headers->f_nsyms +=  glue_symbols();
 
-headers->f_nsyms =   tie_tags();
-  know(symbol_externP == NULL);
-  know(symbol_extern_lastP  == NULL);
+    headers->f_nsyms =   tie_tags();
+    know(symbol_externP == NULL);
+    know(symbol_extern_lastP  == NULL);
 
-#if 0
-  /* FIXME-SOMEDAY 
-     I'm counting line no's here so we know what to put in the section
-     headers, and I'm resolving the addresses since I'm not sure how to
-     do it later. I am NOT resolving the linno's representing functions.
-     Their symbols need a fileptr pointing to this linno when emitted.
-     Thus, I resolve them on emit.  xoxorich. */
-
-  for (lineP = lineno_rootP; lineP; lineP = lineP->next) 
-  {
-      if (lineP->line.l_lnno > 0) {
-         lineP->line.l_addr.l_paddr += ((fragS*)lineP->frag)->fr_address;
-       } else {
-           ;
-         }
-      text_lineno_number++;
-    }                          /* for each line number */
-#endif
-  return;
+    return;
 }
 
 /*
@@ -1406,6 +1445,74 @@ char *where;
 
 
 
+
+/* This is a copy from aout.  All I do is neglect to actually build the symbol. */
+
+static void obj_coff_stab(what)
+int what;
+{
+       char *string;
+       expressionS e;
+       int goof = 0;   /* TRUE if we have aborted. */
+       int length;
+       int saved_type = 0;
+       long longint;
+       symbolS *symbolP = 0;
+
+       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;
+               } /* better be a comma */
+       } /* skip the string */
+
+       /*
+        * Input_line_pointer->after ','.  String->symbol name.
+        */
+       if (!goof) {
+               if (get_absolute_expression_and_terminator(&longint) != ',') {
+                       as_bad("I want a comma after the n_type expression");
+                       goof = 1;
+                       input_line_pointer--; /* Backup over a non-',' char. */
+               } /* on error */
+       } /* no error */
+
+       if (!goof) {
+               if (get_absolute_expression_and_terminator(&longint) != ',') {
+                       as_bad("I want a comma after the n_other expression");
+                       goof = 1;
+                       input_line_pointer--; /* Backup over a non-',' char. */
+               } /* on error */
+       } /* no error */
+
+       if (!goof) {
+               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++;
+                       } /* on goof */
+               } /* not stabd */
+       } /* no error */
+
+       expression(&e);
+
+       if (goof) {
+               ignore_rest_of_line();
+       } else {
+               demand_empty_rest_of_line();
+       } /* on error */
+} /* obj_coff_stab() */
+
+
 static void 
 DEFUN(do_linenos_for,(abfd, file_cursor),
       bfd *abfd AND
@@ -1493,15 +1600,17 @@ extern void DEFUN_VOID(write_object_file)
     struct internal_aouthdr aouthdr;
     unsigned long file_cursor;  
     bfd *abfd;
-  
+      unsigned int addr = 0;  
     abfd = bfd_openw(out_file_name, TARGET_FORMAT);
 
+
     if (abfd == 0) {
            as_perror ("FATAL: Can't create %s", out_file_name);
            exit(42);
        }
     bfd_set_format(abfd, bfd_object);
-    bfd_set_arch_mach(abfd, bfd_arch_h8300, 0);
+    bfd_set_arch_mach(abfd, BFD_ARCH, 0);
+
 
 
     string_byte_count = 4;
@@ -1525,21 +1634,16 @@ extern void DEFUN_VOID(write_object_file)
 
     remove_subsegs();
     
-#if 1
+
     for (i = SEG_E0; i < SEG_UNKNOWN; i++) 
     {
        relax_segment(segment_info[i].frchainP->frch_root, i);
     }
   
-    for (i = SEG_E0; i < SEG_UNKNOWN; i++) 
-    {
-       /*      fixup_segment(segment_info[i].fix_root, i);*/
-    }
-  
-#endif
 
-  {
-      unsigned int addr = 0;
+
+
+
       filehdr.f_nscns = 0;
   
       /* Find out how big the sections are */
@@ -1554,52 +1658,59 @@ extern void DEFUN_VOID(write_object_file)
          if (i == SEG_E2) {
                  /* THis is a special case, we leave the size alone, which will have */
                  /* been made up from all and any lcomms seen */
-
              }
          else {
                  addr += size_section(abfd, i);
              }
       }
-  }
+
+
 
     /* Turn the gas native symbol table shape into a coff symbol table */
-  crawl_symbols(&filehdr, abfd);
+    crawl_symbols(&filehdr, abfd);
 
-  file_cursor =   FILHSZ + SCNHSZ * filehdr.f_nscns ;
+    for (i = SEG_E0; i < SEG_UNKNOWN; i++) 
+    {
+       fixup_segment(segment_info[i].fix_root, i);
+    }
 
-  bfd_seek(abfd, file_cursor, 0);
+    file_cursor =   FILHSZ + SCNHSZ * filehdr.f_nscns ;
 
-  do_relocs_for(abfd, &file_cursor);
-  do_linenos_for(abfd, &file_cursor);
+    bfd_seek(abfd, file_cursor, 0);
 
 
-  /* Plant the data */
+    do_relocs_for(abfd, &file_cursor);
 
-  fill_section(abfd,&filehdr, &file_cursor);
+    do_linenos_for(abfd, &file_cursor);
 
-  filehdr.f_magic = 0x8300;
-  filehdr.f_timdat = 0;
-  filehdr.f_flags = 0;
 
+    /* Plant the data */
 
+    fill_section(abfd,&filehdr, &file_cursor);
 
-{
+    filehdr.f_magic = COFF_MAGIC;
+    filehdr.f_timdat = 0;
+    filehdr.f_flags = 0;
 
-  unsigned int   symtable_size = filehdr.f_nsyms * SYMESZ;
-  char *buffer1 = malloc(symtable_size);
-  char *buffer2 = malloc(string_byte_count+4);
-  char *ptr = buffer1;
-  filehdr.f_symptr = bfd_tell(abfd);
-  w_symbols(abfd,&buffer1, symbol_rootP);
-  bfd_write(ptr, 1, symtable_size, abfd);
 
-  w_strings(buffer2);
-  bfd_write(buffer2, 1, string_byte_count, abfd);
 
-}
-  coff_header_append(abfd, &filehdr, &aouthdr);
+  {
+
+      unsigned int   symtable_size = filehdr.f_nsyms * SYMESZ;
+      char *buffer1 = alloca(symtable_size);
+      char *buffer2 = alloca(string_byte_count+4);
+      char *ptr = buffer1;
+      filehdr.f_symptr = bfd_tell(abfd);
+      w_symbols(abfd,&buffer1, symbol_rootP);
+      bfd_write(ptr, 1, symtable_size, abfd);
 
-  bfd_close_all_done(abfd);
+      w_strings(buffer2);
+      bfd_write(buffer2, 1, string_byte_count, abfd);
+
+  }
+    coff_header_append(abfd, &filehdr, &aouthdr);
+
+    bfd_close_all_done(abfd);
 }
 
 
@@ -1764,26 +1875,19 @@ char *filename;
  * Build a 'section static' symbol.
  */
 
-symbolS *c_section_symbol(name,idx, value, length, nreloc, nlnno)
+symbolS *c_section_symbol(name,idx)
 char *name;
-long value;
-long length;
-unsigned short nreloc;
-unsigned short nlnno;
+int idx;
 {
     symbolS *symbolP;
 
     symbolP = symbol_new(name,idx,
-                        value,
+                        0,
                         &zero_address_frag);
 
     S_SET_STORAGE_CLASS(symbolP, C_STAT);
     S_SET_NUMBER_AUXILIARY(symbolP, 1);
 
-    SA_SET_SCN_SCNLEN(symbolP, length);
-    SA_SET_SCN_NRELOC(symbolP, nreloc);
-    SA_SET_SCN_NLINNO(symbolP, nlnno);
-
     SF_SET_STATICS(symbolP);
 
     return symbolP;
@@ -1795,6 +1899,22 @@ char **where AND
 symbolS *symbol_rootP)
 {
     symbolS *symbolP;
+    unsigned int i;
+    
+    /* First fill in those values we have only just worked out */
+    for (i = SEG_E0; i < SEG_E9; i++) 
+    {
+       symbolP = segment_info[i].dot;
+       if (symbolP) 
+       {
+    
+           SA_SET_SCN_SCNLEN(symbolP, segment_info[i].scnhdr.s_size);
+           SA_SET_SCN_NRELOC(symbolP, segment_info[i].scnhdr.s_nreloc);
+           SA_SET_SCN_NLINNO(symbolP, segment_info[i].scnhdr.s_nlnno);
+           
+       }
+    }
+    
     /*
      * Emit all symbols left in the symbol chain.
      */
@@ -1809,214 +1929,16 @@ symbolS *symbol_rootP)
            if (SF_GET_STRING(symbolP)) {
                    S_SET_OFFSET(symbolP, symbolP->sy_name_offset);
                    S_SET_ZEROES(symbolP, 0);
-           } else {
-                   bzero(symbolP->sy_symbol.ost_entry.n_name, SYMNMLEN);
-                   strncpy(symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN);
-           }
+               } else {
+                       bzero(symbolP->sy_symbol.ost_entry.n_name, SYMNMLEN);
+                       strncpy(symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN);
+                   }
            symbol_to_chars(abfd, where, symbolP);
            S_SET_NAME(symbolP,temp);
-    }
-} /* w_symbols() */
-
-#if 0
-static long fixup_segment(fixP, this_segment_type)
-register fixS *        fixP;
-segT           this_segment_type; /* N_TYPE bits for segment. */
-{
-  register long seg_reloc_count;
-  register symbolS *add_symbolP;
-  register symbolS *sub_symbolP;
-  register long add_number;
-  register int size;
-  register char *place;
-  register long where;
-  register char pcrel;
-  register fragS *fragP;
-  register segT add_symbol_segment = SEG_ABSOLUTE;
-       
-  /* FIXME: remove this line */ /*     fixS *orig = fixP; */
-  seg_reloc_count = 0;
-       
-  for ( ;  fixP;  fixP = fixP->fx_next) {
-      fragP       = fixP->fx_frag;
-      know(fragP);
-      where      = fixP->fx_where;
-      place       = fragP->fr_literal + where;
-      size       = fixP->fx_size;
-      add_symbolP = fixP->fx_addsy;
-#ifdef TC_I960
-      if (fixP->fx_callj && TC_S_IS_CALLNAME(add_symbolP)) {
-         /* Relocation should be done via the
-            associated 'bal' entry point
-            symbol. */
-
-         if (!TC_S_IS_BALNAME(tc_get_bal_of_call(add_symbolP))) {
-             as_bad("No 'bal' entry point for leafproc %s",
-                    S_GET_NAME(add_symbolP));
-             continue;
-           }
-         fixP->fx_addsy = add_symbolP = tc_get_bal_of_call(add_symbolP);
-       }                       /* callj relocation */
-#endif
-      sub_symbolP = fixP->fx_subsy;
-      add_number  = fixP->fx_offset;
-      pcrel      = fixP->fx_pcrel;
-
-      if (add_symbolP) {
-         add_symbol_segment = S_GET_SEGMENT(add_symbolP);
-       }                       /* if there is an addend */
-               
-      if (sub_symbolP) {
-         if (!add_symbolP) {
-             /* Its just -sym */
-             if (S_GET_SEGMENT(sub_symbolP) != SEG_ABSOLUTE) {
-                 as_bad("Negative of non-absolute symbol %s", S_GET_NAME(sub_symbolP));
-               }               /* not absolute */
-                               
-             add_number -= S_GET_VALUE(sub_symbolP);
-                               
-             /* if sub_symbol is in the same segment that add_symbol
-                and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
-           } else if ((S_GET_SEGMENT(sub_symbolP) == add_symbol_segment)
-                      && (SEG_NORMAL(add_symbol_segment)
-                          || (add_symbol_segment == SEG_ABSOLUTE))) {
-               /* Difference of 2 symbols from same segment. */
-               /* Can't make difference of 2 undefineds: 'value' means */
-               /* something different for N_UNDF. */
-#ifdef TC_I960
-               /* Makes no sense to use the difference of 2 arbitrary symbols
-                * as the target of a call instruction.
-                */
-               if (fixP->fx_callj) {
-                   as_bad("callj to difference of 2 symbols");
-                 }
-#endif                         /* TC_I960 */
-               add_number += S_GET_VALUE(add_symbolP) - 
-                S_GET_VALUE(sub_symbolP);
-                               
-               add_symbolP = NULL;
-               fixP->fx_addsy = NULL;
-             } else {
-                 /* Different segments in subtraction. */
-                 know(!(S_IS_EXTERNAL(sub_symbolP) && (S_GET_SEGMENT(sub_symbolP) == SEG_ABSOLUTE)));
-                               
-                 if ((S_GET_SEGMENT(sub_symbolP) == SEG_ABSOLUTE)) {
-                     add_number -= S_GET_VALUE(sub_symbolP);
-                   } else {
-                       as_bad("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
-                              segment_name(S_GET_SEGMENT(sub_symbolP)),
-                              S_GET_NAME(sub_symbolP), fragP->fr_address + where);
-                     }         /* if absolute */
-               }
-       }                       /* if sub_symbolP */
-
-      if (add_symbolP) {
-         if (add_symbol_segment == this_segment_type && pcrel) {
-             /*
-              * This fixup was made when the symbol's segment was
-              * SEG_UNKNOWN, but it is now in the local segment.
-              * So we know how to do the address without relocation.
-              */
-#ifdef TC_I960
-             /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
-              * in which cases it modifies *fixP as appropriate.  In the case
-              * of a 'calls', no further work is required, and *fixP has been
-              * set up to make the rest of the code below a no-op.
-              */
-             reloc_callj(fixP);
-#endif                         /* TC_I960 */
-                               
-             add_number += S_GET_VALUE(add_symbolP);
-             add_number -= md_pcrel_from (fixP);
-             pcrel = 0;        /* Lie. Don't want further pcrel processing. */
-             fixP->fx_addsy = NULL; /* No relocations please. */
-           } else {
-               switch (add_symbol_segment) {
-                 case SEG_ABSOLUTE:
-#ifdef TC_I960
-                   reloc_callj(fixP); /* See comment about reloc_callj() above*/
-#endif                         /* TC_I960 */
-                   add_number += S_GET_VALUE(add_symbolP);
-                   fixP->fx_addsy = NULL;
-                   add_symbolP = NULL;
-                   break;
-                 default:
-                   seg_reloc_count ++;
-                   add_number += S_GET_VALUE(add_symbolP);
-                   break;
-                                       
-                 case SEG_UNKNOWN:
-#ifdef TC_I960
-                   if ((int)fixP->fx_bit_fixP == 13) {
-                       /* This is a COBR instruction.  They have only a
-                        * 13-bit displacement and are only to be used
-                        * for local branches: flag as error, don't generate
-                        * relocation.
-                        */
-                       as_bad("can't use COBR format with external label");
-                       fixP->fx_addsy = NULL; /* No relocations please. */
-                       continue;
-                     }         /* COBR */
-#endif                         /* TC_I960 */
-                   /* FIXME-SOON: I think this is trash, but I'm not sure.  xoxorich. */
-#ifdef comment
-#ifdef OBJ_COFF
-                   if (S_IS_COMMON(add_symbolP))
-                    add_number += S_GET_VALUE(add_symbolP);
-#endif                         /* OBJ_COFF */
-#endif                         /* comment */
-               
-                   ++seg_reloc_count;
-
-                   break;
-                                       
-
-                 }             /* switch on symbol seg */
-             }                 /* if not in local seg */
-       }                       /* if there was a + symbol */
-
-      if (pcrel) {
-         add_number -= md_pcrel_from(fixP);
-         if (add_symbolP == 0) {
-             fixP->fx_addsy = & abs_symbol;
-             ++seg_reloc_count;
-           }                   /* if there's an add_symbol */
-       }                       /* if pcrel */
-               
-      if (!fixP->fx_bit_fixP) {
-         if ((size==1 &&
-              (add_number& ~0xFF)   && (add_number&~0xFF!=(-1&~0xFF))) ||
-             (size==2 &&
-              (add_number& ~0xFFFF) && (add_number&~0xFFFF!=(-1&~0xFFFF)))) {
-             as_bad("Value of %d too large for field of %d bytes at 0x%x",
-                    add_number, size, fragP->fr_address + where);
-           }                   /* generic error checking */
-       }                       /* not a bit fix */
-               
-      md_apply_fix(fixP, add_number);
-    }                          /* For each fixS in this segment. */
-       
-#ifdef OBJ_COFF
-#ifdef TC_I960
-{
-  fixS *topP = fixP;
-               
-  /* two relocs per callj under coff. */
-  for (fixP = topP; fixP; fixP = fixP->fx_next) {
-      if (fixP->fx_callj && fixP->fx_addsy != 0) {
-         ++seg_reloc_count;
-       }                       /* if callj and not already fixed. */
-    }                          /* for each fix */
-}
-#endif                         /* TC_I960 */
-
-#endif                         /* OBJ_COFF */
-  return(seg_reloc_count);
-}                              /* fixup_segment() */
-#endif
-
+       }
+}                              /* w_symbols() */
 
-void obj_coff_lcomm(void)
+static void DEFUN_VOID(obj_coff_lcomm)
 {
     char *name;
     char c;
@@ -2025,6 +1947,8 @@ void obj_coff_lcomm(void)
     symbolS *symbolP;
     name = input_line_pointer;
 
+
+
     c = get_symbol_end();
     p = input_line_pointer;
     *p = c;
@@ -2052,3 +1976,184 @@ void obj_coff_lcomm(void)
     S_SET_STORAGE_CLASS(symbolP, C_STAT);
     demand_empty_rest_of_line();
 }
+
+
+#if 1
+static void DEFUN(fixup_segment,(fixP, this_segment_type),
+register fixS *        fixP AND
+segT           this_segment_type)
+{
+    register symbolS *add_symbolP;
+    register symbolS *sub_symbolP;
+    register long add_number;
+    register int size;
+    register char *place;
+    register long where;
+    register char pcrel;
+    register fragS *fragP;
+    register segT add_symbol_segment = SEG_ABSOLUTE;
+       
+       
+    for ( ;  fixP;  fixP = fixP->fx_next) 
+    {
+       fragP       = fixP->fx_frag;
+       know(fragP);
+       where     = fixP->fx_where;
+       place       = fragP->fr_literal + where;
+       size      = fixP->fx_size;
+       add_symbolP = fixP->fx_addsy;
+#ifdef TC_I960
+       if (fixP->fx_callj && TC_S_IS_CALLNAME(add_symbolP)) {
+               /* Relocation should be done via the
+                  associated 'bal' entry point
+                  symbol. */
+
+               if (!TC_S_IS_BALNAME(tc_get_bal_of_call(add_symbolP))) {
+                       as_bad("No 'bal' entry point for leafproc %s",
+                              S_GET_NAME(add_symbolP));
+                       continue;
+                   }
+               fixP->fx_addsy = add_symbolP = tc_get_bal_of_call(add_symbolP);
+           }                   /* callj relocation */
+#endif
+       sub_symbolP = fixP->fx_subsy;
+       add_number  = fixP->fx_offset;
+       pcrel     = fixP->fx_pcrel;
+
+       if (add_symbolP) {
+               add_symbol_segment = S_GET_SEGMENT(add_symbolP);
+           }                   /* if there is an addend */
+               
+       if (sub_symbolP) {
+               if (!add_symbolP) {
+                       /* Its just -sym */
+                       if (S_GET_SEGMENT(sub_symbolP) != SEG_ABSOLUTE) {
+                               as_bad("Negative of non-absolute symbol %s", S_GET_NAME(sub_symbolP));
+                           }   /* not absolute */
+                               
+                       add_number -= S_GET_VALUE(sub_symbolP);
+                               
+                       /* if sub_symbol is in the same segment that add_symbol
+                          and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
+                   } else if ((S_GET_SEGMENT(sub_symbolP) == add_symbol_segment)
+                              && (SEG_NORMAL(add_symbol_segment)
+                                  || (add_symbol_segment == SEG_ABSOLUTE))) {
+                           /* Difference of 2 symbols from same segment. */
+                           /* Can't make difference of 2 undefineds: 'value' means */
+                           /* something different for N_UNDF. */
+#ifdef TC_I960
+                           /* Makes no sense to use the difference of 2 arbitrary symbols
+                            * as the target of a call instruction.
+                            */
+                           if (fixP->fx_callj) {
+                                   as_bad("callj to difference of 2 symbols");
+                               }
+#endif                         /* TC_I960 */
+                           add_number += S_GET_VALUE(add_symbolP) - 
+                            S_GET_VALUE(sub_symbolP);
+                               
+                           add_symbolP = NULL;
+                           fixP->fx_addsy = NULL;
+                       } else {
+                               /* Different segments in subtraction. */
+                               know(!(S_IS_EXTERNAL(sub_symbolP) && (S_GET_SEGMENT(sub_symbolP) == SEG_ABSOLUTE)));
+                               
+                               if ((S_GET_SEGMENT(sub_symbolP) == SEG_ABSOLUTE)) {
+                                       add_number -= S_GET_VALUE(sub_symbolP);
+                                   } else {
+                                           as_bad("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
+                                                  segment_name(S_GET_SEGMENT(sub_symbolP)),
+                                                  S_GET_NAME(sub_symbolP), fragP->fr_address + where);
+                                       } /* if absolute */
+                           }
+           }                   /* if sub_symbolP */
+
+       if (add_symbolP) {
+               if (add_symbol_segment == this_segment_type && pcrel) {
+                       /*
+                        * This fixup was made when the symbol's segment was
+                        * SEG_UNKNOWN, but it is now in the local segment.
+                        * So we know how to do the address without relocation.
+                        */
+#ifdef TC_I960
+                       /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
+                        * in which cases it modifies *fixP as appropriate.  In the case
+                        * of a 'calls', no further work is required, and *fixP has been
+                        * set up to make the rest of the code below a no-op.
+                        */
+                       reloc_callj(fixP);
+#endif                         /* TC_I960 */
+                               
+                       add_number += S_GET_VALUE(add_symbolP);
+                       add_number -= md_pcrel_from (fixP);
+                       pcrel = 0; /* Lie. Don't want further pcrel processing. */
+                       fixP->fx_addsy = NULL; /* No relocations please. */
+                   } else 
+                   {
+                       switch (add_symbol_segment) 
+                       {
+                         case SEG_ABSOLUTE:
+#ifdef TC_I960
+                           reloc_callj(fixP); /* See comment about reloc_callj() above*/
+#endif                         /* TC_I960 */
+                           add_number += S_GET_VALUE(add_symbolP);
+                           fixP->fx_addsy = NULL;
+                           add_symbolP = NULL;
+                           break;
+                         default:
+
+                           add_number += S_GET_VALUE(add_symbolP) +
+               segment_info[S_GET_SEGMENT(add_symbolP)].scnhdr.s_paddr ;
+                           break;
+                                       
+                         case SEG_UNKNOWN:
+#ifdef TC_I960
+                           if ((int)fixP->fx_bit_fixP == 13) {
+                                   /* This is a COBR instruction.  They have only a
+                                    * 13-bit displacement and are only to be used
+                                    * for local branches: flag as error, don't generate
+                                    * relocation.
+                                    */
+                                   as_bad("can't use COBR format with external label");
+                                   fixP->fx_addsy = NULL; /* No relocations please. */
+                                   continue;
+                               } /* COBR */
+#endif                         /* TC_I960 */
+               
+
+
+                           break;
+                                       
+
+                       }       /* switch on symbol seg */
+                   }           /* if not in local seg */
+           }                   /* if there was a + symbol */
+
+       if (pcrel) {
+               add_number -= md_pcrel_from(fixP);
+               if (add_symbolP == 0) {
+                       fixP->fx_addsy = & abs_symbol;
+                   }           /* if there's an add_symbol */
+           }                   /* if pcrel */
+               
+       if (!fixP->fx_bit_fixP) {
+               if ((size==1 &&
+                    (add_number& ~0xFF)   && (add_number&~0xFF!=(-1&~0xFF))) ||
+                   (size==2 &&
+                    (add_number& ~0xFFFF) && (add_number&~0xFFFF!=(-1&~0xFFFF)))) {
+                       as_bad("Value of %d too large for field of %d bytes at 0x%x",
+                              add_number, size, fragP->fr_address + where);
+                   }           /* generic error checking */
+           }                   /* not a bit fix */
+       /* once this fix has been applied, we don't have to output anything 
+          nothing more need be done -*/
+       md_apply_fix(fixP, add_number);
+      
+    }                          /* For each fixS in this segment. */
+       
+
+}                              /* fixup_segment() */
+#endif
+
+
+
index 7bdcc0b7be3731f36127fd56478081be1c168056..dc8e3fdece7e276e0f2dbac3b27752d13f2a4752 100755 (executable)
@@ -146,7 +146,7 @@ typedef struct
 #define C_DEBUG_SECTION                N_DEBUG
 #define C_NTV_SECTION          N_TV
 #define C_PTV_SECTION          P_TV
-#define C_REGISTER_SECTION     4
+#define C_REGISTER_SECTION     20
 
 /*
  *  Macros to extract information from a symbol table entry.
index 3e716d514b13c75e6ba0f77e9e3828c729c1ead7..57e826d1375f1999e507fe59760a87f3da988fc8 100644 (file)
@@ -770,27 +770,6 @@ void md_apply_fix(fixP, val)
 
     fixP->fx_addnumber = val;  /* Remember value for emit_reloc */
 
-    if (fixP->fx_r_type == NO_RELOC) {
-       as_fatal("failed sanity check.");               /* FIXME-SOON, if this is never used, remove */
-       switch (fixP->fx_size) {
-       case 1:
-               *buf = val;
-               break;
-       case 2:
-               *buf++ = (val>>8);
-               *buf = val;
-               break;
-       case 4:
-               *buf++ = (val>>24);
-               *buf++ = (val>>16);
-               *buf++ = (val>>8);
-               *buf = val;
-               break;
-       default:
-               as_fatal("failed sanity check.");
-       }
-       return;
-    }
 
     know(fixP->fx_size == 4);
     know(fixP->fx_r_type < NO_RELOC);
index 85f4de5e203de1133089ddbf70266fa52cb31ab5..8730c2ab992dc8b36a123f77ae1a1b643b0dfe21 100644 (file)
@@ -27,5 +27,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define tc_coff_symbol_emit_hook(a)    ; /* not used */
 
 #define AOUT_MACHTYPE 101
-
+#define TC_COFF_FIX2RTYPE(fix_ptr) tc_coff_fix2rtype(fix_ptr)
+#define BFD_ARCH bfd_arch_a29k
+#define COFF_MAGIC SIPFBOMAGIC
+/* Should the reloc be output ? 
+       on the 29k, this is true only if there is a symbol attatched.
+       on the h8, this is allways true, since no fixup is done
+*/
+#define TC_COUNT_RELOC(x) (x->fx_addsy)
 /* end of tc-a29k.h */
+
This page took 0.038772 seconds and 4 git commands to generate.