<commit_before>#ifndef lint
static char rcsid[] = "$Header$";
#endif

#include "../../h/out.h"
#include "const.h"
#include "debug.h"
#include "defs.h"
#include "memory.h"
#include "orig.h"
#include "scan.h"

/*
 * Get section sizes and symboltable information from present module.
 */
extract()
{
	struct outhead	head;

	get_modul();
	/*
	 * Copy head because we need it so often but it can change place,
	 * so we can't trust a pointer to it.
	 */
	head = *(struct outhead *)modulptr(IND_HEAD);
	get_names(&head);
	process(&head);
	skip_modul(&head);
}

ushort	NLocals = 0;	/* Number of local names to be saved. */
ushort	NGlobals = 0;	/* Number of global names. */

/*
 * Walk through the nametable of this module, counting the locals that must
 * appear in the final output file if this module is linked.
 * That number will be returned.
 */
static
get_names(head)
	register struct outhead	*head;
{
	register int	nnames;
	register ind_t	sectindex, nameindex, charindex;
	register ind_t	charoff;
	extern int	flagword;

	nnames = head->oh_nname;
	sectindex = IND_SECT(*head);
	nameindex = IND_NAME(*head);
	charindex = IND_CHAR(*head);
	charoff = OFF_CHAR(*head);
	while (nnames--) {
		register struct outsect	*sects;
		struct outname		name;	/* A local copy. */
		/*
		 * Because savelocal/getexternal might relocate the modules
		 * we have to compute the core addresses again.
		 */
		sects = (struct outsect *)modulptr(sectindex);
		name = *(struct outname *)modulptr(nameindex);
		/*
		 * Change the offset in file into an offset in the memory area.
		 * There will always be at least a header before the string
		 * area, so we don't have to be afraid to confuse "no name"
		 * with "the first name".
		 */
		if (name.on_foff)
			name.on_foff += charindex - charoff;
		namerelocate(&name, sects);
		if (name.on_type & S_EXT) {
			getexternal(&name);
		} else {
			/*
			 * The only thing we want to know about locals is
			 * whether they must appear in the output file.
			 */
			if (!(flagword & SFLAG) && mustsavelocal(&name)) {
				NLocals++;
				savelocal(&name);
			}
		}
		nameindex += sizeof(struct outname);
	}
}

extern struct orig	relorig[];

static
process(head)
	register struct outhead	*head;
{
	register struct outsect	*sects;
	register struct outsect	*outsp;
	register int		nsect;
	register struct orig	*orig = relorig;
	extern struct outhead	outhead;
	extern struct outsect	outsect[];

	outhead.oh_nrelo += head->oh_nrelo;
	outhead.oh_nemit += head->oh_nemit;
	if (head->oh_nsect > outhead.oh_nsect)
		outhead.oh_nsect = head->oh_nsect;
	sects = (struct outsect *)modulptr(IND_SECT(*head));
	nsect = head->oh_nsect;
	outsp = outsect;
	while (nsect--) {
		outsp->os_size += sects->os_size;
		outsp->os_flen += sects->os_flen;
		/*
		 * Add all flen's and all (size - flen == zero)'s of
		 * preceding sections with the same number.
		 */
		orig->org_flen += sects->os_flen;
		orig->org_zero += sects->os_size - sects->os_flen;
		orig++; outsp++; sects++;
	}
}

/*
 * Add relocation constant for names in user defined sections.
 * The value of a common name indicates a size instead of an offset,
 * and hence shouldn't be relocated.
 * The value of a name in the zero part of a section is relative from the
 * beginning of the section, not from the beginning of the zero part; but
 * all zero parts will be put after the normal section contents, so we
 * must subtract the flen of its section from the value (and later on add
 * the total flen of its section) and add the accumulated size of all
 * zero parts in preceding sections with the same number.
 * Otherwise we just add the accumulated size of all normal parts in preceding
 * sections with the same size.
 */
namerelocate(name, sects)
	register struct outname	*name;
	struct outsect		*sects;
{
	register int	type = name->on_type;
	register int	sectindex;

	if ((type & S_TYP) == S_UND || (type & S_TYP) == S_ABS)
		return;
	if (type & S_COM)
		return;

	sectindex = (type & S_TYP) - S_MIN;
	if (name->on_valu >= sects[sectindex].os_flen) {
		name->on_type |= S_ZER;
		name->on_valu -= sects[sectindex].os_flen;
		name->on_valu += relorig[sectindex].org_zero;
	} else {
		name->on_valu += relorig[sectindex].org_flen;
	}
}

/*
 * If we see this name for the first time, we must remember it for
 * we might need it later on. Otherwise it must confirm to what we already
 * know about it, and eventually add to that knowledge.
 */
static
getexternal(name)
	register struct outname	*name;
{
	register char		*string;
	register int		h;
	register struct outname	*old;
	extern int		hash();
	extern struct outname	*searchname();

	string = modulptr((ind_t)name->on_foff);
	h = hash(string);
	old = searchname(string, h);
	if (old == (struct outname *)0) {
		NGlobals++;
		entername(name, h);
	} else if (!ISUNDEFINED(name)) {
		if (ISUNDEFINED(old)) {
			transfer(name, old);
		} else {
			name->on_mptr = string;	/* Just for convenience. */
			redefine(name, old);
		}
	}
}

/*
 * Handle the redefinition of `new' in the current module.
 * A name can be defined in three ways, in increasing priority:
 *	undefined,<commit_msg>Added assignment for debuuging info.<commit_after>#ifndef lint
static char rcsid[] = "$Header$";
#endif

#include "../../h/out.h"
#include "const.h"
#include "debug.h"
#include "defs.h"
#include "memory.h"
#include "orig.h"
#include "scan.h"

/*
 * Get section sizes and symboltable information from present module.
 */
