Exemple #1
0
void *
aplist_append(APlist **lpp, const void *ptr, Aliste init_arritems)
{
	Aliste ndx = ((*lpp) == NULL) ? 0 : (*lpp)->apl_nitems;

	return (aplist_insert(lpp, ptr, init_arritems, ndx));
}
Exemple #2
0
/*
 * Add an entrance criteria record for the specified segment
 *
 * entry:
 *	mf - Mapfile descriptor
 *	sgp - Segment for which a new entrance criteria record is needed
 *	name - NULL, or name by which the entrance criteria can be referenced.
 *
 * exit:
 *	On success, a pointer to the new entrace criteria record is
 *	returned, the contents of which have been zeroed. On failure,
 *	NULL is returned.
 */
Ent_desc *
ld_map_seg_ent_add(Mapfile *mf, Sg_desc *sgp, const char *name)
{
	Ent_desc	*enp;
	avl_index_t	where;
	Ofl_desc	*ofl = mf->mf_ofl;

	if ((name != NULL) &&
	    (ld_ent_lookup(mf->mf_ofl, name, &where) != NULL)) {
		mf_fatal(mf, (MSG_MAP_DUPNAMENT), name);
		return (NULL);
	}

	/* Allocate and initialize the entrace criteria descriptor */
	if ((enp = libld_calloc(1, sizeof (*enp))) == NULL)
		return (NULL);
	enp->ec_name = name;
	enp->ec_segment = sgp;	 /* Tie criteria to segment */


	/*
	 * Insert into the APlist. The mf_ec_insndx field for each mapfile
	 * starts at 0, and is incremented with each insertion. This means
	 * that the entrance criteria for each mapfile go to the head of
	 * the list, but that within a single mapfile, they are inserted in
	 * the order they are seen.
	 */
	if (aplist_insert(&ofl->ofl_ents, enp, AL_CNT_OFL_ENTRANCE,
	    mf->mf_ec_insndx) == NULL)
		return (NULL);
	mf->mf_ec_insndx++;

	/*
	 * If the entrance criteria is named insert it into the AVL tree
	 * as well. This provides O(logN) lookups by name.
	 */
	if (name != NULL)
		avl_insert(&ofl->ofl_ents_avl, enp, where);

	return (enp);
}
Exemple #3
0
/*
 * Attach an input section to an output section
 *
 * entry:
 *	ofl - File descriptor
 *	osp - Output section descriptor
 *	isp - Input section descriptor
 *	mapfile_sort - True (1) if segment supports mapfile specified ordering
 *		of otherwise unordered input sections, and False (0) otherwise.
 *
 * exit:
 *	- The input section has been attached to the output section
 *	- If the input section is a candidate for string table merging,
 *		then it is appended to the output section's list of merge
 *		candidates (os_mstridescs).
 *
 *	On success, returns True (1). On failure, False (0).
 */
static int
os_attach_isp(Ofl_desc *ofl, Os_desc *osp, Is_desc *isp, int mapfile_sort)
{
	Aliste	init_arritems;
	int	os_isdescs_idx, do_append = 1;

	if ((isp->is_flags & FLG_IS_ORDERED) == 0) {
		init_arritems = AL_CNT_OS_ISDESCS;
		os_isdescs_idx = OS_ISD_DEFAULT;

		/*
		 * If section ordering was specified for an unordered section
		 * via the mapfile, then search in the OS_ISD_DEFAULT list
		 * and insert it in the specified position. Ordered sections
		 * are placed in ascending order before unordered sections
		 * (sections with an is_ordndx value of zero).
		 *
		 * If no mapfile ordering was specified, we append it in
		 * the usual way below.
		 */
		if (mapfile_sort && (isp->is_ordndx > 0)) {
			APlist *ap_isdesc = osp->os_isdescs[OS_ISD_DEFAULT];
			Aliste	idx2;
			Is_desc	*isp2;

			for (APLIST_TRAVERSE(ap_isdesc, idx2, isp2)) {
				if (isp2->is_ordndx &&
				    (isp2->is_ordndx <= isp->is_ordndx))
						continue;

				if (aplist_insert(
				    &osp->os_isdescs[OS_ISD_DEFAULT],
				    isp, init_arritems, idx2) == NULL)
					return (0);
				do_append = 0;
				break;
			}
		}
Exemple #4
0
/*
 * Finish the initialization of a new segment descriptor allocated by
 * ld_map_seg_alloc(), and enter it into the segment list.
 *
 * entry:
 *	mf - Mapfile descriptor
 *	seg_type - One of DBG_SEG_NEW or DBG_SEG_NEW_IMPLICIT
 *	ins_head - If true, the new segment goes at the front of
 *		others of its type. If false, it goes at the end.
 *	sgp - Segment descriptor to enter.
 *	where - Insertion point, initialized by a previous (failed) call to
 *		ld_seg_lookup(). Ignored if the segment has a NULL sg_name.
 *
 * exit:
 *	On success, returns SEG_INS_OK. A non-fatal error is indicated with
 *	a return value of SEG_INS_SKIP, in which case the descriptor is
 *	not entered, but the user is expected to discard it and continue
 *	running. On failure, returns SEG_INS_FAIL.
 *
 * note:
 *	This routine will modify the contents of the descriptor referenced
 *	by sgp_tmpl before allocating the new descriptor. The caller must
 *	not expect it to be unmodified.
 */
ld_map_seg_ins_t
ld_map_seg_insert(Mapfile *mf, dbg_state_t dbg_state, Sg_desc *sgp,
    avl_index_t where)
{
	Ofl_desc	*ofl = mf->mf_ofl;
	size_t		idx;
	Sg_desc		*sgp2;		/* temp segment descriptor pointer */
	int		ins_head;
	Elf64_Xword	sg_ndx;

	/*
	 * If specific fields have not been supplied via
	 * map_equal(), make sure defaults are supplied.
	 */
	if (((sgp->sg_flags & FLG_SG_P_TYPE) == 0) &&
	    (sgp->sg_phdr.p_type == PT_NULL)) {
		/*
		 * Default to a loadable segment.
		 */
		sgp->sg_phdr.p_type = PT_LOAD;
		sgp->sg_flags |= FLG_SG_P_TYPE;
	}
	if (sgp->sg_phdr.p_type == PT_LOAD) {
		if ((sgp->sg_flags & FLG_SG_P_FLAGS) == 0) {
			/*
			 * Default to read/write and execute.
			 */
			sgp->sg_phdr.p_flags = PF_R + PF_W + PF_X;
			sgp->sg_flags |= FLG_SG_P_FLAGS;
		}
		if ((sgp->sg_flags & FLG_SG_P_ALIGN) == 0) {
			/*
			 * Default to segment alignment
			 */
			sgp->sg_phdr.p_align = ld_targ.t_m.m_segm_align;
			sgp->sg_flags |= FLG_SG_P_ALIGN;
		}
	}

	/*
	 * Determine where the new item should be inserted in
	 * the segment descriptor list.
	 */
	switch (sgp->sg_phdr.p_type) {
	case PT_LOAD:
		if (sgp->sg_flags & FLG_SG_EMPTY)
			sgp->sg_id = SGID_TEXT_EMPTY;
		else
			sgp->sg_id = SGID_TEXT;
		break;
	case PT_NULL:
		if (sgp->sg_flags & FLG_SG_EMPTY)
			sgp->sg_id = SGID_NULL_EMPTY;
		else
			sgp->sg_id = SGID_NULL;
		break;
	case PT_NOTE:
		sgp->sg_id = SGID_NOTE;
		break;
	default:
		mf_fatal(mf, (MSG_MAP_UNKSEGTYP),
		    EC_WORD(sgp->sg_phdr.p_type));
		return (SEG_INS_FAIL);
	}

	/*
	 * Add the descriptor to the segment list. In the v1 syntax,
	 * new sections are added at the head of their type, while in
	 * the newer syntax, they go at the end of their type.
	 */
	sg_ndx = 0;
	ins_head = (mf->mf_version == MFV_SYSV);
	for (APLIST_TRAVERSE(ofl->ofl_segs, idx, sgp2)) {
		if (ins_head) {	/* Insert before the others of its type */
			if (sgp->sg_id > sgp2->sg_id) {
				sg_ndx++;
				continue;
			}
		} else {	/* Insert after the others of its type */
			if (sgp->sg_id >= sgp2->sg_id) {
				sg_ndx++;
				continue;
			}
		}
		break;
	}
	if (aplist_insert(&ofl->ofl_segs, sgp, AL_CNT_SEGMENTS, idx) == NULL)
		return (SEG_INS_FAIL);
	if (sgp->sg_name != NULL)
		avl_insert(&ofl->ofl_segs_avl, sgp, where);

	//DBG_CALL(Dbg_map_seg(ofl, dbg_state, sg_ndx, sgp, mf->mf_lineno));
	return (SEG_INS_OK);
}