Ejemplo n.º 1
0
Is_desc *
ld_os_first_isdesc(Os_desc *osp)
{
	int i;

	for (i = 0; i < OS_ISD_NUM; i++) {
		APlist *ap_isdesc = osp->os_isdescs[i];

		if (aplist_nitems(ap_isdesc) > 0)
			return ((Is_desc *)ap_isdesc->apl_data[0]);
	}

	return (NULL);
}
Ejemplo n.º 2
0
/*
 * Generate a statistics line for the auxiliary relocation descriptor cache.
 *
 * entry:
 *	ofl - output file descriptor
 */
static void
rel_aux_cache_statistics(Ofl_desc *ofl)
{
	Rel_aux_cachebuf	*racp;
	Lm_list	*lml = ofl->ofl_lml;
	size_t	desc_cnt = 0, desc_used = 0, bytes;
	Aliste	idx;
	char	unit_buf[CONV_INV_BUFSIZE + 10];

	/* Sum the total memory allocated across all the buffers */
	for (APLIST_TRAVERSE(ofl->ofl_relaux, idx, racp)) {
		desc_cnt += racp->rac_end - racp->rac_arr;
		desc_used += racp->rac_free - racp->rac_arr;
	}
	bytes = desc_cnt * sizeof (Rel_desc);

	dbg_print(lml, MSG_INTL(MSG_STATS_REL_ACACHE),
	    EC_WORD(aplist_nitems(ofl->ofl_relaux)),
	    EC_XWORD(desc_used), EC_XWORD(desc_cnt),
	    (desc_cnt == 0) ? 100 : EC_WORD((desc_used * 100) / desc_cnt),
	    EC_XWORD(bytes),
	    fmt_human_units(bytes, unit_buf, sizeof (unit_buf)));
}
Ejemplo n.º 3
0
/*
 * Add a size symbol to a segment
 *
 * entry:
 *	mf - Mapfile descriptor
 *	sgp - Segment descriptor
 *	eq_tol - Type of assignment: TK_EQUAL, or TK_PLUSEQ
 *	symname - Name of symbol. Must be in stable static storage
 *		that can be retained.
 *
 * exit:
 *	On success, the symbol has been added and true is returned.
 *	Otherwise an error is reported and false is returned.
 */
