From bea9907b2a19c3ed94595a88003b8900938b0ad9 Mon Sep 17 00:00:00 2001 From: Timothy Wall Date: Thu, 3 Feb 2000 18:20:23 +0000 Subject: [PATCH] octets vs bytes changes for GAS --- gas/ChangeLog | 32 +++++++++++++++++++ gas/as.h | 10 ++++++ gas/config/obj-coff.c | 15 ++++++--- gas/frags.c | 15 ++++++--- gas/frags.h | 7 ++-- gas/listing.c | 74 +++++++++++++++++++++++++++---------------- gas/read.c | 4 +-- gas/symbols.c | 6 ++-- 8 files changed, 120 insertions(+), 43 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 49709ab8278..58133a1b5f8 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,35 @@ +2000-02-03 Timothy Wall + + * as.h: Define OCTETS_PER_BYTE and OCTETS_PER_BYTE_POWER + default values. + * frags.c (frag_new): Calculate fr_fix in octets + (frag_now_fix) Return offset as target address offset (bytes). + (frag_now_fix_octets) New - Return offset in octets (8-bit + quantities). + * frags.h: Added prototype for frag_now_fix_octets(). + Distinguish between octets and bytes in field descriptions. + * listing.c (calc_hex): Account for octets vs bytes when + printing addresses/offsets. + (print_lines) Ditto. Also, if LISTING_WORD_SIZE is not 1, and + target is little-endian, print the octets in a word in big-endian + order so that the display looks like a proper hexadecimal number, + instead of having the octets reversed. + * read.c (do_align): When recording alignment, alignment power + should be in terms of target bytes (minimum addressible unit) + instead of octets. + (do_org) Convert ORG target address (byte) argument into an + octet offset when generating a variable fragment. + * symbols.c (resolve_symbol_value): Symbol final value + converted to a target address offset (bytes) from its octet offset. + * config/obj-coff.c (coff_frob_symbol): Symbol target address + offset (bytes) is adjusted by the frag offset (octets) converted + to bytes. + (coff_frob_section) Section alignment power is in terms of bytes; + convert it to an octet alignment power when calculating size (and + size mask) in octets. Don't modify the section size in order to + "align" it for TI COFF, since that format has a different method + for storing alignment information. + 2000-02-01 Timothy Wall * stabs.c (generate_asm_file): Escape backslashes in stabs file diff --git a/gas/as.h b/gas/as.h index 62ef3761112..3f16d5649ef 100644 --- a/gas/as.h +++ b/gas/as.h @@ -643,6 +643,16 @@ void eh_frame_convert_frag PARAMS ((fragS *)); #define BSS_SECTION_NAME ".bss" #endif +#ifndef OCTETS_PER_BYTE_POWER +#define OCTETS_PER_BYTE_POWER 0 +#endif +#ifndef OCTETS_PER_BYTE +#define OCTETS_PER_BYTE (1< 0; i--) { if (lptr->frag) - lptr->l.u.offset += lptr->frag->fr_address; + lptr->l.u.offset += lptr->frag->fr_address / OCTETS_PER_BYTE; l[i] = lptr->l; lptr = lptr->next; } @@ -1453,25 +1453,32 @@ coff_frob_section (sec) char *p; fragS *fragp; bfd_vma size, n_entries, mask; + bfd_vma align_power = (bfd_vma)sec->alignment_power + OCTETS_PER_BYTE_POWER; /* The COFF back end in BFD requires that all section sizes be - rounded up to multiples of the corresponding section alignments. - Seems kinda silly to me, but that's the way it is. */ + rounded up to multiples of the corresponding section alignments, + supposedly because standard COFF has no other way of encoding alignment + for sections. If your COFF flavor has a different way of encoding + section alignment, then skip this step, as TICOFF does. */ size = bfd_get_section_size_before_reloc (sec); - mask = ((bfd_vma) 1 << (bfd_vma) sec->alignment_power) - 1; + mask = ((bfd_vma) 1 << align_power) - 1; +#if !defined(TICOFF) if (size & mask) { size = (size + mask) & ~mask; bfd_set_section_size (stdoutput, sec, size); } +#endif /* If the section size is non-zero, the section symbol needs an aux entry associated with it, indicating the size. We don't know all the values yet; coff_frob_symbol will fill them in later. */ +#ifndef TICOFF if (size != 0 || sec == text_section || sec == data_section || sec == bss_section) +#endif { symbolS *secsym = section_symbol (sec); diff --git a/gas/frags.c b/gas/frags.c index 240b2ee63a0..882cb12284f 100644 --- a/gas/frags.c +++ b/gas/frags.c @@ -114,7 +114,7 @@ frag_new (old_frags_var_max_size) assert (frchain_now->frch_last == frag_now); /* Fix up old frag's fr_fix. */ - frag_now->fr_fix = frag_now_fix () - old_frags_var_max_size; + frag_now->fr_fix = frag_now_fix_octets () - old_frags_var_max_size; /* Make sure its type is valid. */ assert (frag_now->fr_type != 0); @@ -336,12 +336,19 @@ frag_align_pattern (alignment, fill_pattern, n_fill, max) } addressT -frag_now_fix () +frag_now_fix_octets () { if (now_seg == absolute_section) return abs_section_offset; - return (addressT) ((char*) obstack_next_free (&frchain_now->frch_obstack) - - frag_now->fr_literal); + + return ((char*) obstack_next_free (&frchain_now->frch_obstack) + - frag_now->fr_literal); +} + +addressT +frag_now_fix () +{ + return frag_now_fix_octets() / OCTETS_PER_BYTE; } void diff --git a/gas/frags.h b/gas/frags.h index b188e33cf43..b4c6e383dc0 100644 --- a/gas/frags.h +++ b/gas/frags.h @@ -44,14 +44,14 @@ struct obstack; struct frag { - /* Object file address. */ + /* Object file address (as an octet offset). */ addressT fr_address; /* Chain forward; ascending address order. Rooted in frch_root. */ struct frag *fr_next; - /* (Fixed) number of chars we know we have. May be 0. */ + /* (Fixed) number of octets we know we have. May be 0. */ offsetT fr_fix; - /* (Variable) number of chars after above. May be 0. */ + /* (Variable) number of octets after above. May be 0. */ offsetT fr_var; /* For variable-length tail. */ symbolS *fr_symbol; @@ -101,6 +101,7 @@ struct frag instead, use frag_now_fix (). */ COMMON fragS *frag_now; extern addressT frag_now_fix PARAMS ((void)); +extern addressT frag_now_fix_octets PARAMS ((void)); /* For foreign-segment symbol fixups. */ COMMON fragS zero_address_frag; diff --git a/gas/listing.c b/gas/listing.c index 1ab0ddef180..441cac2b3ea 100644 --- a/gas/listing.c +++ b/gas/listing.c @@ -596,7 +596,7 @@ calc_hex (list) unsigned int address = ~ (unsigned int) 0; fragS *frag; fragS *frag_ptr; - unsigned int byte_in_frag; + unsigned int octet_in_frag; /* Find first frag which says it belongs to this line */ frag = list->frag; @@ -611,33 +611,33 @@ calc_hex (list) while (frag_ptr != (fragS *) NULL && frag_ptr->line == first) { /* Print as many bytes from the fixed part as is sensible */ - byte_in_frag = 0; - while ((offsetT) byte_in_frag < frag_ptr->fr_fix + octet_in_frag = 0; + while ((offsetT) octet_in_frag < frag_ptr->fr_fix && data_buffer_size < MAX_BYTES - 3) { if (address == ~ (unsigned int) 0) { - address = frag_ptr->fr_address; + address = frag_ptr->fr_address / OCTETS_PER_BYTE; } sprintf (data_buffer + data_buffer_size, "%02X", - (frag_ptr->fr_literal[byte_in_frag]) & 0xff); + (frag_ptr->fr_literal[octet_in_frag]) & 0xff); data_buffer_size += 2; - byte_in_frag++; + octet_in_frag++; } { - unsigned int var_rep_max = byte_in_frag; - unsigned int var_rep_idx = byte_in_frag; + unsigned int var_rep_max = octet_in_frag; + unsigned int var_rep_idx = octet_in_frag; /* Print as many bytes from the variable part as is sensible */ - while (((offsetT) byte_in_frag - < frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset) + while (((offsetT) octet_in_frag + < (frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset)) && data_buffer_size < MAX_BYTES - 3) { if (address == ~ (unsigned int) 0) { - address = frag_ptr->fr_address; + address = frag_ptr->fr_address / OCTETS_PER_BYTE; } sprintf (data_buffer + data_buffer_size, "%02X", @@ -649,7 +649,7 @@ calc_hex (list) data_buffer_size += 2; var_rep_idx++; - byte_in_frag++; + octet_in_frag++; if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var) var_rep_idx = var_rep_max; @@ -677,8 +677,10 @@ print_lines (list, lineno, string, address) unsigned int idx; unsigned int nchars; unsigned int lines; - unsigned int byte_in_word = 0; + unsigned int octet_in_word = 0; char *src = data_buffer; + int end = strlen(src); + int cur; /* Print the stuff on the first line */ listing_page (list); @@ -707,18 +709,27 @@ print_lines (list, lineno, string, address) /* And the data to go along with it */ idx = 0; - - while (*src && idx < nchars) + cur = 0; + while (src[cur] && idx < nchars) { - fprintf (list_file, "%c%c", src[0], src[1]); - src += 2; - byte_in_word++; + int offset; +#if TARGET_BYTES_BIG_ENDIAN != 0 + offset = cur; + fprintf (list_file, "%c%c", src[offset], src[offset+1]); +#else + offset = (cur & ~(LISTING_WORD_SIZE * 2 - 1)) + + (LISTING_WORD_SIZE - octet_in_word - 1) * 2; + if (offset < end) + fprintf (list_file, "%c%c", src[offset], src[offset+1]); +#endif + cur += 2; + octet_in_word++; - if (byte_in_word == LISTING_WORD_SIZE) + if (octet_in_word == LISTING_WORD_SIZE) { fprintf (list_file, " "); idx++; - byte_in_word = 0; + octet_in_word = 0; } idx += 2; @@ -740,7 +751,7 @@ print_lines (list, lineno, string, address) for (lines = 0; lines < (unsigned int) listing_lhs_cont_lines - && *src; + && src[cur]; lines ++) { nchars = ((LISTING_WORD_SIZE * 2) + 1) @@ -750,18 +761,27 @@ print_lines (list, lineno, string, address) /* Print any more lines of data, but more compactly */ fprintf (list_file, "% 4d ", lineno); - while (*src && idx < nchars) + while (src[cur] && idx < nchars) { - fprintf (list_file, "%c%c", src[0], src[1]); - src += 2; + int offset; +#if TARGET_BYTES_BIG_ENDIAN != 0 + offset = cur; + fprintf (list_file, "%c%c", src[offset], src[offset+1]); +#else + offset = (cur & ~(LISTING_WORD_SIZE * 2 - 1)) + + (LISTING_WORD_SIZE - octet_in_word - 1) * 2; + if (offset < end) + fprintf (list_file, "%c%c", src[offset], src[offset+1]); +#endif + cur += 2; idx += 2; - byte_in_word++; + octet_in_word++; - if (byte_in_word == LISTING_WORD_SIZE) + if (octet_in_word == LISTING_WORD_SIZE) { fprintf (list_file, " "); idx++; - byte_in_word = 0; + octet_in_word = 0; } } diff --git a/gas/read.c b/gas/read.c index d25c45935cc..821c074837b 100644 --- a/gas/read.c +++ b/gas/read.c @@ -1194,7 +1194,7 @@ do_align (n, fill, len, max) just_record_alignment: #endif - record_alignment (now_seg, n); + record_alignment (now_seg, n - OCTETS_PER_BYTE_POWER); } /* Handle the .align pseudo-op. A positive ARG is a default alignment @@ -2369,7 +2369,7 @@ do_org (segment, exp, fill) char *p; p = frag_var (rs_org, 1, 1, (relax_substateT) 0, exp->X_add_symbol, - exp->X_add_number, (char *) NULL); + exp->X_add_number * OCTETS_PER_BYTE, (char *) NULL); *p = fill; } } diff --git a/gas/symbols.c b/gas/symbols.c index 1e0f190b308..b54a2fd9377 100644 --- a/gas/symbols.c +++ b/gas/symbols.c @@ -862,10 +862,10 @@ resolve_symbol_value (symp, finalize) struct local_symbol *locsym = (struct local_symbol *) symp; if (local_symbol_resolved_p (locsym)) - return locsym->lsy_offset; + return locsym->lsy_offset / OCTETS_PER_BYTE; final_val = (local_symbol_get_frag (locsym)->fr_address - + locsym->lsy_offset); + + locsym->lsy_offset) / OCTETS_PER_BYTE; if (finalize) { @@ -921,7 +921,7 @@ resolve_symbol_value (symp, finalize) /* Fall through. */ case O_constant: - final_val += symp->sy_frag->fr_address; + final_val += symp->sy_frag->fr_address / OCTETS_PER_BYTE; if (final_seg == expr_section) final_seg = absolute_section; resolved = 1; -- 2.30.2