aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorSteve Chamberlain <sac@cygnus>1991-11-29 01:05:58 +0000
committerSteve Chamberlain <sac@cygnus>1991-11-29 01:05:58 +0000
commit63c92fcd9644cf4980bc004911165d46c5814d4e (patch)
treed9d4b52bfdefd3de04b7274d22e54f9eeda211b9 /gas
parentada269da8774cba8e43f8dc75a08f6a45ab78495 (diff)
downloadgdb-63c92fcd9644cf4980bc004911165d46c5814d4e.zip
gdb-63c92fcd9644cf4980bc004911165d46c5814d4e.tar.gz
gdb-63c92fcd9644cf4980bc004911165d46c5814d4e.tar.bz2
Massive changes to generalize coff-bfd support enough to get 29k
working as well as it did before. This means that 29k now supports multiple sections
Diffstat (limited to 'gas')
-rw-r--r--gas/config/ebmon29k.mt3
-rwxr-xr-xgas/config/obj-coff-bfd.c927
-rwxr-xr-xgas/config/obj-coff-bfd.h2
-rw-r--r--gas/config/tc-a29k.c21
-rw-r--r--gas/config/tc-a29k.h10
5 files changed, 528 insertions, 435 deletions
diff --git a/gas/config/ebmon29k.mt b/gas/config/ebmon29k.mt
index 0fda48e..8534848 100644
--- a/gas/config/ebmon29k.mt
+++ b/gas/config/ebmon29k.mt
@@ -1,6 +1,7 @@
TARG_CPU_DEPENDENTS=
LOCAL_LOADLIBES=$(srcdir)/../bfd$(subdir)/libbfd.a
-TDEFINES=-DBFD_HEADERS
+TDEFINES=-DBFD_HEADERS -DMANY_SEGMENTS -DBFD
+
diff --git a/gas/config/obj-coff-bfd.c b/gas/config/obj-coff-bfd.c
index d2e24e1..5c0cd7b 100755
--- a/gas/config/obj-coff-bfd.c
+++ b/gas/config/obj-coff-bfd.c
@@ -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
+
+
+
diff --git a/gas/config/obj-coff-bfd.h b/gas/config/obj-coff-bfd.h
index 7bdcc0b..dc8e3fd 100755
--- a/gas/config/obj-coff-bfd.h
+++ b/gas/config/obj-coff-bfd.h
@@ -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.
diff --git a/gas/config/tc-a29k.c b/gas/config/tc-a29k.c
index 3e716d5..57e826d 100644
--- a/gas/config/tc-a29k.c
+++ b/gas/config/tc-a29k.c
@@ -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);
diff --git a/gas/config/tc-a29k.h b/gas/config/tc-a29k.h
index 85f4de5..8730c2a 100644
--- a/gas/config/tc-a29k.h
+++ b/gas/config/tc-a29k.h
@@ -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 */
+