bool
ld_map_seg_size_symbol(Mapfile *mf, Sg_desc *sgp, Token eq_tok,
    const char *symname)
{
	Elf64_Sym	*sym;		/* New symbol pointer */
	Sym_desc	*sdp;		/* New symbol node pointer */
	Ifl_desc	*ifl;		/* Dummy input file structure */
	avl_index_t	where;
	Ofl_desc	*ofl = mf->mf_ofl;

	/*
	 * We don't allow resetting the list of size symbols, so if the
	 * operator is TK_EQUAL and the list is not empty, issue an error.
	 *
	 * If we want to lift this restriction, we would have to save the
	 * size symbols and enter them from ld_map_post_process(). Doing that
	 * well would require a significant overhead in saved error reporting
	 * state, and interactions with the same symbols created by symbol
	 * directives. As size symbols are of little practical use, and are
	 * maintained primarily for backward compatibility with SysV, we have
	 * decided not to do that, but to create the symbols as the mapfiles
	 * are processed, and to disallow later attempts to remove them.
	 */
	if ((eq_tok == TK_EQUAL) && (aplist_nitems(sgp->sg_sizesym) > 0)) {
		mf_fatal(mf, (MSG_MAP_SEGSIZE), sgp->sg_name);
		return (false);
	}

	/*
	 * Make sure we have a pseudo file descriptor to associate to the
	 * symbol.
	 */
	if ((ifl = ld_map_ifl(mf)) == NULL)
		return (false);

	/*
	 * Make sure the symbol doesn't already exist.  It is possible that the
	 * symbol has been scoped or versioned, in which case it does exist
	 * but we can freely update it here.
	 */
	if ((sdp = ld_sym_find(symname, SYM_NOHASH, &where, ofl)) == NULL) {
		Elf64_Word hval;

		if ((sym = libld_calloc(sizeof (Elf64_Sym), 1)) == NULL)
			return (false);
		sym->st_shndx = SHN_ABS;
		sym->st_size = 0;
		sym->st_info = ELF_ST_INFO(STB_GLOBAL, STT_OBJECT);

		//DBG_CALL(Dbg_map_size_new(ofl->ofl_lml, symname,
		//    sgp->sg_name, mf->mf_lineno));
		/* LINTED */
		hval = (Elf64_Word)elf_hash(symname);
		if ((sdp = ld_sym_enter(symname, sym, hval, ifl, ofl, 0,
		    SHN_ABS, (FLG_SY_SPECSEC | FLG_SY_GLOBREF), &where)) ==
		    (Sym_desc *)S_ERROR)
			return (false);
		sdp->sd_flags &= ~FLG_SY_CLEAN;
		//DBG_CALL(Dbg_map_symbol(ofl, sdp));
	} else {
		sym = sdp->sd_sym;

		if (sym->st_shndx == SHN_UNDEF) {
			sdp->sd_shndx = sym->st_shndx = SHN_ABS;
			sdp->sd_flags |= FLG_SY_SPECSEC;
			sym->st_size = 0;
			sym->st_info = ELF_ST_INFO(STB_GLOBAL, STT_OBJECT);

			sdp->sd_flags &= ~FLG_SY_MAPREF;

			//DBG_CALL(Dbg_map_size_old(ofl, sdp,
			//    sgp->sg_name, mf->mf_lineno));
		} else {
			mf_fatal(mf, (MSG_MAP_SYMDEF1),
			    demangle(sdp->sd_name), sdp->sd_file->ifl_name,
			    (MSG_MAP_DIFF_SYMMUL));
			return (false);
		}
	}

	/*
	 * Assign the symbol to the segment.
	 */
	if (aplist_append(&sgp->sg_sizesym, sdp, AL_CNT_SG_SIZESYM) == NULL)
		return (false);

	return (true);
}
Ejemplo n.º 4
0
void
Dbg_sec_order_list(Ofl_desc *ofl, int flag)
{
	Os_desc		*osp;
	Is_desc		*isp1;
	Aliste		idx1;
	Lm_list		*lml = ofl->ofl_lml;
	const char	*str;

	if (DBG_NOTCLASS(DBG_C_SECTIONS))
		return;
	if (DBG_NOTDETAIL())
		return;

	Dbg_util_nl(lml, DBG_NL_STD);

	/*
	 * If the flag == 0, then the routine is called before sorting.
	 */
	if (flag == 0)
		str = MSG_INTL(MSG_ORD_SORT_BEFORE);
	else
		str = MSG_INTL(MSG_ORD_SORT_AFTER);

	for (APLIST_TRAVERSE(ofl->ofl_ordered, idx1, osp)) {
		int		os_isdescs_idx;
		Aliste		idx2;

		Dbg_util_nl(lml, DBG_NL_STD);
		dbg_print(lml, str, osp->os_name);
		dbg_print(lml, MSG_INTL(MSG_ORD_HDR_1),
		    EC_WORD(aplist_nitems(osp->os_isdescs[OS_ISD_BEFORE])),
		    EC_WORD(aplist_nitems(osp->os_isdescs[OS_ISD_ORDERED])),
		    EC_WORD(aplist_nitems(osp->os_isdescs[OS_ISD_DEFAULT])),
		    EC_WORD(aplist_nitems(osp->os_isdescs[OS_ISD_AFTER])));

		OS_ISDESCS_TRAVERSE(os_isdescs_idx, osp, idx2, isp1) {
			dbg_isec_name_buf_t	buf;
			char			*alloc_mem;
			const char		*isp1_str;
			Word			link;
			Ifl_desc		*ifl = isp1->is_file;
			Is_desc			*isp2;
			const char		*msg;

			/*
			 * An output segment that requires ordering might have
			 * as little as two sorted input sections.  For example,
			 * the crt's can provide a SHN_BEGIN and SHN_AFTER, and
			 * only these two sections must be processed.  Thus, if
			 * a input section is unordered, move on.  Diagnosing
			 * any unsorted section can produce way too much noise.
			 */
			if ((isp1->is_flags & FLG_IS_ORDERED) == 0)
				continue;

			if (isp1->is_shdr->sh_flags & SHF_ORDERED) {
				link = isp1->is_shdr->sh_info;
				msg = MSG_ORIG(MSG_SH_INFO);
			} else {	/* SHF_LINK_ORDER */
				link = isp1->is_shdr->sh_link;
				msg = MSG_ORIG(MSG_SH_LINK);
			}

			isp1_str = dbg_fmt_isec_name(isp1, buf, &alloc_mem);

			if (link == SHN_BEFORE) {
				dbg_print(lml, MSG_INTL(MSG_ORD_TITLE_1), msg,
				    isp1_str, isp1->is_file->ifl_name);
			} else if (link == SHN_AFTER) {
				dbg_print(lml, MSG_INTL(MSG_ORD_TITLE_2), msg,
				    isp1_str, isp1->is_file->ifl_name);
			} else {
				isp2 = ifl->ifl_isdesc[link];
				dbg_print(lml, MSG_INTL(MSG_ORD_TITLE_3),
				    EC_WORD(isp2->is_keyident), isp1_str,
				    ifl->ifl_name, msg, isp2->is_name);
			}
			if (alloc_mem != NULL)
				free(alloc_mem);
		}
	}