extract()
{
	struct outhead	head;

	get_modul();
	/*
	 * Copy head because we need it so often but it can change place,
	 * so we can't trust a pointer to it.
	 */
	head = *(struct outhead *)modulptr(IND_HEAD);
	get_names(&head);
	process(&head);
	skip_modul(&head);
}

ushort	NLocals = 0;	/* Number of local names to be saved. */
ushort	NGlobals = 0;	/* Number of global names. */

/*
 * Walk through the nametable of this module, counting the locals that must
 * appear in the final output file if this module is linked.
 * That number will be returned.
 */
static
get_names(head)
	register struct outhead	*head;
{
	register int	nnames;
	register ind_t	sectindex, nameindex, charindex;
	register ind_t	charoff;
	extern int	flagword;

	nnames = head->oh_nname;
	sectindex = IND_SECT(*head);
	nameindex = IND_NAME(*head);
	charindex = IND_CHAR(*head);
	charoff = OFF_CHAR(*head);
	while (nnames--) {
		register struct outsect	*sects;
		struct outname		name;	/* A local copy. */
		/*
		 * Because savelocal/getexternal might relocate the modules
		 * we have to compute the core addresses again.
		 */
		sects = (struct outsect *)modulptr(sectindex);
		name = *(struct outname *)modulptr(nameindex);
		/*
		 * Change the offset in file into an offset in the memory area.
		 * There will always be at least a header before the string
		 * area, so we don't have to be afraid to confuse "no name"
		 * with "the first name".
		 */
		if (name.on_foff)
			name.on_foff += charindex - charoff;
		namerelocate(&name, sects);
		if (name.on_type & S_EXT) {
			getexternal(&name);
		} else {
			/*
			 * The only thing we want to know about locals is
			 * whether they must appear in the output file.
			 */
			if (!(flagword & SFLAG) && mustsavelocal(&name)) {
				NLocals++;
				savelocal(&name);
			}
		}
		nameindex += sizeof(struct outname);
	}
}

extern struct orig	relorig[];

static
process(head)
	register struct outhead	*head;
{
	register struct outsect	*sects;
	register struct outsect	*outsp;
	register int		nsect;
	register struct orig	*orig = relorig;
	extern struct outhead	outhead;
	extern struct outsect	outsect[];

	outhead.oh_nrelo += head->oh_nrelo;
	outhead.oh_nemit += head->oh_nemit;
	if (head->oh_nsect > outhead.oh_nsect)
		outhead.oh_nsect = head->oh_nsect;
	sects = (struct outsect *)modulptr(IND_SECT(*head));
	nsect = head->oh_nsect;
	outsp = outsect;
	while (nsect--) {
		outsp->os_size += sects->os_size;
		outsp->os_flen += sects->os_flen;
		/*
		 * Add all flen's and all (size - flen == zero)'s of
		 * preceding sections with the same number.
		 */
		orig->org_flen += sects->os_flen;
		orig->org_zero += sects->os_size - sects->os_flen;
		orig++; outsp++; sects++;
	}
}

/*
 * Add relocation constant for names in user defined sections.
 * The value of a common name indicates a size instead of an offset,
 * and hence shouldn't be relocated.
 * The value of a name in the zero part of a section is relative from the
 * beginning of the section, not from the beginning of the zero part; but
 * all zero parts will be put after the normal section contents, so we
 * must subtract the flen of its section from the value (and later on add
 * the total flen of its section) and add the accumulated size of all
 * zero parts in preceding sections with the same number.
 * Otherwise we just add the accumulated size of all normal parts in preceding
 * sections with the same size.
 */
namerelocate(name, sects)
	register struct outname	*name;
	struct outsect		*sects;
{
	register int	type = name->on_type;
	register int	sectindex;

	if ((type & S_TYP) == S_UND || (type & S_TYP) == S_ABS)
		return;
	if (type & S_COM)
		return;

	sectindex = (type & S_TYP) - S_MIN;
	if (name->on_valu >= sects[sectindex].os_flen) {
		name->on_type |= S_ZER;
		name->on_valu -= sects[sectindex].os_flen;
		name->on_valu += relorig[sectindex].org_zero;
	} else {
		name->on_valu += relorig[sectindex].org_flen;
	}
}

/*
 * If we see this name for the first time, we must remember it for
 * we might need it later on. Otherwise it must confirm to what we already
 * know about it, and eventually add to that knowledge.
 */
static
getexternal(name)
	register struct outname	*name;
{
	register char		*string;
	register int		h;
	register struct outname	*old;
	extern int		hash();
	extern struct outname	*searchname();

	string = modulptr((ind_t)name->on_foff);
	h = hash(string);
	old = searchname(string, h);
	if (old == (struct outname *)0) {
		NGlobals++;
		entername(name, h);
	} else if (!ISUNDEFINED(name)) {
		if (ISUNDEFINED(old)) {
			name->on_mptr = string;	/* Just for convenience. */
			transfer(name, old);
		} else {
			name->on_mptr = string;	/* Just for convenience. */
			redefine(name, old);
		}
	}
}

/*
 * Handle the redefinition of `new' in the current module.
 * A name can be defined in three ways, in increasing priority:
 *	undefined,
{'fraction_non_alphanumeric': 0.11636505156645262, 'fraction_numerical': 0.0005837711617046118, 'mean_word_length': 3.623931623931624, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 54, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7205058', 'n_tokens_mistral': 3730, 'n_tokens_neox': 3485, 'n_words': 1224}