addressT frag_now_fix_octets (void) { #ifdef NeXT_MOD return ((char *) obstack_next_free (&frags) - frag_now->fr_literal); #else if (now_seg == absolute_section) return abs_section_offset; return ((char *) obstack_next_free (&frchain_now->frch_obstack) - frag_now->fr_literal); #endif }
static void pascal_object_print_static_field (struct value *val, struct ui_file *stream, int recurse, const struct value_print_options *options) { struct type *type = value_type (val); struct value_print_options opts; if (value_entirely_optimized_out (val)) { val_print_optimized_out (val, stream); return; } if (TYPE_CODE (type) == TYPE_CODE_STRUCT) { CORE_ADDR *first_dont_print, addr; int i; first_dont_print = (CORE_ADDR *) obstack_base (&dont_print_statmem_obstack); i = (CORE_ADDR *) obstack_next_free (&dont_print_statmem_obstack) - first_dont_print; while (--i >= 0) { if (value_address (val) == first_dont_print[i]) { fputs_filtered ("\ <same as static member of an already seen type>", stream); return; } }
static _IO_size_t _IO_obstack_xsputn (_IO_FILE *fp, const void *data, _IO_size_t n) { struct obstack *obstack = ((struct _IO_obstack_file *) fp)->obstack; if (fp->_IO_write_ptr + n > fp->_IO_write_end) { int size; /* We need some more memory. First shrink the buffer to the space we really currently need. */ obstack_blank_fast (obstack, fp->_IO_write_ptr - fp->_IO_write_end); /* Now grow for N bytes, and put the data there. */ obstack_grow (obstack, data, n); /* Setup the buffer pointers again. */ fp->_IO_write_base = obstack_base (obstack); fp->_IO_write_ptr = obstack_next_free (obstack); size = obstack_room (obstack); fp->_IO_write_end = fp->_IO_write_ptr + size; /* Now allocate the rest of the current chunk. */ obstack_blank_fast (obstack, size); } else fp->_IO_write_ptr = __mempcpy (fp->_IO_write_ptr, data, n); return n; }
char * frag_variant (relax_stateT type, int max_chars, int var, relax_substateT subtype, symbolS *symbol, offsetT offset, char *opcode) { register char *retval; retval = obstack_next_free (&frchain_now->frch_obstack); frag_now->fr_var = var; frag_now->fr_type = type; frag_now->fr_subtype = subtype; frag_now->fr_symbol = symbol; frag_now->fr_offset = offset; frag_now->fr_opcode = opcode; #ifdef USING_CGEN frag_now->fr_cgen.insn = 0; frag_now->fr_cgen.opindex = 0; frag_now->fr_cgen.opinfo = 0; #endif #ifdef TC_FRAG_INIT TC_FRAG_INIT (frag_now); #endif as_where (&frag_now->fr_file, &frag_now->fr_line); frag_new (max_chars); return (retval); }
static int gmp_obstack_reps (struct obstack *ob, int c, int reps) { obstack_blank (ob, reps); memset ((char *) obstack_next_free(ob) - reps, c, reps); return reps; }
addressT frag_now_fix_octets (void) { if (now_seg == absolute_section) return abs_section_offset; return ((char *) obstack_next_free (&frchain_now->frch_obstack) - frag_now->fr_literal); }
int _IO_obstack_vprintf (struct obstack *obstack, const char *format, va_list args) { struct obstack_FILE { struct _IO_obstack_file ofile; } new_f; int result; int size; int room; #ifdef _IO_MTSAFE_IO new_f.ofile.file.file._lock = NULL; #endif _IO_no_init (&new_f.ofile.file.file, _IO_USER_LOCK, -1, NULL, NULL); _IO_JUMPS (&new_f.ofile.file) = &_IO_obstack_jumps; room = obstack_room (obstack); size = obstack_object_size (obstack) + room; if (size == 0) { /* We have to handle the allocation a bit different since the `_IO_str_init_static' function would handle a size of zero different from what we expect. */ /* Get more memory. */ obstack_make_room (obstack, 64); /* Recompute how much room we have. */ room = obstack_room (obstack); size = room; assert (size != 0); } _IO_str_init_static_internal ((struct _IO_strfile_ *) &new_f.ofile, obstack_base (obstack), size, obstack_next_free (obstack)); /* Now allocate the rest of the current chunk. */ assert (size == (new_f.ofile.file.file._IO_write_end - new_f.ofile.file.file._IO_write_base)); assert (new_f.ofile.file.file._IO_write_ptr == (new_f.ofile.file.file._IO_write_base + obstack_object_size (obstack))); obstack_blank_fast (obstack, room); new_f.ofile.obstack = obstack; result = _IO_vfprintf (&new_f.ofile.file.file, format, args); /* Shrink the buffer to the space we really currently need. */ obstack_blank_fast (obstack, (new_f.ofile.file.file._IO_write_ptr - new_f.ofile.file.file._IO_write_end)); return result; }
/* * frag_new() * * Call this to close off a completed frag, and start up a new (empty) * frag, in the same subsegment as the old frag. * [frchain_now remains the same but frag_now is updated.] * Because this calculates the correct value of fr_fix by * looking at the obstack 'frags', it needs to know how many * characters at the end of the old frag belong to (the maximal) * fr_var: the rest must belong to fr_fix. * It doesn't actually set up the old frag's fr_var: you may have * set fr_var == 1, but allocated 10 chars to the end of the frag: * in this case you pass old_frags_var_max_size == 10. * * Make a new frag, initialising some components. Link new frag at end * of frchain_now. */ void frag_new( int old_frags_var_max_size) /* Number of chars (already allocated on obstack frags) in variable_length part of frag. */ { register fragS * former_last_fragP; /* char *throw_away_pointer; JF unused */ register frchainS * frchP; long tmp; /* JF */ if(frags.chunk_size == 0) { know(flagseen['n']); as_fatal("with -n a section directive must be seen before assembly " "can begin"); } frag_now->fr_fix = (char *) (obstack_next_free (&frags)) - (frag_now->fr_literal) - old_frags_var_max_size; /* Fix up old frag's fr_fix. */ obstack_finish (&frags); /* This will align the obstack so the */ /* next struct we allocate on it will */ /* begin at a correct boundary. */ frchP = frchain_now; know (frchP); former_last_fragP = frchP->frch_last; know (former_last_fragP); know (former_last_fragP == frag_now); obstack_blank (&frags, SIZEOF_STRUCT_FRAG); /* We expect this will begin at a correct */ /* boundary for a struct. */ tmp=obstack_alignment_mask(&frags); obstack_alignment_mask(&frags)=0; /* Turn off alignment */ /* If we ever hit a machine where strings must be aligned, we Lose Big */ frag_now=(fragS *)obstack_finish(&frags); obstack_alignment_mask(&frags)=tmp; /* Restore alignment */ /* Just in case we don't get zero'd bytes */ memset(frag_now, '\0', SIZEOF_STRUCT_FRAG); /* obstack_unaligned_done (&frags, &frag_now); */ /* know (frags.obstack_c_next_free == frag_now->fr_literal); */ /* Generally, frag_now->points to an */ /* address rounded up to next alignment. */ /* However, characters will add to obstack */ /* frags IMMEDIATELY after the struct frag, */ /* even if they are not starting at an */ /* alignment address. */ former_last_fragP->fr_next = frag_now; frchP->frch_last = frag_now; frag_now->fr_next = NULL; } /* frag_new() */
/* * frag_more() * * Start a new frag unless we have n more chars of room in the current frag. * Close off the old frag with a .fill 0. * * Return the address of the 1st char to write into. Advance * frag_now_growth past the new chars. */ char * frag_more( int nchars) { register char *retval; frag_grow (nchars); retval = obstack_next_free (&frags); obstack_blank_fast (&frags, nchars); return (retval); } /* frag_more() */
char * frag_more (int nchars) { register char *retval; frag_alloc_check (&frchain_now->frch_obstack); frag_grow (nchars); retval = obstack_next_free (&frchain_now->frch_obstack); obstack_blank_fast (&frchain_now->frch_obstack, nchars); return (retval); }
char * frag_variant (relax_stateT type, int max_chars, int var, relax_substateT subtype, symbolS *symbol, offsetT offset, char *opcode) { register char *retval; retval = obstack_next_free (&frchain_now->frch_obstack); frag_var_init (type, max_chars, var, subtype, symbol, offset, opcode); return retval; }
/* * add_last_frags_to_sections() does what layout_addresses() does below about * adding a last ".fill 0" frag to each section. This is called by * dwarf2_finish() allow get_frag_fix() in dwarf2dbg.c to work for the last * fragment in a section. */ void add_last_frags_to_sections( void) { struct frchain *frchainP; if(frchain_root == NULL) return; /* * If there is any current frag close it off. */ if(frag_now != NULL && frag_now->fr_fix == 0){ frag_now->fr_fix = obstack_next_free(&frags) - frag_now->fr_literal; frag_wane(frag_now); } /* * For every section, add a last ".fill 0" frag that will later be used * as the ending address of that section. */ for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ /* * We must do the obstack_finish(), so the next object we put on * obstack frags will not appear to start at the fr_literal of the * current frag. Also, it ensures that the next object will begin * on a address that is aligned correctly for the engine that runs * the assembler. */ (void)obstack_finish(&frags); /* * Make a fresh frag for the last frag. */ frag_now = (fragS *)obstack_alloc(&frags, SIZEOF_STRUCT_FRAG); memset(frag_now, '\0', SIZEOF_STRUCT_FRAG); frag_now->fr_next = NULL; (void)obstack_finish(&frags); /* * Append the new frag to current frchain. */ frchainP->frch_last->fr_next = frag_now; frchainP->frch_last = frag_now; frag_wane(frag_now); } }
static offsetT get_frag_fix (fragS *frag, segT seg) { frchainS *fr; if (frag->fr_next) return frag->fr_fix; /* If a fragment is the last in the chain, special measures must be taken to find its size before relaxation, since it may be pending on some subsegment chain. */ for (fr = seg_info (seg)->frchainP; fr; fr = fr->frch_next) if (fr->frch_last == frag) return (char *) obstack_next_free (&fr->frch_obstack) - frag->fr_literal; abort (); }
bool xheader_string_end (struct xheader *xhdr, char const *keyword) { uintmax_t len; uintmax_t p; uintmax_t n = 0; size_t size; char nbuf[UINTMAX_STRSIZE_BOUND]; char const *np; char *cp; if (xhdr->buffer) return false; xheader_init (xhdr); len = strlen (keyword) + xhdr->string_length + 3; /* ' ' + '=' + '\n' */ do { p = n; np = umaxtostr (len + p, nbuf); n = nbuf + sizeof nbuf - 1 - np; } while (n != p); p = strlen (keyword) + n + 2; size = p; if (size != p) { ERROR ((0, 0, _("Generated keyword/value pair is too long (keyword=%s, length=%s)"), keyword, nbuf)); obstack_free (xhdr->stk, obstack_finish (xhdr->stk)); return false; } x_obstack_blank (xhdr, p); x_obstack_1grow (xhdr, '\n'); cp = obstack_next_free (xhdr->stk) - xhdr->string_length - p - 1; memmove (cp + p, cp, xhdr->string_length); cp = stpcpy (cp, np); *cp++ = ' '; cp = stpcpy (cp, keyword); *cp++ = '='; return true; }
static void pascal_object_print_static_field (struct value *val, struct ui_file *stream, int recurse, const struct value_print_options *options) { struct type *type = value_type (val); struct value_print_options opts; if (TYPE_CODE (type) == TYPE_CODE_STRUCT) { CORE_ADDR *first_dont_print, addr; int i; first_dont_print = (CORE_ADDR *) obstack_base (&dont_print_statmem_obstack); i = (CORE_ADDR *) obstack_next_free (&dont_print_statmem_obstack) - first_dont_print; while (--i >= 0) { if (value_address (val) == first_dont_print[i]) { fputs_filtered ("<same as static member of an already seen type>", stream); return; } } addr = value_address (val); obstack_grow (&dont_print_statmem_obstack, (char *) &addr, sizeof (CORE_ADDR)); CHECK_TYPEDEF (type); pascal_object_print_value_fields (type, value_contents (val), addr, stream, recurse, NULL, options, NULL, 1); return; } opts = *options; opts.deref_ref = 0; common_val_print (val, stream, recurse, &opts, current_language); }
static int _IO_obstack_overflow (_IO_FILE *fp, int c) { struct obstack *obstack = ((struct _IO_obstack_file *) fp)->obstack; int size; /* Make room for another character. This might as well allocate a new chunk a memory and moves the old contents over. */ assert (c != EOF); obstack_1grow (obstack, c); /* Setup the buffer pointers again. */ fp->_IO_write_base = obstack_base (obstack); fp->_IO_write_ptr = obstack_next_free (obstack); size = obstack_room (obstack); fp->_IO_write_end = fp->_IO_write_ptr + size; /* Now allocate the rest of the current chunk. */ obstack_blank_fast (obstack, size); return c; }
int seg_not_empty_p (segT sec ATTRIBUTE_UNUSED) { segment_info_type *seginfo = seg_info (sec); frchainS *chain; fragS *frag; if (!seginfo) return 0; for (chain = seginfo->frchainP; chain; chain = chain->frch_next) { for (frag = chain->frch_root; frag; frag = frag->fr_next) if (frag->fr_fix) return 1; if (obstack_next_free (&chain->frch_obstack) != chain->frch_last->fr_literal) return 1; } return 0; }
/* Grow an obstack with formatted output. Return the number of bytes added to OBS. No trailing nul byte is added, and the object should be closed with obstack_finish before use. Upon memory allocation error, call obstack_alloc_failed_handler. Upon other error, return -1. */ int obstack_vprintf (struct obstack *obs, const char *format, va_list args) { /* If we are close to the end of the current obstack chunk, use a stack-allocated buffer and copy, to reduce the likelihood of a small-size malloc. Otherwise, print directly into the obstack. */ enum { CUTOFF = 1024 }; char buf[CUTOFF]; char *base = obstack_next_free (obs); size_t len = obstack_room (obs); char *str; if (len < CUTOFF) { base = buf; len = CUTOFF; } str = vasnprintf (base, &len, format, args); if (!str) { if (errno == ENOMEM) obstack_alloc_failed_handler (); return -1; } if (str == base && str != buf) /* The output was already computed in place, but we need to account for its size. */ obstack_blank_fast (obs, len); else { /* The output exceeded available obstack space or we used buf; copy the resulting string. */ obstack_grow (obs, str, len); if (str != buf) free (str); } return len; }
static void pascal_object_print_static_field (struct value *val, struct ui_file *stream, int format, int recurse, enum val_prettyprint pretty) { struct type *type = value_type (val); if (TYPE_CODE (type) == TYPE_CODE_STRUCT) { CORE_ADDR *first_dont_print; int i; first_dont_print = (CORE_ADDR *) obstack_base (&dont_print_statmem_obstack); i = (CORE_ADDR *) obstack_next_free (&dont_print_statmem_obstack) - first_dont_print; while (--i >= 0) { if (VALUE_ADDRESS (val) == first_dont_print[i]) { fputs_filtered ("<same as static member of an already seen type>", stream); return; } } obstack_grow (&dont_print_statmem_obstack, (char *) &VALUE_ADDRESS (val), sizeof (CORE_ADDR)); CHECK_TYPEDEF (type); pascal_object_print_value_fields (type, value_contents (val), VALUE_ADDRESS (val), stream, format, recurse, pretty, NULL, 1); return; } common_val_print (val, stream, format, 0, recurse, pretty); }
/* * frag_var() * * Start a new frag unless we have max_chars more chars of room in the current frag. * Close off the old frag with a .fill 0. * * Set up a machine_dependent relaxable frag, then start a new frag. * Return the address of the 1st char of the var part of the old frag * to write into. */ char * frag_var( relax_stateT type, int max_chars, int var, relax_substateT subtype, symbolS *symbol, long offset, char *opcode) { register char *retval; frag_grow (max_chars); retval = obstack_next_free (&frags); obstack_blank_fast (&frags, max_chars); frag_now->fr_var = var; frag_now->fr_type = type; frag_now->fr_subtype = subtype; frag_now->fr_symbol = symbol; frag_now->fr_offset = offset; frag_now->fr_opcode = opcode; frag_new (max_chars); return (retval); } /* frag_var() */
static void pascal_object_print_value (struct type *type, const gdb_byte *valaddr, CORE_ADDR address, struct ui_file *stream, int format, int recurse, enum val_prettyprint pretty, struct type **dont_print_vb) { struct type **last_dont_print = (struct type **) obstack_next_free (&dont_print_vb_obstack); struct obstack tmp_obstack = dont_print_vb_obstack; int i, n_baseclasses = TYPE_N_BASECLASSES (type); if (dont_print_vb == 0) { /* If we're at top level, carve out a completely fresh chunk of the obstack and use that until this particular invocation returns. */ /* Bump up the high-water mark. Now alpha is omega. */ obstack_finish (&dont_print_vb_obstack); } for (i = 0; i < n_baseclasses; i++) { int boffset; struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i)); char *basename = type_name_no_tag (baseclass); const gdb_byte *base_valaddr; if (BASETYPE_VIA_VIRTUAL (type, i)) { struct type **first_dont_print = (struct type **) obstack_base (&dont_print_vb_obstack); int j = (struct type **) obstack_next_free (&dont_print_vb_obstack) - first_dont_print; while (--j >= 0) if (baseclass == first_dont_print[j]) goto flush_it; obstack_ptr_grow (&dont_print_vb_obstack, baseclass); } boffset = baseclass_offset (type, i, valaddr, address); if (pretty) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 * recurse, stream); } fputs_filtered ("<", stream); /* Not sure what the best notation is in the case where there is no baseclass name. */ fputs_filtered (basename ? basename : "", stream); fputs_filtered ("> = ", stream); /* The virtual base class pointer might have been clobbered by the user program. Make sure that it still points to a valid memory location. */ if (boffset != -1 && (boffset < 0 || boffset >= TYPE_LENGTH (type))) { /* FIXME (alloc): not safe is baseclass is really really big. */ gdb_byte *buf = alloca (TYPE_LENGTH (baseclass)); base_valaddr = buf; if (target_read_memory (address + boffset, buf, TYPE_LENGTH (baseclass)) != 0) boffset = -1; } else base_valaddr = valaddr + boffset; if (boffset == -1) fprintf_filtered (stream, "<invalid address>"); else pascal_object_print_value_fields (baseclass, base_valaddr, address + boffset, stream, format, recurse, pretty, (struct type **) obstack_base (&dont_print_vb_obstack), 0); fputs_filtered (", ", stream); flush_it: ; } if (dont_print_vb == 0) { /* Free the space used to deal with the printing of this type from top level. */ obstack_free (&dont_print_vb_obstack, last_dont_print); /* Reset watermark so that we can continue protecting ourselves from whatever we were protecting ourselves. */ dont_print_vb_obstack = tmp_obstack; } }
void colon( /* just seen "x:" - rattle symbols & frags */ char *sym_name) /* symbol name, as a cannonical string */ /* We copy this string: OK to alter later. */ { register struct symbol * symbolP; /* symbol we are working with */ if (frchain_now == NULL) { know(flagseen['n']); as_fatal("with -n a section directive must be seen before assembly " "can begin"); } if ((symbolP = symbol_table_lookup( sym_name ))) { /* * Now check for undefined symbols */ if ((symbolP -> sy_type & N_TYPE) == N_UNDF) { temp = symbolP->sy_desc; if( symbolP -> sy_other == 0 /* bug #50416 -O causes this not to work for: && ((symbolP->sy_desc) & (~REFERENCE_TYPE)) == 0 */ && (temp & (~(REFERENCE_TYPE | N_WEAK_REF | N_WEAK_DEF | N_ARM_THUMB_DEF | N_NO_DEAD_STRIP | REFERENCED_DYNAMICALLY))) == 0 && symbolP -> sy_value == 0) { symbolP -> sy_frag = frag_now; symbolP -> sy_value = obstack_next_free(& frags) - frag_now -> fr_literal; know( N_UNDF == 0 ); symbolP -> sy_type |= N_SECT; /* keep N_EXT bit */ symbolP -> sy_other = frchain_now->frch_nsect; symbolP -> sy_desc &= ~REFERENCE_TYPE; symbolP -> sy_desc &= ~N_WEAK_REF; symbol_assign_index(symbolP); if((symbolP->sy_desc & N_WEAK_DEF) == N_WEAK_DEF && (frchain_now->frch_section.flags & S_COALESCED) != S_COALESCED) as_fatal("symbol: %s can't be a weak_definition (currently " "only supported in section of type coalesced)", sym_name); #ifdef NeXT_MOD /* generate stabs for debugging assembly code */ if(flagseen['g']) make_stab_for_symbol(symbolP); #endif } else { as_fatal( "Symbol \"%s\" is already defined as \"%s\"/%d.%d." TA_DFMT ".", sym_name, seg_name [(int) N_TYPE_seg [symbolP -> sy_type & N_TYPE]], symbolP -> sy_other, symbolP -> sy_desc, TA_DFT_CAST(symbolP -> sy_value)); } } else { as_fatal("Symbol %s already defined.",sym_name); } } else { symbolP = symbol_new (sym_name, N_SECT, frchain_now->frch_nsect, 0, (valueT)(obstack_next_free(&frags)-frag_now->fr_literal), frag_now); symbol_table_insert (symbolP); symbol_assign_index (symbolP); #ifdef NeXT_MOD /* generate stabs for debugging assembly code */ if(flagseen['g']) make_stab_for_symbol(symbolP); #endif } #ifdef tc_frob_label tc_frob_label(symbolP); #endif }
void pascal_object_print_value_fields (struct type *type, const gdb_byte *valaddr, CORE_ADDR address, struct ui_file *stream, int format, int recurse, enum val_prettyprint pretty, struct type **dont_print_vb, int dont_print_statmem) { int i, len, n_baseclasses; char *last_dont_print = obstack_next_free (&dont_print_statmem_obstack); CHECK_TYPEDEF (type); fprintf_filtered (stream, "{"); len = TYPE_NFIELDS (type); n_baseclasses = TYPE_N_BASECLASSES (type); /* Print out baseclasses such that we don't print duplicates of virtual baseclasses. */ if (n_baseclasses > 0) pascal_object_print_value (type, valaddr, address, stream, format, recurse + 1, pretty, dont_print_vb); if (!len && n_baseclasses == 1) fprintf_filtered (stream, "<No data fields>"); else { struct obstack tmp_obstack = dont_print_statmem_obstack; int fields_seen = 0; if (dont_print_statmem == 0) { /* If we're at top level, carve out a completely fresh chunk of the obstack and use that until this particular invocation returns. */ obstack_finish (&dont_print_statmem_obstack); } for (i = n_baseclasses; i < len; i++) { /* If requested, skip printing of static fields. */ if (!pascal_static_field_print && TYPE_FIELD_STATIC (type, i)) continue; if (fields_seen) fprintf_filtered (stream, ", "); else if (n_baseclasses > 0) { if (pretty) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 + 2 * recurse, stream); fputs_filtered ("members of ", stream); fputs_filtered (type_name_no_tag (type), stream); fputs_filtered (": ", stream); } } fields_seen = 1; if (pretty) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 + 2 * recurse, stream); } else { wrap_here (n_spaces (2 + 2 * recurse)); } if (inspect_it) { if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR) fputs_filtered ("\"( ptr \"", stream); else fputs_filtered ("\"( nodef \"", stream); if (TYPE_FIELD_STATIC (type, i)) fputs_filtered ("static ", stream); fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), language_cplus, DMGL_PARAMS | DMGL_ANSI); fputs_filtered ("\" \"", stream); fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), language_cplus, DMGL_PARAMS | DMGL_ANSI); fputs_filtered ("\") \"", stream); } else { annotate_field_begin (TYPE_FIELD_TYPE (type, i)); if (TYPE_FIELD_STATIC (type, i)) fputs_filtered ("static ", stream); fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), language_cplus, DMGL_PARAMS | DMGL_ANSI); annotate_field_name_end (); fputs_filtered (" = ", stream); annotate_field_value (); } if (!TYPE_FIELD_STATIC (type, i) && TYPE_FIELD_PACKED (type, i)) { struct value *v; /* Bitfields require special handling, especially due to byte order problems. */ if (TYPE_FIELD_IGNORE (type, i)) { fputs_filtered ("<optimized out or zero length>", stream); } else { v = value_from_longest (TYPE_FIELD_TYPE (type, i), unpack_field_as_long (type, valaddr, i)); common_val_print (v, stream, format, 0, recurse + 1, pretty); } } else { if (TYPE_FIELD_IGNORE (type, i)) { fputs_filtered ("<optimized out or zero length>", stream); } else if (TYPE_FIELD_STATIC (type, i)) { /* struct value *v = value_static_field (type, i); v4.17 specific */ struct value *v; v = value_from_longest (TYPE_FIELD_TYPE (type, i), unpack_field_as_long (type, valaddr, i)); if (v == NULL) fputs_filtered ("<optimized out>", stream); else pascal_object_print_static_field (v, stream, format, recurse + 1, pretty); } else { /* val_print (TYPE_FIELD_TYPE (type, i), valaddr + TYPE_FIELD_BITPOS (type, i) / 8, address + TYPE_FIELD_BITPOS (type, i) / 8, 0, stream, format, 0, recurse + 1, pretty); */ val_print (TYPE_FIELD_TYPE (type, i), valaddr, TYPE_FIELD_BITPOS (type, i) / 8, address + TYPE_FIELD_BITPOS (type, i) / 8, stream, format, 0, recurse + 1, pretty); } } annotate_field_end (); } if (dont_print_statmem == 0) { /* Free the space used to deal with the printing of the members from top level. */ obstack_free (&dont_print_statmem_obstack, last_dont_print); dont_print_statmem_obstack = tmp_obstack; } if (pretty) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 * recurse, stream); } } fprintf_filtered (stream, "}"); }
void pascal_object_print_value_fields (struct type *type, const gdb_byte *valaddr, int offset, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value *val, const struct value_print_options *options, struct type **dont_print_vb, int dont_print_statmem) { int i, len, n_baseclasses; char *last_dont_print = (char *) obstack_next_free (&dont_print_statmem_obstack); type = check_typedef (type); fprintf_filtered (stream, "{"); len = TYPE_NFIELDS (type); n_baseclasses = TYPE_N_BASECLASSES (type); /* Print out baseclasses such that we don't print duplicates of virtual baseclasses. */ if (n_baseclasses > 0) pascal_object_print_value (type, valaddr, offset, address, stream, recurse + 1, val, options, dont_print_vb); if (!len && n_baseclasses == 1) fprintf_filtered (stream, "<No data fields>"); else { struct obstack tmp_obstack = dont_print_statmem_obstack; int fields_seen = 0; if (dont_print_statmem == 0) { /* If we're at top level, carve out a completely fresh chunk of the obstack and use that until this particular invocation returns. */ obstack_finish (&dont_print_statmem_obstack); } for (i = n_baseclasses; i < len; i++) { /* If requested, skip printing of static fields. */ if (!options->pascal_static_field_print && field_is_static (&TYPE_FIELD (type, i))) continue; if (fields_seen) fprintf_filtered (stream, ", "); else if (n_baseclasses > 0) { if (options->prettyformat) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 + 2 * recurse, stream); fputs_filtered ("members of ", stream); fputs_filtered (type_name_no_tag (type), stream); fputs_filtered (": ", stream); } } fields_seen = 1; if (options->prettyformat) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 + 2 * recurse, stream); } else { wrap_here (n_spaces (2 + 2 * recurse)); } annotate_field_begin (TYPE_FIELD_TYPE (type, i)); if (field_is_static (&TYPE_FIELD (type, i))) fputs_filtered ("static ", stream); fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), language_cplus, DMGL_PARAMS | DMGL_ANSI); annotate_field_name_end (); fputs_filtered (" = ", stream); annotate_field_value (); if (!field_is_static (&TYPE_FIELD (type, i)) && TYPE_FIELD_PACKED (type, i)) { struct value *v; /* Bitfields require special handling, especially due to byte order problems. */ if (TYPE_FIELD_IGNORE (type, i)) { fputs_filtered ("<optimized out or zero length>", stream); } else if (value_bits_synthetic_pointer (val, TYPE_FIELD_BITPOS (type, i), TYPE_FIELD_BITSIZE (type, i))) { fputs_filtered (_("<synthetic pointer>"), stream); } else { struct value_print_options opts = *options; v = value_field_bitfield (type, i, valaddr, offset, val); opts.deref_ref = 0; common_val_print (v, stream, recurse + 1, &opts, current_language); } } else { if (TYPE_FIELD_IGNORE (type, i)) { fputs_filtered ("<optimized out or zero length>", stream); } else if (field_is_static (&TYPE_FIELD (type, i))) { /* struct value *v = value_static_field (type, i); v4.17 specific. */ struct value *v; v = value_field_bitfield (type, i, valaddr, offset, val); if (v == NULL) val_print_optimized_out (NULL, stream); else pascal_object_print_static_field (v, stream, recurse + 1, options); } else { struct value_print_options opts = *options; opts.deref_ref = 0; /* val_print (TYPE_FIELD_TYPE (type, i), valaddr + TYPE_FIELD_BITPOS (type, i) / 8, address + TYPE_FIELD_BITPOS (type, i) / 8, 0, stream, format, 0, recurse + 1, pretty); */ val_print (TYPE_FIELD_TYPE (type, i), valaddr, offset + TYPE_FIELD_BITPOS (type, i) / 8, address, stream, recurse + 1, val, &opts, current_language); } } annotate_field_end (); } if (dont_print_statmem == 0) { /* Free the space used to deal with the printing of the members from top level. */ obstack_free (&dont_print_statmem_obstack, last_dont_print); dont_print_statmem_obstack = tmp_obstack; } if (options->prettyformat) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 * recurse, stream); } } fprintf_filtered (stream, "}"); }
static void pascal_object_print_value (struct type *type, const gdb_byte *valaddr, int offset, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value *val, const struct value_print_options *options, struct type **dont_print_vb) { struct type **last_dont_print = (struct type **) obstack_next_free (&dont_print_vb_obstack); struct obstack tmp_obstack = dont_print_vb_obstack; int i, n_baseclasses = TYPE_N_BASECLASSES (type); if (dont_print_vb == 0) { /* If we're at top level, carve out a completely fresh chunk of the obstack and use that until this particular invocation returns. */ /* Bump up the high-water mark. Now alpha is omega. */ obstack_finish (&dont_print_vb_obstack); } for (i = 0; i < n_baseclasses; i++) { int boffset = 0; struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i)); const char *basename = type_name_no_tag (baseclass); const gdb_byte *base_valaddr = NULL; int thisoffset; int skip = 0; if (BASETYPE_VIA_VIRTUAL (type, i)) { struct type **first_dont_print = (struct type **) obstack_base (&dont_print_vb_obstack); int j = (struct type **) obstack_next_free (&dont_print_vb_obstack) - first_dont_print; while (--j >= 0) if (baseclass == first_dont_print[j]) goto flush_it; obstack_ptr_grow (&dont_print_vb_obstack, baseclass); } thisoffset = offset; TRY { boffset = baseclass_offset (type, i, valaddr, offset, address, val); } CATCH (ex, RETURN_MASK_ERROR) { if (ex.error == NOT_AVAILABLE_ERROR) skip = -1; else skip = 1; } END_CATCH if (skip == 0) { /* The virtual base class pointer might have been clobbered by the user program. Make sure that it still points to a valid memory location. */ if (boffset < 0 || boffset >= TYPE_LENGTH (type)) { gdb_byte *buf; struct cleanup *back_to; buf = (gdb_byte *) xmalloc (TYPE_LENGTH (baseclass)); back_to = make_cleanup (xfree, buf); base_valaddr = buf; if (target_read_memory (address + boffset, buf, TYPE_LENGTH (baseclass)) != 0) skip = 1; address = address + boffset; thisoffset = 0; boffset = 0; do_cleanups (back_to); } else base_valaddr = valaddr; } if (options->prettyformat) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 * recurse, stream); } fputs_filtered ("<", stream); /* Not sure what the best notation is in the case where there is no baseclass name. */ fputs_filtered (basename ? basename : "", stream); fputs_filtered ("> = ", stream); if (skip < 0) val_print_unavailable (stream); else if (skip > 0) val_print_invalid_address (stream); else pascal_object_print_value_fields (baseclass, base_valaddr, thisoffset + boffset, address, stream, recurse, val, options, (struct type **) obstack_base (&dont_print_vb_obstack), 0); fputs_filtered (", ", stream); flush_it: ; } if (dont_print_vb == 0) { /* Free the space used to deal with the printing of this type from top level. */ obstack_free (&dont_print_vb_obstack, last_dont_print); /* Reset watermark so that we can continue protecting ourselves from whatever we were protecting ourselves. */ dont_print_vb_obstack = tmp_obstack; } }
/* * section_new() (for non-zerofill sections) switches to a new section, creating * it if needed, and creates a fresh fragment. If it is the current section * nothing happens except checks to make sure the type, attributes and * sizeof_stub are the same. The segment and section names will be trimed to * fit in the section structure and is the responsiblity of the caller to * report errors if they don't. For zerofill sections only the struct frchain * for the section is returned after possibly being created (these section are * never made the current section and no frags are ever touched). * * Globals on input: * frchain_now points to the (possibly none) struct frchain for the current * section. * frag_now points at an incomplete frag for current section. * If frag_now == NULL, then there is no old, incomplete frag, so the old * frag is not closed off. * * Globals on output: * frchain_now points to the (possibly new) struct frchain for this section. * frchain_root updated if needed (for the first section created). * frag_now is set to the last (possibly new) frag in the section. * now_seg is set to the Mach-O section number (frch_nsect field) except * it is not set for section types of S_ZEROFILL. */ frchainS * section_new( char *segname, char *sectname, uint32_t type, uint32_t attributes, uint32_t sizeof_stub) { frchainS *frcP; frchainS **lastPP; uint32_t last_nsect; if(frags.chunk_size == 0) /* * This line is use instead of: * obstack_begin(&frags, 5000); * which the only difference is that frags are allocated on 4 byte * boundaries instead of the default. The problem with the default * is that on some RISC machines the obstack uses 8 (the alignment * of a double after a char in a struct) and then the common use of: * frag_now->fr_fix = obstack_next_free(&frags) - * frag_now->fr_literal; * can get an extra 4 bytes that are not in the frag because of the * 8 byte alignment where only 4 byte alignment for frags are * needed. */ _obstack_begin(&frags, 5000, 4, obstack_chunk_alloc, obstack_chunk_free); /* * Determine if this section has been seen. */ last_nsect = 0; for(frcP = *(lastPP = &frchain_root); frcP != NULL; frcP = *(lastPP = &frcP->frch_next)){ if(strncmp(frcP->frch_section.segname, segname, sizeof(frcP->frch_section.segname)) == 0 && strncmp(frcP->frch_section.sectname, sectname, sizeof(frcP->frch_section.sectname)) == 0) break; last_nsect = frcP->frch_nsect; } /* * If this section has been seen make sure it's type and attributes * for this call are the same as when the section was created. */ if(frcP != NULL){ if((frcP->frch_section.flags & SECTION_TYPE) != type){ as_warn("section type does not match previous section type"); } if(type == S_SYMBOL_STUBS && frcP->frch_section.reserved2 != sizeof_stub){ as_warn("section stub size does not match previous section " "stub size"); } frcP->frch_section.flags |= attributes; } /* * If the current section is the same as for this call there is nothing * more to do. */ if(frcP != NULL && (frchain_now == frcP || type == S_ZEROFILL)){ if(type != S_ZEROFILL) now_seg = frcP->frch_nsect; return(frcP); } /* * For non-zerofill sections it will be made the current section so deal * with the current frag. */ if(type != S_ZEROFILL){ /* * If there is any current frag in the old section close it off. */ if(frag_now != NULL){ frag_now->fr_fix = obstack_next_free(&frags) - frag_now->fr_literal; frag_wane(frag_now); } /* * We must do the obstack_finish(), so the next object we put on * obstack frags will not appear to start at the fr_literal of the * current frag. Also, it ensures that the next object will begin * on a address that is aligned correctly for the engine that runs * the assembler. */ obstack_finish(&frags); } /* * If this section exists since it is not the current section switch to * it by making it the current chain and create a new frag in it. */ if(frcP != NULL){ if(type != S_ZEROFILL) now_seg = frcP->frch_nsect; /* * For a zerofill section no frags are created here and since it * exist just return a pointer to the section. */ if((frcP->frch_section.flags & SECTION_TYPE) == S_ZEROFILL){ return(frcP); } else{ /* * Make this section the current section. */ frchain_now = frcP; if(type != S_ZEROFILL) now_seg = frchain_now->frch_nsect; /* * Make a fresh frag for the section. */ frag_now = (fragS *)obstack_alloc(&frags, SIZEOF_STRUCT_FRAG); memset(frag_now, '\0', SIZEOF_STRUCT_FRAG); frag_now->fr_next = NULL; /* * Append the new frag to the existing frchain. */ frchain_now->frch_last->fr_next = frag_now; frchain_now->frch_last = frag_now; } } else{ /* * This section does not exist so create a new frchainS struct fill * it in, link it to the chain */ frcP = (frchainS *)xmalloc(sizeof(frchainS)); memset(frcP, '\0', sizeof(frchainS)); strncpy(frcP->frch_section.segname, segname, sizeof(frcP->frch_section.segname)); strncpy(frcP->frch_section.sectname, sectname, sizeof(frcP->frch_section.sectname)); frcP->frch_section.flags = attributes | type; frcP->frch_section.reserved2 = sizeof_stub; frcP->frch_nsect = last_nsect + 1; if(type != S_ZEROFILL) now_seg = frcP->frch_nsect; *lastPP = frcP; /* * For zerofill sections no frag is created here so just return. * For non-zerofill section create the sections new frag and * make the section the current chain. */ if(type == S_ZEROFILL){ return(frcP); } else{ /* * Make a fresh frag for the new section. */ frag_now = (fragS *)obstack_alloc(&frags, SIZEOF_STRUCT_FRAG); memset(frag_now, '\0', SIZEOF_STRUCT_FRAG); frag_now->fr_next = NULL; /* * Append the new frag to new frchain. */ frcP->frch_root = frag_now; frcP->frch_last = frag_now; /* * Make this section the current section. */ frchain_now = frcP; } } return(frchain_now); }
/* * layout_addresses() is called after all the assembly code has been read and * fragments, symbols and fixups have been created. This routine sets the * address of the fragments and symbols. Then it does the fixups of the frags * and prepares the fixes so relocation entries can be created from them. */ void layout_addresses( void) { struct frchain *frchainP; fragS *fragP; relax_addressT slide, tmp; symbolS *symbolP; uint32_t nbytes, fill_size, repeat_expression, partial_bytes, layout_pass; relax_stateT old_fr_type; int changed; if(frchain_root == NULL) return; /* * If there is any current frag close it off. */ if(frag_now != NULL && frag_now->fr_fix == 0){ frag_now->fr_fix = obstack_next_free(&frags) - frag_now->fr_literal; frag_wane(frag_now); } /* * For every section, add a last ".fill 0" frag that will later be used * as the ending address of that section. */ for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ /* * We must do the obstack_finish(), so the next object we put on * obstack frags will not appear to start at the fr_literal of the * current frag. Also, it ensures that the next object will begin * on a address that is aligned correctly for the engine that runs * the assembler. */ (void)obstack_finish(&frags); /* * Make a fresh frag for the last frag. */ frag_now = (fragS *)obstack_alloc(&frags, SIZEOF_STRUCT_FRAG); memset(frag_now, '\0', SIZEOF_STRUCT_FRAG); frag_now->fr_next = NULL; (void)obstack_finish(&frags); /* * Append the new frag to current frchain. */ frchainP->frch_last->fr_next = frag_now; frchainP->frch_last = frag_now; frag_wane(frag_now); } /* * Now set the relative addresses of frags within the section by * relaxing each section. That is all sections will start at address * zero and addresses of the frags in that section will increase from * there. * * The debug sections are done last as other section are needed to be * done first becase debug sections may have line numbers with .loc * directives in them and their sizes need to be set before processing * the line number sections. We also do sections that have rs_leb128s * in them before debug sections but after other sections since they * are used for things like exception tables and they may be refering to * sections such that their sizes too must be known first. */ for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ if((frchainP->frch_section.flags & S_ATTR_DEBUG) == S_ATTR_DEBUG) frchainP->layout_pass = 2; else if(frchainP->has_rs_leb128s == TRUE) frchainP->layout_pass = 1; else frchainP->layout_pass = 0; } for(layout_pass = 0; layout_pass < 3; layout_pass++){ do{ changed = 0; for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ if(frchainP->layout_pass != layout_pass) continue; if((frchainP->frch_section.flags & SECTION_TYPE) == S_ZEROFILL) continue; /* * This is done so in case md_estimate_size_before_relax() * (called by relax_section) wants to make fixSs they are * for this section. */ frchain_now = frchainP; changed += relax_section(frchainP->frch_root, frchainP->frch_nsect); } } while(changed != 0); } /* * Now set the absolute addresses of all frags by sliding the frags in * each non-zerofill section by the address ranges taken up by the * sections before it. */ slide = 0; for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ if((frchainP->frch_section.flags & SECTION_TYPE) == S_ZEROFILL) continue; slide = round(slide, 1 << frchainP->frch_section.align); tmp = frchainP->frch_last->fr_address; if(slide != 0){ for(fragP = frchainP->frch_root; fragP; fragP = fragP->fr_next){ fragP->fr_address += slide; } } slide += tmp; } /* * Now with the non-zerofill section addresses set set all of the * addresses of the zerofill sections. Comming in the fr_address is * the size of the section and going out it is the start address. This * will make layout_symbols() work out naturally. The only funky thing * is that section numbers do not end up in address order. */ for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ if((frchainP->frch_section.flags & SECTION_TYPE) != S_ZEROFILL) continue; slide = round(slide, 1 << frchainP->frch_section.align); tmp = frchainP->frch_root->fr_address; frchainP->frch_root->fr_address = slide; frchainP->frch_last->fr_address = tmp + slide; slide += tmp; } /* * Set the symbol addresses based on their frag's address. * First forward references are handled. */ for(symbolP = symbol_rootP; symbolP; symbolP = symbolP->sy_next){ if(symbolP->sy_forward != NULL){ if(symbolP->sy_nlist.n_type & N_STAB) symbolP->sy_other = symbolP->sy_forward->sy_other; symbolP->sy_value += symbolP->sy_forward->sy_value + symbolP->sy_forward->sy_frag->fr_address; symbolP->sy_forward = 0; } } for(symbolP = symbol_rootP; symbolP; symbolP = symbolP->sy_next){ symbolP->sy_value += symbolP->sy_frag->fr_address; } /* * At this point the addresses of frags now reflect addresses we use in * the object file and the symbol values are correct. * Scan the frags, converting any ".org"s and ".align"s to ".fill"s. * Also converting any machine-dependent frags using md_convert_frag(); */ for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ /* * This is done so any fixes created by md_convert_frag() are for * this section. */ frchain_now = frchainP; for(fragP = frchainP->frch_root; fragP; fragP = fragP->fr_next){ switch(fragP->fr_type){ case rs_align: case rs_org: old_fr_type = fragP->fr_type; /* convert this frag to an rs_fill type */ fragP->fr_type = rs_fill; /* * Calculate the number of bytes the variable part of the * the rs_fill frag will need to fill. Then calculate this * as the fill_size * repeat_expression + partial_bytes. */ know(fragP->fr_next != NULL); nbytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix; if(nbytes < 0){ as_warn("rs_org invalid, dot past value by %d bytes", nbytes); nbytes = 0; } fill_size = fragP->fr_var; repeat_expression = nbytes / fill_size; #ifdef I386 /* * For x86 architecures in sections containing only * instuctions being padded with nops that are aligned to 16 * bytes or less and are assembled with -dynamic we will * actually end up padding with the optimal nop sequence. * Previously there has been the maximum number of bytes * allocated in the frag to use for this. */ if(old_fr_type == rs_align && (frchain_now->frch_section.flags & S_ATTR_PURE_INSTRUCTIONS) != 0 && fill_size == 1 && fragP->fr_literal[fragP->fr_fix] == (char)0x90 && nbytes > 0 && nbytes < 16 && flagseen['k'] == TRUE){ i386_align_code(fragP, nbytes); /* * The call to i386_align_code() has set the fill_size * in fragP->fr_var to nbytes. So we set the fr_offset * to the fill repeat_expression to 1 to match for this * now an rs_fill type frag. */ fragP->fr_offset = 1; break; } #endif /* I386 */ partial_bytes = nbytes - (repeat_expression * fill_size); /* * Now set the fr_offset to the fill repeat_expression * since this is now an rs_fill type. The fr_var is still * the fill_size. */ fragP->fr_offset = repeat_expression; /* * For rs_align frags there may be partial_bytes to fill * with zeros before we can fill with the fill_expression * of fill_size. When the rs_align frag was created it was * created with fill_size-1 extra bytes in the fixed part. */ if(partial_bytes != 0){ /* moved the fill_expression bytes foward */ memmove(fragP->fr_literal +fragP->fr_fix +partial_bytes, fragP->fr_literal +fragP->fr_fix, fragP->fr_var); /* zero out the partial_bytes */ memset(fragP->fr_literal + fragP->fr_fix, '\0', partial_bytes); /* adjust the fixed part of the frag */ fragP->fr_fix += partial_bytes; } break; case rs_fill: break; case rs_machine_dependent: md_convert_frag(fragP); /* * After md_convert_frag, we make the frag into a ".fill 0" * md_convert_frag() should set up any fixSs and constants * required. */ frag_wane(fragP); break; case rs_dwarf2dbg: dwarf2dbg_convert_frag(fragP); break; case rs_leb128: { int size; #ifdef OLD valueT value = S_GET_VALUE (fragP->fr_symbol); #else valueT value; expressionS *expression; if(fragP->fr_symbol->expression != NULL){ expression = (expressionS *)fragP->fr_symbol->expression; value = 0; if(expression->X_add_symbol != NULL) value += expression->X_add_symbol->sy_nlist.n_value; if(expression->X_subtract_symbol != NULL) value -= expression->X_subtract_symbol->sy_nlist.n_value; value += expression->X_add_number; } else{ value = fragP->fr_symbol->sy_nlist.n_value + fragP->fr_address; } #endif size = output_leb128 (fragP->fr_literal + fragP->fr_fix, value, fragP->fr_subtype); fragP->fr_fix += size; fragP->fr_type = rs_fill; fragP->fr_var = 0; fragP->fr_offset = 0; fragP->fr_symbol = NULL; } break; default: BAD_CASE(fragP->fr_type); break; } } } /* * For each section do the fixups for the frags. */ for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ now_seg = frchainP->frch_nsect; fixup_section(frchainP->frch_fix_root, frchainP->frch_nsect); } }
/* * layout_addresses() is called after all the assembly code has been read and * fragments, symbols and fixups have been created. This routine sets the * address of the fragments and symbols. Then it does the fixups of the frags * and prepares the fixes so relocation entries can be created from them. */ void layout_addresses( void) { struct frchain *frchainP; fragS *fragP; relax_addressT slide, tmp; symbolS *symbolP; unsigned long nbytes, fill_size, repeat_expression, partial_bytes; if(frchain_root == NULL) return; /* * If there is any current frag close it off. */ if(frag_now != NULL && frag_now->fr_fix == 0){ frag_now->fr_fix = obstack_next_free(&frags) - frag_now->fr_literal; frag_wane(frag_now); } /* * For every section, add a last ".fill 0" frag that will later be used * as the ending address of that section. */ for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ /* * We must do the obstack_finish(), so the next object we put on * obstack frags will not appear to start at the fr_literal of the * current frag. Also, it ensures that the next object will begin * on a address that is aligned correctly for the engine that runs * the assembler. */ obstack_finish(&frags); /* * Make a fresh frag for the last frag. */ frag_now = (fragS *)obstack_alloc(&frags, SIZEOF_STRUCT_FRAG); memset(frag_now, '\0', SIZEOF_STRUCT_FRAG); frag_now->fr_next = NULL; obstack_finish(&frags); /* * Append the new frag to current frchain. */ frchainP->frch_last->fr_next = frag_now; frchainP->frch_last = frag_now; frag_wane(frag_now); } /* * Now set the relitive addresses of frags within the section by * relaxing each section. That is all sections will start at address * zero and addresses of the frags in that section will increase from * there. */ for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ if((frchainP->frch_section.flags & SECTION_TYPE) == S_ZEROFILL) continue; /* * This is done so in case md_estimate_size_before_relax() (called * by relax_section) wants to make fixSs they are for this * section. */ frchain_now = frchainP; relax_section(frchainP->frch_root, frchainP->frch_nsect); } /* * Now set the absolute addresses of all frags by sliding the frags in * each non-zerofill section by the address ranges taken up by the * sections before it. */ slide = 0; for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ if((frchainP->frch_section.flags & SECTION_TYPE) == S_ZEROFILL) continue; slide = round(slide, 1 << frchainP->frch_section.align); tmp = frchainP->frch_last->fr_address; if(slide != 0){ for(fragP = frchainP->frch_root; fragP; fragP = fragP->fr_next){ fragP->fr_address += slide; } } slide += tmp; } /* * Now with the non-zerofill section addresses set set all of the * addresses of the zerofill sections. Comming in the fr_address is * the size of the section and going out it is the start address. This * will make layout_symbols() work out naturally. The only funky thing * is that section numbers do not end up in address order. */ for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ if((frchainP->frch_section.flags & SECTION_TYPE) != S_ZEROFILL) continue; slide = round(slide, 1 << frchainP->frch_section.align); tmp = frchainP->frch_root->fr_address; frchainP->frch_root->fr_address = slide; frchainP->frch_last->fr_address = tmp + slide; slide += tmp; } /* * Set the symbol addresses based on there frag's address. * First forward references are handled. */ for(symbolP = symbol_rootP; symbolP; symbolP = symbolP->sy_next){ if(symbolP->sy_forward != NULL){ if(symbolP->sy_nlist.n_type & N_STAB) symbolP->sy_other = symbolP->sy_forward->sy_other; symbolP->sy_value += symbolP->sy_forward->sy_value + symbolP->sy_forward->sy_frag->fr_address; symbolP->sy_forward = 0; } } for(symbolP = symbol_rootP; symbolP; symbolP = symbolP->sy_next){ symbolP->sy_value += symbolP->sy_frag->fr_address; } /* * At this point the addresses of frags now reflect addresses we use in * the object file and the symbol values are correct. * Scan the frags, converting any ".org"s and ".align"s to ".fill"s. * Also converting any machine-dependent frags using md_convert_frag(); */ for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ /* * This is done so any fixes created by md_convert_frag() are for * this section. */ frchain_now = frchainP; for(fragP = frchainP->frch_root; fragP; fragP = fragP->fr_next){ switch(fragP->fr_type){ case rs_align: case rs_org: /* convert this frag to an rs_fill type */ fragP->fr_type = rs_fill; /* * Calculate the number of bytes the variable part of the * the rs_fill frag will need to fill. Then calculate this * as the fill_size * repeat_expression + partial_bytes. */ know(fragP->fr_next != NULL); nbytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix; if(nbytes < 0){ as_warn("rs_org invalid, dot past value by %ld bytes", nbytes); nbytes = 0; } fill_size = fragP->fr_var; repeat_expression = nbytes / fill_size; partial_bytes = nbytes - (repeat_expression * fill_size); /* * Now set the fr_offset to the fill repeat_expression * since this is now an rs_fill type. The fr_var is still * the fill_size. */ fragP->fr_offset = repeat_expression; /* * For rs_align frags there may be partial_bytes to fill * with zeros before we can fill with the fill_expression * of fill_size. When the rs_align frag was created it was * created with fill_size-1 extra bytes in the fixed part. */ if(partial_bytes != 0){ /* moved the fill_expression bytes foward */ memmove(fragP->fr_literal +fragP->fr_fix +partial_bytes, fragP->fr_literal +fragP->fr_fix, fragP->fr_var); /* zero out the partial_bytes */ memset(fragP->fr_literal + fragP->fr_fix, '\0', partial_bytes); /* adjust the fixed part of the frag */ fragP->fr_fix += partial_bytes; } break; case rs_fill: break; case rs_machine_dependent: md_convert_frag(fragP); /* * After md_convert_frag, we make the frag into a ".fill 0" * md_convert_frag() should set up any fixSs and constants * required. */ frag_wane(fragP); break; default: BAD_CASE(fragP->fr_type); break; } } } /* * For each section do the fixups for the frags. */ for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){ fixup_section(frchainP->frch_fix_root, frchainP->frch_nsect); } }