⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 frags.c

📁 早期freebsd实现
💻 C
字号:
/* frags.c - manage frags -   Copyright (C) 1987 Free Software Foundation, Inc.This file is part of GAS, the GNU Assembler.GAS is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 1, or (at your option)any later version.GAS is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GAS; see the file COPYING.  If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */#include "as.h"#include "subsegs.h"#include "obstack.h"#include "frags.h"#include "struc-symbol.h"struct obstack  frags;	/* All, and only, frags live here. */fragS zero_address_frag = {	0,			/* fr_address */	NULL,			/* fr_next */	0,			/* fr_fix */	0,			/* fr_var */	0,			/* fr_symbol */	0,			/* fr_offset */	NULL,			/* fr_opcode */	rs_fill,		/* fr_type */	0,			/* fr_subtype */	0,			/* fr_pcrel_adjust */	0,			/* fr_bsr */	0			/* fr_literal [0] */};fragS bss_address_frag = {	0,			/* fr_address. Gets filled in to make up				   sy_value-s. */	NULL,			/* fr_next */	0,			/* fr_fix */	0,			/* fr_var */	0,			/* fr_symbol */	0,			/* fr_offset */	NULL,			/* fr_opcode */	rs_fill,		/* fr_type */	0,			/* fr_subtype */	0,			/* fr_pcrel_adjust */	0,			/* fr_bsr */	0			/* fr_literal [0] */};/* *			frag_grow() * * Internal. * Try to augment current frag by nchars chars. * If there is no room, close of the current frag with a ".fill 0" * and begin a new frag. Unless the new frag has nchars chars available * do not return. Do not set up any fields of *now_frag. */static  voidfrag_grow (nchars)int     nchars;{    if (obstack_room (&frags) < nchars) {	unsigned int n,oldn;	long oldc;	frag_wane (frag_now);	frag_new (0);	oldn=(unsigned)-1;	oldc=frags.chunk_size;	frags.chunk_size=2*nchars;	while((n=obstack_room(&frags))<nchars && n<oldn) {		frag_wane(frag_now);		frag_new(0);		oldn=n;	}	frags.chunk_size=oldc;    }    if (obstack_room (&frags) < nchars)	as_fatal ("Can't extend frag %d. chars", nchars);}/* *			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. */voidfrag_new (old_frags_var_max_size)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 */    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 */ bzero(frag_now, 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 (nchars)int     nchars;{    register char  *retval;    frag_grow (nchars);    retval = obstack_next_free (&frags);    obstack_blank_fast (&frags, nchars);    return (retval);}				/* frag_more() *//* *			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 (type, max_chars, var, subtype, symbol, offset, opcode)relax_stateT	type;int		max_chars;int		var;relax_substateT	subtype;symbolS *	symbol;long int	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;    /* default these to zero. */    frag_now->fr_pcrel_adjust = 0;    frag_now->fr_bsr = 0;    frag_new (max_chars);    return (retval);}				/* frag_var() *//* *			frag_variant() * * OVE: This variant of frag_var assumes that space for the tail has been *      allocated by caller. *      No call to frag_grow is done. *      Two new arguments have been added. */char   *frag_variant (type, max_chars, var, subtype, symbol, offset, opcode, pcrel_adjust,bsr)     relax_stateT	 type;     int		 max_chars;     int		 var;     relax_substateT	 subtype;     symbolS		*symbol;     long int		 offset;     char		*opcode;     char		 pcrel_adjust;     char		 bsr;{    register char  *retval;/*    frag_grow (max_chars); */    retval = obstack_next_free (&frags);/*  obstack_blank_fast (&frags, max_chars); */ /* OVE: so far the only diff */    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_now->fr_pcrel_adjust = pcrel_adjust;    frag_now->fr_bsr = bsr;    frag_new (max_chars);    return (retval);}				/* frag_variant() *//* *			frag_wane() * * Reduce the variable end of a frag to a harmless state. */voidfrag_wane (fragP)register    fragS * fragP;{    fragP->fr_type = rs_fill;    fragP->fr_offset = 0;    fragP->fr_var = 0;}/* *			frag_align() * * Make a frag for ".align foo,bar". Call is "frag_align (foo,bar);". * Foo & bar are absolute integers. * * Call to close off the current frag with a ".align", then start a new * (so far empty) frag, in the same subsegment as the last frag. */voidfrag_align (alignment, fill_character)int     alignment;int     fill_character;{    *(frag_var (rs_align, 1, 1, (relax_substateT)0, (symbolS *)0, (long)alignment, (char *)0)) = fill_character;}/* end: frags.c */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -