/ external / libelf / elf_update.c
elf_update.c
   1  /*-
   2   * Copyright (c) 2006-2011 Joseph Koshy
   3   * All rights reserved.
   4   *
   5   * Redistribution and use in source and binary forms, with or without
   6   * modification, are permitted provided that the following conditions
   7   * are met:
   8   * 1. Redistributions of source code must retain the above copyright
   9   *    notice, this list of conditions and the following disclaimer.
  10   * 2. Redistributions in binary form must reproduce the above copyright
  11   *    notice, this list of conditions and the following disclaimer in the
  12   *    documentation and/or other materials provided with the distribution.
  13   *
  14   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  15   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  16   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  17   * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  18   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  19   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  20   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  21   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  22   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  23   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  24   * SUCH DAMAGE.
  25   */
  26  
  27  #include <sys/param.h>
  28  #include <sys/stat.h>
  29  
  30  #include <assert.h>
  31  #include <errno.h>
  32  #include <gelf.h>
  33  #include <libelf.h>
  34  #include <stdlib.h>
  35  #include <string.h>
  36  #include <unistd.h>
  37  
  38  #include "_libelf.h"
  39  
  40  #if	ELFTC_HAVE_MMAP
  41  #include <sys/mman.h>
  42  #endif
  43  
  44  #ifndef roundup2
  45  #define	roundup2(x, y)	(((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
  46  #endif
  47  
  48  ELFTC_VCSID("$Id$");
  49  
  50  /*
  51   * Layout strategy:
  52   *
  53   * - Case 1: ELF_F_LAYOUT is asserted
  54   *     In this case the application has full control over where the
  55   *     section header table, program header table, and section data
  56   *     will reside.   The library only perform error checks.
  57   *
  58   * - Case 2: ELF_F_LAYOUT is not asserted
  59   *
  60   *     The library will do the object layout using the following
  61   *     ordering:
  62   *     - The executable header is placed first, are required by the
  63   *     	 ELF specification.
  64   *     - The program header table is placed immediately following the
  65   *       executable header.
  66   *     - Section data, if any, is placed after the program header
  67   *       table, aligned appropriately.
  68   *     - The section header table, if needed, is placed last.
  69   *
  70   *     There are two sub-cases to be taken care of:
  71   *
  72   *     - Case 2a: e->e_cmd == ELF_C_READ or ELF_C_RDWR
  73   *
  74   *       In this sub-case, the underlying ELF object may already have
  75   *       content in it, which the application may have modified.  The
  76   *       library will retrieve content from the existing object as
  77   *       needed.
  78   *
  79   *     - Case 2b: e->e_cmd == ELF_C_WRITE
  80   *
  81   *       The ELF object is being created afresh in this sub-case;
  82   *       there is no pre-existing content in the underlying ELF
  83   *       object.
  84   */
  85  
  86  /*
  87   * The types of extents in an ELF object.
  88   */
  89  enum elf_extent {
  90  	ELF_EXTENT_EHDR,
  91  	ELF_EXTENT_PHDR,
  92  	ELF_EXTENT_SECTION,
  93  	ELF_EXTENT_SHDR
  94  };
  95  
  96  /*
  97   * A extent descriptor, used when laying out an ELF object.
  98   */
  99  struct _Elf_Extent {
 100  	SLIST_ENTRY(_Elf_Extent) ex_next;
 101  	uint64_t	ex_start; /* Start of the region. */
 102  	uint64_t	ex_size;  /* The size of the region. */
 103  	enum elf_extent	ex_type;  /* Type of region. */
 104  	void		*ex_desc; /* Associated descriptor. */
 105  };
 106  
 107  SLIST_HEAD(_Elf_Extent_List, _Elf_Extent);
 108  
 109  /*
 110   * Compute the extents of a section, by looking at the data
 111   * descriptors associated with it.  The function returns 1
 112   * if successful, or zero if an error was detected.
 113   */
 114  static int
 115  _libelf_compute_section_extents(Elf *e, Elf_Scn *s, off_t rc)
 116  {
 117  	Elf_Data *d;
 118  	size_t fsz, msz;
 119  	int ec, elftype;
 120  	uint32_t sh_type;
 121  	uint64_t d_align;
 122  	Elf32_Shdr *shdr32;
 123  	Elf64_Shdr *shdr64;
 124  	struct _Libelf_Data *ld;
 125  	uint64_t scn_size, scn_alignment;
 126  	uint64_t sh_align, sh_entsize, sh_offset, sh_size;
 127  
 128  	ec = e->e_class;
 129  
 130  	shdr32 = &s->s_shdr.s_shdr32;
 131  	shdr64 = &s->s_shdr.s_shdr64;
 132  	if (ec == ELFCLASS32) {
 133  		sh_type    = shdr32->sh_type;
 134  		sh_align   = (uint64_t) shdr32->sh_addralign;
 135  		sh_entsize = (uint64_t) shdr32->sh_entsize;
 136  		sh_offset  = (uint64_t) shdr32->sh_offset;
 137  		sh_size    = (uint64_t) shdr32->sh_size;
 138  	} else {
 139  		sh_type    = shdr64->sh_type;
 140  		sh_align   = shdr64->sh_addralign;
 141  		sh_entsize = shdr64->sh_entsize;
 142  		sh_offset  = shdr64->sh_offset;
 143  		sh_size    = shdr64->sh_size;
 144  	}
 145  
 146  	assert(sh_type != SHT_NULL && sh_type != SHT_NOBITS);
 147  
 148  	elftype = _libelf_xlate_shtype(sh_type);
 149  	if (elftype > ELF_T_LAST) {
 150  		LIBELF_SET_ERROR(SECTION, 0);
 151  		return (0);
 152  	}
 153  
 154  	if (sh_align == 0)
 155  		sh_align = _libelf_falign(elftype, ec);
 156  
 157  	/*
 158  	 * Compute the section's size and alignment using the data
 159  	 * descriptors associated with the section.
 160  	 */
 161  	if (STAILQ_EMPTY(&s->s_data)) {
 162  		/*
 163  		 * The section's content (if any) has not been read in
 164  		 * yet.  If section is not dirty marked dirty, we can
 165  		 * reuse the values in the 'sh_size' and 'sh_offset'
 166  		 * fields of the section header.
 167  		 */
 168  		if ((s->s_flags & ELF_F_DIRTY) == 0) {
 169  			/*
 170  			 * If the library is doing the layout, then we
 171  			 * compute the new start offset for the
 172  			 * section based on the current offset and the
 173  			 * section's alignment needs.
 174  			 *
 175  			 * If the application is doing the layout, we
 176  			 * can use the value in the 'sh_offset' field
 177  			 * in the section header directly.
 178  			 */
 179  			if (e->e_flags & ELF_F_LAYOUT)
 180  				goto updatedescriptor;
 181  			else
 182  				goto computeoffset;
 183  		}
 184  
 185  		/*
 186  		 * Otherwise, we need to bring in the section's data
 187  		 * from the underlying ELF object.
 188  		 */
 189  		if (e->e_cmd != ELF_C_WRITE && elf_getdata(s, NULL) == NULL)
 190  			return (0);
 191  	}
 192  
 193  	/*
 194  	 * Loop through the section's data descriptors.
 195  	 */
 196  	scn_size = 0L;
 197  	scn_alignment = 0;
 198  	STAILQ_FOREACH(ld, &s->s_data, d_next)  {
 199  
 200  		d = &ld->d_data;
 201  
 202  		/*
 203  		 * The data buffer's type is known.
 204  		 */
 205  		if (d->d_type >= ELF_T_NUM) {
 206  			LIBELF_SET_ERROR(DATA, 0);
 207  			return (0);
 208  		}
 209  
 210  		/*
 211  		 * The data buffer's version is supported.
 212  		 */
 213  		if (d->d_version != e->e_version) {
 214  			LIBELF_SET_ERROR(VERSION, 0);
 215  			return (0);
 216  		}
 217  
 218  		/*
 219  		 * The buffer's alignment is non-zero and a power of
 220  		 * two.
 221  		 */
 222  		if ((d_align = d->d_align) == 0 ||
 223  		    (d_align & (d_align - 1))) {
 224  			LIBELF_SET_ERROR(DATA, 0);
 225  			return (0);
 226  		}
 227  
 228  		/*
 229  		 * The buffer's size should be a multiple of the
 230  		 * memory size of the underlying type.
 231  		 */
 232  		msz = _libelf_msize(d->d_type, ec, e->e_version);
 233  		if (d->d_size % msz) {
 234  			LIBELF_SET_ERROR(DATA, 0);
 235  			return (0);
 236  		}
 237  
 238  		/*
 239  		 * If the application is controlling layout, then the
 240  		 * d_offset field should be compatible with the
 241  		 * buffer's specified alignment.
 242  		 */
 243  		if ((e->e_flags & ELF_F_LAYOUT) &&
 244  		    (d->d_off & (d_align - 1))) {
 245  			LIBELF_SET_ERROR(LAYOUT, 0);
 246  			return (0);
 247  		}
 248  
 249  		/*
 250  		 * Compute the section's size.
 251  		 */
 252  		if (e->e_flags & ELF_F_LAYOUT) {
 253  			if ((uint64_t) d->d_off + d->d_size > scn_size)
 254  				scn_size = d->d_off + d->d_size;
 255  		} else {
 256  			scn_size = roundup2(scn_size, d->d_align);
 257  			d->d_off = scn_size;
 258  			fsz = _libelf_fsize(d->d_type, ec, d->d_version,
 259  			    (size_t) d->d_size / msz);
 260  			scn_size += fsz;
 261  		}
 262  
 263  		/*
 264  		 * The section's alignment is the maximum alignment
 265  		 * needed for its data buffers.
 266  		 */
 267  		if (d_align > scn_alignment)
 268  			scn_alignment = d_align;
 269  	}
 270  
 271  
 272  	/*
 273  	 * If the application is requesting full control over the
 274  	 * layout of the section, check the section's specified size,
 275  	 * offsets and alignment for sanity.
 276  	 */
 277  	if (e->e_flags & ELF_F_LAYOUT) {
 278  		if (scn_alignment > sh_align || sh_offset % sh_align ||
 279  		    sh_size < scn_size) {
 280  			LIBELF_SET_ERROR(LAYOUT, 0);
 281  			return (0);
 282  		}
 283  		goto updatedescriptor;
 284  	}
 285  
 286  	/*
 287  	 * Otherwise, compute the values in the section header.
 288  	 *
 289  	 * The section alignment is the maximum alignment for any of
 290  	 * its contained data descriptors.
 291  	 */
 292  	if (scn_alignment > sh_align)
 293  		sh_align = scn_alignment;
 294  
 295  	/*
 296  	 * If the section entry size is zero, try and fill in an
 297  	 * appropriate entry size.  Per the elf(5) manual page
 298  	 * sections without fixed-size entries should have their
 299  	 * 'sh_entsize' field set to zero.
 300  	 */
 301  	if (sh_entsize == 0 &&
 302  	    (sh_entsize = _libelf_fsize(elftype, ec, e->e_version,
 303  		(size_t) 1)) == 1)
 304  		sh_entsize = 0;
 305  
 306  	sh_size = scn_size;
 307  
 308  computeoffset:
 309  	/*
 310  	 * Compute the new offset for the section based on
 311  	 * the section's alignment needs.
 312  	 */
 313  	sh_offset = roundup((uint64_t) rc, sh_align);
 314  
 315  	/*
 316  	 * Update the section header.
 317  	 */
 318  	if (ec == ELFCLASS32) {
 319  		shdr32->sh_addralign = (uint32_t) sh_align;
 320  		shdr32->sh_entsize   = (uint32_t) sh_entsize;
 321  		shdr32->sh_offset    = (uint32_t) sh_offset;
 322  		shdr32->sh_size      = (uint32_t) sh_size;
 323  	} else {
 324  		shdr64->sh_addralign = sh_align;
 325  		shdr64->sh_entsize   = sh_entsize;
 326  		shdr64->sh_offset    = sh_offset;
 327  		shdr64->sh_size      = sh_size;
 328  	}
 329  
 330  updatedescriptor:
 331  	/*
 332  	 * Update the section descriptor.
 333  	 */
 334  	s->s_size = sh_size;
 335  	s->s_offset = sh_offset;
 336  
 337  	return (1);
 338  }
 339  
 340  /*
 341   * Free a list of extent descriptors.
 342   */
 343  
 344  static void
 345  _libelf_release_extents(struct _Elf_Extent_List *extents)
 346  {
 347  	struct _Elf_Extent *ex;
 348  
 349  	while ((ex = SLIST_FIRST(extents)) != NULL) {
 350  		SLIST_REMOVE_HEAD(extents, ex_next);
 351  		free(ex);
 352  	}
 353  }
 354  
 355  /*
 356   * Check if an extent 's' defined by [start..start+size) is free.
 357   * This routine assumes that the given extent list is sorted in order
 358   * of ascending extent offsets.
 359   */
 360  
 361  static int
 362  _libelf_extent_is_unused(struct _Elf_Extent_List *extents,
 363      const uint64_t start, const uint64_t size, struct _Elf_Extent **prevt)
 364  {
 365  	uint64_t tmax, tmin;
 366  	struct _Elf_Extent *t, *pt;
 367  	const uint64_t smax = start + size;
 368  
 369  	/* First, look for overlaps with existing extents. */
 370  	pt = NULL;
 371  	SLIST_FOREACH(t, extents, ex_next) {
 372  		tmin = t->ex_start;
 373  		tmax = tmin + t->ex_size;
 374  
 375  		if (tmax <= start) {
 376  			/*
 377  			 * 't' lies entirely before 's': ...| t |...| s |...
 378  			 */
 379  			pt = t;
 380  			continue;
 381  		} else if (smax <= tmin) {
 382  			/*
 383  			 * 's' lies entirely before 't', and after 'pt':
 384  			 *      ...| pt |...| s |...| t |...
 385  			 */
 386  			assert(pt == NULL ||
 387  			    pt->ex_start + pt->ex_size <= start);
 388  			break;
 389  		} else
 390  			/* 's' and 't' overlap. */
 391  			return (0);
 392  	}
 393  
 394  	if (prevt)
 395  		*prevt = pt;
 396  	return (1);
 397  }
 398  
 399  /*
 400   * Insert an extent into the list of extents.
 401   */
 402  
 403  static int
 404  _libelf_insert_extent(struct _Elf_Extent_List *extents, int type,
 405      uint64_t start, uint64_t size, void *desc)
 406  {
 407  	struct _Elf_Extent *ex, *prevt;
 408  
 409  	assert(type >= ELF_EXTENT_EHDR && type <= ELF_EXTENT_SHDR);
 410  
 411  	prevt = NULL;
 412  
 413  	/*
 414  	 * If the requested range overlaps with an existing extent,
 415  	 * signal an error.
 416  	 */
 417  	if (!_libelf_extent_is_unused(extents, start, size, &prevt)) {
 418  		LIBELF_SET_ERROR(LAYOUT, 0);
 419  		return (0);
 420  	}
 421  
 422  	/* Allocate and fill in a new extent descriptor. */
 423  	if ((ex = malloc(sizeof(struct _Elf_Extent))) == NULL) {
 424  		LIBELF_SET_ERROR(RESOURCE, errno);
 425  		return (0);
 426  	}
 427  	ex->ex_start = start;
 428  	ex->ex_size = size;
 429  	ex->ex_desc = desc;
 430  	ex->ex_type = type;
 431  
 432  	/* Insert the region descriptor into the list. */
 433  	if (prevt)
 434  		SLIST_INSERT_AFTER(prevt, ex, ex_next);
 435  	else
 436  		SLIST_INSERT_HEAD(extents, ex, ex_next);
 437  	return (1);
 438  }
 439  
 440  /*
 441   * Recompute section layout.
 442   */
 443  
 444  static off_t
 445  _libelf_resync_sections(Elf *e, off_t rc, struct _Elf_Extent_List *extents)
 446  {
 447  	int ec;
 448  	Elf_Scn *s;
 449  	size_t sh_type;
 450  
 451  	ec = e->e_class;
 452  
 453  	/*
 454  	 * Make a pass through sections, computing the extent of each
 455  	 * section.
 456  	 */
 457  	STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next) {
 458  		if (ec == ELFCLASS32)
 459  			sh_type = s->s_shdr.s_shdr32.sh_type;
 460  		else
 461  			sh_type = s->s_shdr.s_shdr64.sh_type;
 462  
 463  		if (sh_type == SHT_NOBITS || sh_type == SHT_NULL)
 464  			continue;
 465  
 466  		if (_libelf_compute_section_extents(e, s, rc) == 0)
 467  			return ((off_t) -1);
 468  
 469  		if (s->s_size == 0)
 470  			continue;
 471  
 472  		if (!_libelf_insert_extent(extents, ELF_EXTENT_SECTION,
 473  		    s->s_offset, s->s_size, s))
 474  			return ((off_t) -1);
 475  
 476  		if ((size_t) rc < s->s_offset + s->s_size)
 477  			rc = (off_t) (s->s_offset + s->s_size);
 478  	}
 479  
 480  	return (rc);
 481  }
 482  
 483  /*
 484   * Recompute the layout of the ELF object and update the internal data
 485   * structures associated with the ELF descriptor.
 486   *
 487   * Returns the size in bytes the ELF object would occupy in its file
 488   * representation.
 489   *
 490   * After a successful call to this function, the following structures
 491   * are updated:
 492   *
 493   * - The ELF header is updated.
 494   * - All extents in the ELF object are sorted in order of ascending
 495   *   addresses.  Sections have their section header table entries
 496   *   updated.  An error is signalled if an overlap was detected among
 497   *   extents.
 498   * - Data descriptors associated with sections are checked for valid
 499   *   types, offsets and alignment.
 500   *
 501   * After a resync_elf() successfully returns, the ELF descriptor is
 502   * ready for being handed over to _libelf_write_elf().
 503   */
 504  
 505  static off_t
 506  _libelf_resync_elf(Elf *e, struct _Elf_Extent_List *extents)
 507  {
 508  	int ec, eh_class;
 509  	unsigned int eh_byteorder, eh_version;
 510  	size_t align, fsz;
 511  	size_t phnum, shnum;
 512  	off_t rc, phoff, shoff;
 513  	void *ehdr, *phdr;
 514  	Elf32_Ehdr *eh32;
 515  	Elf64_Ehdr *eh64;
 516  
 517  	rc = 0;
 518  
 519  	ec = e->e_class;
 520  
 521  	assert(ec == ELFCLASS32 || ec == ELFCLASS64);
 522  
 523  	/*
 524  	 * Prepare the EHDR.
 525  	 */
 526  	if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL)
 527  		return ((off_t) -1);
 528  
 529  	eh32 = ehdr;
 530  	eh64 = ehdr;
 531  
 532  	if (ec == ELFCLASS32) {
 533  		eh_byteorder = eh32->e_ident[EI_DATA];
 534  		eh_class     = eh32->e_ident[EI_CLASS];
 535  		phoff        = (off_t) eh32->e_phoff;
 536  		shoff        = (off_t) eh32->e_shoff;
 537  		eh_version   = eh32->e_version;
 538  	} else {
 539  		eh_byteorder = eh64->e_ident[EI_DATA];
 540  		eh_class     = eh64->e_ident[EI_CLASS];
 541  		phoff        = (off_t) eh64->e_phoff;
 542  		shoff        = (off_t) eh64->e_shoff;
 543  		eh_version   = eh64->e_version;
 544  	}
 545  
 546  	if (phoff < 0 || shoff < 0) {
 547  		LIBELF_SET_ERROR(HEADER, 0);
 548  		return ((off_t) -1);
 549  	}
 550  
 551  	if (eh_version == EV_NONE)
 552  		eh_version = EV_CURRENT;
 553  
 554  	if (eh_version != e->e_version) {	/* always EV_CURRENT */
 555  		LIBELF_SET_ERROR(VERSION, 0);
 556  		return ((off_t) -1);
 557  	}
 558  
 559  	if (eh_class != e->e_class) {
 560  		LIBELF_SET_ERROR(CLASS, 0);
 561  		return ((off_t) -1);
 562  	}
 563  
 564  	if (e->e_cmd != ELF_C_WRITE && eh_byteorder != e->e_byteorder) {
 565  		LIBELF_SET_ERROR(HEADER, 0);
 566  		return ((off_t) -1);
 567  	}
 568  
 569  	shnum = e->e_u.e_elf.e_nscn;
 570  	phnum = e->e_u.e_elf.e_nphdr;
 571  
 572  	e->e_byteorder = eh_byteorder;
 573  
 574  #define	INITIALIZE_EHDR(E,EC,V)	do {					\
 575  		unsigned int _version = (unsigned int) (V);		\
 576  		(E)->e_ident[EI_MAG0] = ELFMAG0;			\
 577  		(E)->e_ident[EI_MAG1] = ELFMAG1;			\
 578  		(E)->e_ident[EI_MAG2] = ELFMAG2;			\
 579  		(E)->e_ident[EI_MAG3] = ELFMAG3;			\
 580  		(E)->e_ident[EI_CLASS] = (unsigned char) (EC);		\
 581  		(E)->e_ident[EI_VERSION] = (_version & 0xFFU);		\
 582  		(E)->e_ehsize = (uint16_t) _libelf_fsize(ELF_T_EHDR,	\
 583  		    (EC), _version, (size_t) 1);			\
 584  		(E)->e_phentsize = (uint16_t) ((phnum == 0) ? 0 :	\
 585  		    _libelf_fsize(ELF_T_PHDR, (EC), _version,		\
 586  			(size_t) 1));					\
 587  		(E)->e_shentsize = (uint16_t) _libelf_fsize(ELF_T_SHDR,	\
 588  		    (EC), _version, (size_t) 1);			\
 589  	} while (0)
 590  
 591  	if (ec == ELFCLASS32)
 592  		INITIALIZE_EHDR(eh32, ec, eh_version);
 593  	else
 594  		INITIALIZE_EHDR(eh64, ec, eh_version);
 595  
 596  	(void) elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY);
 597  
 598  	rc += (off_t) _libelf_fsize(ELF_T_EHDR, ec, eh_version, (size_t) 1);
 599  
 600  	if (!_libelf_insert_extent(extents, ELF_EXTENT_EHDR, 0, (uint64_t) rc,
 601  		ehdr))
 602  		return ((off_t) -1);
 603  
 604  	/*
 605  	 * Compute the layout the program header table, if one is
 606  	 * present.  The program header table needs to be aligned to a
 607  	 * `natural' boundary.
 608  	 */
 609  	if (phnum) {
 610  		fsz = _libelf_fsize(ELF_T_PHDR, ec, eh_version, phnum);
 611  		align = _libelf_falign(ELF_T_PHDR, ec);
 612  
 613  		if (e->e_flags & ELF_F_LAYOUT) {
 614  			/*
 615  			 * Check offsets for sanity.
 616  			 */
 617  			if (rc > phoff) {
 618  				LIBELF_SET_ERROR(LAYOUT, 0);
 619  				return ((off_t) -1);
 620  			}
 621  
 622  			if (phoff % (off_t) align) {
 623  				LIBELF_SET_ERROR(LAYOUT, 0);
 624  				return ((off_t) -1);
 625  			}
 626  
 627  		} else
 628  			phoff = roundup(rc, (off_t) align);
 629  
 630  		rc = phoff + (off_t) fsz;
 631  
 632  		phdr = _libelf_getphdr(e, ec);
 633  
 634  		if (!_libelf_insert_extent(extents, ELF_EXTENT_PHDR,
 635  			(uint64_t) phoff, fsz, phdr))
 636  			return ((off_t) -1);
 637  	} else
 638  		phoff = 0;
 639  
 640  	/*
 641  	 * Compute the layout of the sections associated with the
 642  	 * file.
 643  	 */
 644  
 645  	if (e->e_cmd != ELF_C_WRITE &&
 646  	    (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 &&
 647  	    _libelf_load_section_headers(e, ehdr) == 0)
 648  		return ((off_t) -1);
 649  
 650  	if ((rc = _libelf_resync_sections(e, rc, extents)) < 0)
 651  		return ((off_t) -1);
 652  
 653  	/*
 654  	 * Compute the space taken up by the section header table, if
 655  	 * one is needed.
 656  	 *
 657  	 * If ELF_F_LAYOUT has been asserted, the application may have
 658  	 * placed the section header table in between existing
 659  	 * sections, so the net size of the file need not increase due
 660  	 * to the presence of the section header table.
 661  	 *
 662  	 * If the library is responsible for laying out the object,
 663  	 * the section header table is placed after section data.
 664  	 */
 665  	if (shnum) {
 666  		fsz = _libelf_fsize(ELF_T_SHDR, ec, eh_version, shnum);
 667  		align = _libelf_falign(ELF_T_SHDR, ec);
 668  
 669  		if (e->e_flags & ELF_F_LAYOUT) {
 670  			if (shoff % (off_t) align) {
 671  				LIBELF_SET_ERROR(LAYOUT, 0);
 672  				return ((off_t) -1);
 673  			}
 674  		} else
 675  			shoff = roundup(rc, (off_t) align);
 676  
 677  		if (shoff + (off_t) fsz > rc)
 678  			rc = shoff + (off_t) fsz;
 679  
 680  		if (!_libelf_insert_extent(extents, ELF_EXTENT_SHDR,
 681  			(uint64_t) shoff, fsz, NULL))
 682  			return ((off_t) -1);
 683  	} else
 684  		shoff = 0;
 685  
 686  	/*
 687  	 * Set the fields of the Executable Header that could potentially use
 688  	 * extended numbering.
 689  	 */
 690  	_libelf_setphnum(e, ehdr, ec, phnum);
 691  	_libelf_setshnum(e, ehdr, ec, shnum);
 692  
 693  	/*
 694  	 * Update the `e_phoff' and `e_shoff' fields if the library is
 695  	 * doing the layout.
 696  	 */
 697  	if ((e->e_flags & ELF_F_LAYOUT) == 0) {
 698  		if (ec == ELFCLASS32) {
 699  			eh32->e_phoff = (uint32_t) phoff;
 700  			eh32->e_shoff = (uint32_t) shoff;
 701  		} else {
 702  			eh64->e_phoff = (uint64_t) phoff;
 703  			eh64->e_shoff = (uint64_t) shoff;
 704  		}
 705  	}
 706  
 707  	return (rc);
 708  }
 709  
 710  /*
 711   * Write out the contents of an ELF section.
 712   */
 713  
 714  static off_t
 715  _libelf_write_scn(Elf *e, unsigned char *nf, struct _Elf_Extent *ex)
 716  {
 717  	int ec;
 718  	off_t rc;
 719  	Elf_Scn *s;
 720  	int elftype;
 721  	Elf_Data *d, dst;
 722  	uint32_t sh_type;
 723  	struct _Libelf_Data *ld;
 724  	uint64_t sh_off, sh_size;
 725  	size_t fsz, msz, nobjects;
 726  
 727  	assert(ex->ex_type == ELF_EXTENT_SECTION);
 728  
 729  	s = ex->ex_desc;
 730  	rc = (off_t) ex->ex_start;
 731  
 732  	if ((ec = e->e_class) == ELFCLASS32) {
 733  		sh_type = s->s_shdr.s_shdr32.sh_type;
 734  		sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size;
 735  	} else {
 736  		sh_type = s->s_shdr.s_shdr64.sh_type;
 737  		sh_size = s->s_shdr.s_shdr64.sh_size;
 738  	}
 739  
 740  	/*
 741  	 * Ignore sections that do not allocate space in the file.
 742  	 */
 743  	if (sh_type == SHT_NOBITS || sh_type == SHT_NULL || sh_size == 0)
 744  		return (rc);
 745  
 746  	elftype = _libelf_xlate_shtype(sh_type);
 747  	assert(elftype >= ELF_T_FIRST && elftype <= ELF_T_LAST);
 748  
 749  	sh_off = s->s_offset;
 750  	assert(sh_off % _libelf_falign(elftype, ec) == 0);
 751  
 752  	/*
 753  	 * If the section has a `rawdata' descriptor, and the section
 754  	 * contents have not been modified, use its contents directly.
 755  	 * The `s_rawoff' member contains the offset into the original
 756  	 * file, while `s_offset' contains its new location in the
 757  	 * destination.
 758  	 */
 759  
 760  	if (STAILQ_EMPTY(&s->s_data)) {
 761  
 762  		if ((d = elf_rawdata(s, NULL)) == NULL)
 763  			return ((off_t) -1);
 764  
 765  		STAILQ_FOREACH(ld, &s->s_rawdata, d_next) {
 766  
 767  			d = &ld->d_data;
 768  
 769  			if ((uint64_t) rc < sh_off + d->d_off)
 770  				(void) memset(nf + rc,
 771  				    LIBELF_PRIVATE(fillchar),
 772  				    (size_t) (sh_off + d->d_off -
 773  					(uint64_t) rc));
 774  			rc = (off_t) (sh_off + d->d_off);
 775  
 776  			assert(d->d_buf != NULL);
 777  			assert(d->d_type == ELF_T_BYTE);
 778  			assert(d->d_version == e->e_version);
 779  
 780  			(void) memcpy(nf + rc,
 781  			    e->e_rawfile + s->s_rawoff + d->d_off,
 782  			    (size_t) d->d_size);
 783  
 784  			rc += (off_t) d->d_size;
 785  		}
 786  
 787  		return (rc);
 788  	}
 789  
 790  	/*
 791  	 * Iterate over the set of data descriptors for this section.
 792  	 * The prior call to _libelf_resync_elf() would have setup the
 793  	 * descriptors for this step.
 794  	 */
 795  
 796  	dst.d_version = e->e_version;
 797  
 798  	STAILQ_FOREACH(ld, &s->s_data, d_next) {
 799  
 800  		d = &ld->d_data;
 801  
 802  		msz = _libelf_msize(d->d_type, ec, e->e_version);
 803  
 804  		if ((uint64_t) rc < sh_off + d->d_off)
 805  			(void) memset(nf + rc,
 806  			    LIBELF_PRIVATE(fillchar),
 807  			    (size_t) (sh_off + d->d_off - (uint64_t) rc));
 808  
 809  		rc = (off_t) (sh_off + d->d_off);
 810  
 811  		assert(d->d_buf != NULL);
 812  		assert(d->d_version == e->e_version);
 813  		assert(d->d_size % msz == 0);
 814  
 815  		nobjects = (size_t) (d->d_size / msz);
 816  
 817  		fsz = _libelf_fsize(d->d_type, ec, e->e_version, nobjects);
 818  
 819  		dst.d_buf    = nf + rc;
 820  		dst.d_size   = fsz;
 821  
 822  		if (_libelf_xlate(&dst, d, e->e_byteorder, ec, ELF_TOFILE) ==
 823  		    NULL)
 824  			return ((off_t) -1);
 825  
 826  		rc += (off_t) fsz;
 827  	}
 828  
 829  	return (rc);
 830  }
 831  
 832  /*
 833   * Write out an ELF Executable Header.
 834   */
 835  
 836  static off_t
 837  _libelf_write_ehdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex)
 838  {
 839  	int ec;
 840  	void *ehdr;
 841  	size_t fsz, msz;
 842  	Elf_Data dst, src;
 843  
 844  	assert(ex->ex_type == ELF_EXTENT_EHDR);
 845  	assert(ex->ex_start == 0); /* Ehdr always comes first. */
 846  
 847  	ec = e->e_class;
 848  
 849  	ehdr = _libelf_ehdr(e, ec, 0);
 850  	assert(ehdr != NULL);
 851  
 852  	fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1);
 853  	msz = _libelf_msize(ELF_T_EHDR, ec, e->e_version);
 854  
 855  	(void) memset(&dst, 0, sizeof(dst));
 856  	(void) memset(&src, 0, sizeof(src));
 857  
 858  	src.d_buf     = ehdr;
 859  	src.d_size    = msz;
 860  	src.d_type    = ELF_T_EHDR;
 861  	src.d_version = dst.d_version = e->e_version;
 862  
 863  	dst.d_buf     = nf;
 864  	dst.d_size    = fsz;
 865  
 866  	if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, ELF_TOFILE) ==
 867  	    NULL)
 868  		return ((off_t) -1);
 869  
 870  	return ((off_t) fsz);
 871  }
 872  
 873  /*
 874   * Write out an ELF program header table.
 875   */
 876  
 877  static off_t
 878  _libelf_write_phdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex)
 879  {
 880  	int ec;
 881  	void *ehdr;
 882  	Elf32_Ehdr *eh32;
 883  	Elf64_Ehdr *eh64;
 884  	Elf_Data dst, src;
 885  	size_t fsz, phnum;
 886  	uint64_t phoff;
 887  
 888  	assert(ex->ex_type == ELF_EXTENT_PHDR);
 889  
 890  	ec = e->e_class;
 891  	ehdr = _libelf_ehdr(e, ec, 0);
 892  	phnum = e->e_u.e_elf.e_nphdr;
 893  
 894  	assert(phnum > 0);
 895  
 896  	if (ec == ELFCLASS32) {
 897  		eh32 = (Elf32_Ehdr *) ehdr;
 898  		phoff = (uint64_t) eh32->e_phoff;
 899  	} else {
 900  		eh64 = (Elf64_Ehdr *) ehdr;
 901  		phoff = eh64->e_phoff;
 902  	}
 903  
 904  	assert(phoff > 0);
 905  	assert(ex->ex_start == phoff);
 906  	assert(phoff % _libelf_falign(ELF_T_PHDR, ec) == 0);
 907  
 908  	(void) memset(&dst, 0, sizeof(dst));
 909  	(void) memset(&src, 0, sizeof(src));
 910  
 911  	fsz = _libelf_fsize(ELF_T_PHDR, ec, e->e_version, phnum);
 912  	assert(fsz > 0);
 913  
 914  	src.d_buf = _libelf_getphdr(e, ec);
 915  	src.d_version = dst.d_version = e->e_version;
 916  	src.d_type = ELF_T_PHDR;
 917  	src.d_size = phnum * _libelf_msize(ELF_T_PHDR, ec,
 918  	    e->e_version);
 919  
 920  	dst.d_size = fsz;
 921  	dst.d_buf = nf + ex->ex_start;
 922  
 923  	if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, ELF_TOFILE) ==
 924  	    NULL)
 925  		return ((off_t) -1);
 926  
 927  	return ((off_t) (phoff + fsz));
 928  }
 929  
 930  /*
 931   * Write out an ELF section header table.
 932   */
 933  
 934  static off_t
 935  _libelf_write_shdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex)
 936  {
 937  	int ec;
 938  	void *ehdr;
 939  	Elf_Scn *scn;
 940  	uint64_t shoff;
 941  	Elf32_Ehdr *eh32;
 942  	Elf64_Ehdr *eh64;
 943  	size_t fsz, nscn;
 944  	Elf_Data dst, src;
 945  
 946  	assert(ex->ex_type == ELF_EXTENT_SHDR);
 947  
 948  	ec = e->e_class;
 949  	ehdr = _libelf_ehdr(e, ec, 0);
 950  	nscn = e->e_u.e_elf.e_nscn;
 951  
 952  	if (ec == ELFCLASS32) {
 953  		eh32 = (Elf32_Ehdr *) ehdr;
 954  		shoff = (uint64_t) eh32->e_shoff;
 955  	} else {
 956  		eh64 = (Elf64_Ehdr *) ehdr;
 957  		shoff = eh64->e_shoff;
 958  	}
 959  
 960  	assert(nscn > 0);
 961  	assert(shoff % _libelf_falign(ELF_T_SHDR, ec) == 0);
 962  	assert(ex->ex_start == shoff);
 963  
 964  	(void) memset(&dst, 0, sizeof(dst));
 965  	(void) memset(&src, 0, sizeof(src));
 966  
 967  	src.d_type = ELF_T_SHDR;
 968  	src.d_size = _libelf_msize(ELF_T_SHDR, ec, e->e_version);
 969  	src.d_version = dst.d_version = e->e_version;
 970  
 971  	fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, (size_t) 1);
 972  
 973  	STAILQ_FOREACH(scn, &e->e_u.e_elf.e_scn, s_next) {
 974  		if (ec == ELFCLASS32)
 975  			src.d_buf = &scn->s_shdr.s_shdr32;
 976  		else
 977  			src.d_buf = &scn->s_shdr.s_shdr64;
 978  
 979  		dst.d_size = fsz;
 980  		dst.d_buf = nf + ex->ex_start + scn->s_ndx * fsz;
 981  
 982  		if (_libelf_xlate(&dst, &src, e->e_byteorder, ec,
 983  		    ELF_TOFILE) == NULL)
 984  			return ((off_t) -1);
 985  	}
 986  
 987  	return ((off_t) (ex->ex_start + nscn * fsz));
 988  }
 989  
 990  /*
 991   * Write out the file image.
 992   *
 993   * The original file could have been mapped in with an ELF_C_RDWR
 994   * command and the application could have added new content or
 995   * re-arranged its sections before calling elf_update().  Consequently
 996   * its not safe to work `in place' on the original file.  So we
 997   * malloc() the required space for the updated ELF object and build
 998   * the object there and write it out to the underlying file at the
 999   * end.  Note that the application may have opened the underlying file
1000   * in ELF_C_RDWR and only retrieved/modified a few sections.  We take
1001   * care to avoid translating file sections unnecessarily.
1002   *
1003   * Gaps in the coverage of the file by the file's sections will be
1004   * filled with the fill character set by elf_fill(3).
1005   */
1006  
1007  static off_t
1008  _libelf_write_elf(Elf *e, off_t newsize, struct _Elf_Extent_List *extents)
1009  {
1010  	off_t nrc, rc;
1011  	Elf_Scn *scn, *tscn;
1012  	struct _Elf_Extent *ex;
1013  	unsigned char *newfile;
1014  
1015  	assert(e->e_kind == ELF_K_ELF);
1016  	assert(e->e_cmd == ELF_C_RDWR || e->e_cmd == ELF_C_WRITE);
1017  	assert(e->e_fd >= 0);
1018  
1019  	if ((newfile = malloc((size_t) newsize)) == NULL) {
1020  		LIBELF_SET_ERROR(RESOURCE, errno);
1021  		return ((off_t) -1);
1022  	}
1023  
1024  	nrc = rc = 0;
1025  	SLIST_FOREACH(ex, extents, ex_next) {
1026  
1027  		/* Fill inter-extent gaps. */
1028  		if (ex->ex_start > (size_t) rc)
1029  			(void) memset(newfile + rc, LIBELF_PRIVATE(fillchar),
1030  			    (size_t) (ex->ex_start - (uint64_t) rc));
1031  
1032  		switch (ex->ex_type) {
1033  		case ELF_EXTENT_EHDR:
1034  			if ((nrc = _libelf_write_ehdr(e, newfile, ex)) < 0)
1035  				goto error;
1036  			break;
1037  
1038  		case ELF_EXTENT_PHDR:
1039  			if ((nrc = _libelf_write_phdr(e, newfile, ex)) < 0)
1040  				goto error;
1041  			break;
1042  
1043  		case ELF_EXTENT_SECTION:
1044  			if ((nrc = _libelf_write_scn(e, newfile, ex)) < 0)
1045  				goto error;
1046  			break;
1047  
1048  		case ELF_EXTENT_SHDR:
1049  			if ((nrc = _libelf_write_shdr(e, newfile, ex)) < 0)
1050  				goto error;
1051  			break;
1052  
1053  		default:
1054  			assert(0);
1055  			break;
1056  		}
1057  
1058  		assert(ex->ex_start + ex->ex_size == (size_t) nrc);
1059  		assert(rc < nrc);
1060  
1061  		rc = nrc;
1062  	}
1063  
1064  	assert(rc == newsize);
1065  
1066  	/*
1067  	 * For regular files, throw away existing file content and
1068  	 * unmap any existing mappings.
1069  	 */
1070  	if ((e->e_flags & LIBELF_F_SPECIAL_FILE) == 0) {
1071  		if (ftruncate(e->e_fd, (off_t) 0) < 0 ||
1072  		    lseek(e->e_fd, (off_t) 0, SEEK_SET)) {
1073  			LIBELF_SET_ERROR(IO, errno);
1074  			goto error;
1075  		}
1076  #if	ELFTC_HAVE_MMAP
1077  		if (e->e_flags & LIBELF_F_RAWFILE_MMAP) {
1078  			assert(e->e_rawfile != NULL);
1079  			assert(e->e_cmd == ELF_C_RDWR);
1080  			if (munmap(e->e_rawfile, e->e_rawsize) < 0) {
1081  				LIBELF_SET_ERROR(IO, errno);
1082  				goto error;
1083  			}
1084  		}
1085  #endif
1086  	}
1087  
1088  	/*
1089  	 * Write out the new contents.
1090  	 */
1091  	if (write(e->e_fd, newfile, (size_t) newsize) != newsize) {
1092  		LIBELF_SET_ERROR(IO, errno);
1093  		goto error;
1094  	}
1095  
1096  	/*
1097  	 * For files opened in ELF_C_RDWR mode, set up the new 'raw'
1098  	 * contents.
1099  	 */
1100  	if (e->e_cmd == ELF_C_RDWR) {
1101  		assert(e->e_rawfile != NULL);
1102  		assert((e->e_flags & LIBELF_F_RAWFILE_MALLOC) ||
1103  		    (e->e_flags & LIBELF_F_RAWFILE_MMAP));
1104  		if (e->e_flags & LIBELF_F_RAWFILE_MALLOC) {
1105  			free(e->e_rawfile);
1106  			e->e_rawfile = newfile;
1107  			newfile = NULL;
1108  		}
1109  #if	ELFTC_HAVE_MMAP
1110  		else if (e->e_flags & LIBELF_F_RAWFILE_MMAP) {
1111  			if ((e->e_rawfile = mmap(NULL, (size_t) newsize,
1112  			    PROT_READ, MAP_PRIVATE, e->e_fd, (off_t) 0)) ==
1113  			    MAP_FAILED) {
1114  				LIBELF_SET_ERROR(IO, errno);
1115  				goto error;
1116  			}
1117  		}
1118  #endif	/* ELFTC_HAVE_MMAP */
1119  
1120  		/* Record the new size of the file. */
1121  		e->e_rawsize = (size_t) newsize;
1122  	} else {
1123  		/* File opened in ELF_C_WRITE mode. */
1124  		assert(e->e_rawfile == NULL);
1125  	}
1126  
1127  	/*
1128  	 * Reset flags, remove existing section descriptors and
1129  	 * {E,P}HDR pointers so that a subsequent elf_get{e,p}hdr()
1130  	 * and elf_getscn() will function correctly.
1131  	 */
1132  
1133  	e->e_flags &= ~ELF_F_DIRTY;
1134  
1135  	STAILQ_FOREACH_SAFE(scn, &e->e_u.e_elf.e_scn, s_next, tscn)
1136  		_libelf_release_scn(scn);
1137  
1138  	if (e->e_class == ELFCLASS32) {
1139  		free(e->e_u.e_elf.e_ehdr.e_ehdr32);
1140  		if (e->e_u.e_elf.e_phdr.e_phdr32)
1141  			free(e->e_u.e_elf.e_phdr.e_phdr32);
1142  
1143  		e->e_u.e_elf.e_ehdr.e_ehdr32 = NULL;
1144  		e->e_u.e_elf.e_phdr.e_phdr32 = NULL;
1145  	} else {
1146  		free(e->e_u.e_elf.e_ehdr.e_ehdr64);
1147  		if (e->e_u.e_elf.e_phdr.e_phdr64)
1148  			free(e->e_u.e_elf.e_phdr.e_phdr64);
1149  
1150  		e->e_u.e_elf.e_ehdr.e_ehdr64 = NULL;
1151  		e->e_u.e_elf.e_phdr.e_phdr64 = NULL;
1152  	}
1153  
1154  	/* Free the temporary buffer. */
1155  	if (newfile)
1156  		free(newfile);
1157  
1158  	return (rc);
1159  
1160   error:
1161  	free(newfile);
1162  
1163  	return ((off_t) -1);
1164  }
1165  
1166  /*
1167   * Update an ELF object.
1168   */
1169  
1170  off_t
1171  elf_update(Elf *e, Elf_Cmd c)
1172  {
1173  	int ec;
1174  	off_t rc;
1175  	struct _Elf_Extent_List extents;
1176  
1177  	rc = (off_t) -1;
1178  
1179  	if (e == NULL || e->e_kind != ELF_K_ELF ||
1180  	    (c != ELF_C_NULL && c != ELF_C_WRITE)) {
1181  		LIBELF_SET_ERROR(ARGUMENT, 0);
1182  		return (rc);
1183  	}
1184  
1185  	if ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64) {
1186  		LIBELF_SET_ERROR(CLASS, 0);
1187  		return (rc);
1188  	}
1189  
1190  	if (e->e_version == EV_NONE)
1191  		e->e_version = EV_CURRENT;
1192  
1193  	if (c == ELF_C_WRITE && e->e_cmd == ELF_C_READ) {
1194  		LIBELF_SET_ERROR(MODE, 0);
1195  		return (rc);
1196  	}
1197  
1198  	SLIST_INIT(&extents);
1199  
1200  	if ((rc = _libelf_resync_elf(e, &extents)) < 0)
1201  		goto done;
1202  
1203  	if (c == ELF_C_NULL)
1204  		goto done;
1205  
1206  	if (e->e_fd < 0) {
1207  		rc = (off_t) -1;
1208  		LIBELF_SET_ERROR(SEQUENCE, 0);
1209  		goto done;
1210  	}
1211  
1212  	rc = _libelf_write_elf(e, rc, &extents);
1213  
1214  done:
1215  	_libelf_release_extents(&extents);
1216  	return (rc);
1217  }