/ util / cbfstool / elfheaders.c
elfheaders.c
   1  /* elf header parsing */
   2  /* SPDX-License-Identifier: GPL-2.0-only */
   3  
   4  #include <stdio.h>
   5  #include <stdlib.h>
   6  #include <string.h>
   7  
   8  #include "elfparsing.h"
   9  #include "common.h"
  10  #include "cbfs.h"
  11  
  12  /*
  13   * Short form: this is complicated, but we've tried making it simple
  14   * and we keep hitting problems with our ELF parsing.
  15   *
  16   * The ELF parsing situation has always been a bit tricky.  In fact,
  17   * we (and most others) have been getting it wrong in small ways for
  18   * years. Recently this has caused real trouble for the ARM V8 build.
  19   * In this file we attempt to finally get it right for all variations
  20   * of endian-ness and word size and target architectures and
  21   * architectures we might get run on. Phew!. To do this we borrow a
  22   * page from the FreeBSD NFS xdr model (see elf_ehdr and elf_phdr),
  23   * the Plan 9 endianness functions (see xdr.c), and Go interfaces (see
  24   * how we use buffer structs in this file). This ends up being a bit
  25   * wordy at the lowest level, but greatly simplifies the elf parsing
  26   * code and removes a common source of bugs, namely, forgetting to
  27   * flip type endianness when referencing a struct member.
  28   *
  29   * ELF files can have four combinations of data layout: 32/64, and
  30   * big/little endian.  Further, to add to the fun, depending on the
  31   * word size, the size of the ELF structs varies. The coreboot SELF
  32   * format is simpler in theory: it's supposed to be always BE, and the
  33   * various struct members allow room for growth: the entry point is
  34   * always 64 bits, for example, so the size of a SELF struct is
  35   * constant, regardless of target architecture word size.  Hence, we
  36   * need to do some transformation of the ELF files.
  37   *
  38   * A given architecture, realistically, only supports one of the four
  39   * combinations at a time as the 'native' format. Hence, our code has
  40   * been sprinkled with every variation of [nh]to[hn][sll] over the
  41   * years. We've never quite gotten it all right, however, and a quick
  42   * pass over this code revealed another bug.  It's all worked because,
  43   * until now, all the working platforms that had CBFS were 32 LE. Even then,
  44   * however, bugs crept in: we recently realized that we're not
  45   * transforming the entry point to big format when we store into the
  46   * SELF image.
  47   *
  48   * The problem is essentially an XDR operation:
  49   * we have something in a foreign format and need to transform it.
  50   * It's most like XDR because:
  51   * 1) the byte order can be wrong
  52   * 2) the word size can be wrong
  53   * 3) the size of elements in the stream depends on the value
  54   *    of other elements in the stream
  55   * it's not like XDR because:
  56   * 1) the byte order can be right
  57   * 2) the word size can be right
  58   * 3) the struct members are all on a natural alignment
  59   *
  60   * Hence, this new approach.  To cover word size issues, we *always*
  61   * transform the two structs we care about, the file header and
  62   * program header, into a native struct in the 64 bit format:
  63   *
  64   * [32,little] -> [Elf64_Ehdr, Elf64_Phdr]
  65   * [64,little] -> [Elf64_Ehdr, Elf64_Phdr]
  66   * [32,big] -> [Elf64_Ehdr, Elf64_Phdr]
  67   * [64,big] -> [Elf64_Ehdr, Elf64_Phdr]
  68   * Then we just use those structs, and all the need for inline ntoh* goes away,
  69   * as well as all the chances for error.
  70   * This works because all the SELF structs have fields large enough for
  71   * the largest ELF 64 struct members, and all the Elf64 struct members
  72   * are at least large enough for all ELF 32 struct members.
  73   * We end up with one function to do all our ELF parsing, and two functions
  74   * to transform the headers. For the put case, we also have
  75   * XDR functions, and hopefully we'll never again spend 5 years with the
  76   * wrong endian-ness on an output value :-)
  77   * This should work for all word sizes and endianness we hope to target.
  78   * I *really* don't want to be here for 128 bit addresses.
  79   *
  80   * The parse functions are called with a pointer to an input buffer
  81   * struct. One might ask: are there enough bytes in the input buffer?
  82   * We know there need to be at *least* sizeof(Elf32_Ehdr) +
  83   * sizeof(Elf32_Phdr) bytes. Realistically, there has to be some data
  84   * too.  If we start to worry, though we have not in the past, we
  85   * might apply the simple test: the input buffer needs to be at least
  86   * sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr) bytes because, even if it's
  87   * ELF 32, there's got to be *some* data! This is not theoretically
  88   * accurate but it is actually good enough in practice. It allows the
  89   * header transformation code to ignore the possibility of underrun.
  90   *
  91   * We also must accommodate different ELF files, and hence formats,
  92   * in the same cbfs invocation. We might load a 64-bit payload
  93   * on a 32-bit machine; we might even have a mixed armv7/armv8
  94   * SOC or even a system with an x86/ARM!
  95   *
  96   * A possibly problematic (though unlikely to be so) assumption
  97   * is that we expect the BIOS to remain in the lowest 32 bits
  98   * of the physical address space. Since ARMV8 has standardized
  99   * on that, and x86_64 also has, this seems a safe assumption.
 100   *
 101   * To repeat, ELF structs are different sizes because ELF struct
 102   * members are different sizes, depending on values in the ELF file
 103   * header. For this we use the functions defined in xdr.c, which
 104   * consume bytes, convert the endianness, and advance the data pointer
 105   * in the buffer struct.
 106   */
 107  
 108  
 109  static int iself(const void *input)
 110  {
 111  	const Elf32_Ehdr *ehdr = input;
 112  	return !memcmp(ehdr->e_ident, ELFMAG, 4);
 113  }
 114  
 115  /* Get the ident array, so we can figure out
 116   * endian-ness, word size, and in future other useful
 117   * parameters
 118   */
 119  static void
 120  elf_eident(struct buffer *input, Elf64_Ehdr *ehdr)
 121  {
 122  	bgets(input, ehdr->e_ident, sizeof(ehdr->e_ident));
 123  }
 124  
 125  
 126  static int
 127  check_size(const struct buffer *b, size_t offset, size_t size, const char *desc)
 128  {
 129  	if (size == 0)
 130  		return 0;
 131  
 132  	if (offset >= buffer_size(b) || (offset + size) > buffer_size(b)) {
 133  		ERROR("The file is not large enough for the '%s'. "
 134  		      "%zu bytes @ offset %zu, input %zu bytes.\n",
 135  		      desc, size, offset, buffer_size(b));
 136  		return -1;
 137  	}
 138  	return 0;
 139  }
 140  
 141  static void
 142  elf_ehdr(struct buffer *input, Elf64_Ehdr *ehdr, struct xdr *xdr, int bit64)
 143  {
 144  	ehdr->e_type = xdr->get16(input);
 145  	ehdr->e_machine = xdr->get16(input);
 146  	ehdr->e_version = xdr->get32(input);
 147  	if (bit64){
 148  		ehdr->e_entry = xdr->get64(input);
 149  		ehdr->e_phoff = xdr->get64(input);
 150  		ehdr->e_shoff = xdr->get64(input);
 151  	} else {
 152  		ehdr->e_entry = xdr->get32(input);
 153  		ehdr->e_phoff = xdr->get32(input);
 154  		ehdr->e_shoff = xdr->get32(input);
 155  	}
 156  	ehdr->e_flags = xdr->get32(input);
 157  	ehdr->e_ehsize = xdr->get16(input);
 158  	ehdr->e_phentsize = xdr->get16(input);
 159  	ehdr->e_phnum = xdr->get16(input);
 160  	ehdr->e_shentsize = xdr->get16(input);
 161  	ehdr->e_shnum = xdr->get16(input);
 162  	ehdr->e_shstrndx = xdr->get16(input);
 163  }
 164  
 165  static void
 166  elf_phdr(struct buffer *pinput, Elf64_Phdr *phdr,
 167  	 int entsize, struct xdr *xdr, int bit64)
 168  {
 169  	/*
 170  	 * The entsize need not be sizeof(*phdr).
 171  	 * Hence, it is easier to keep a copy of the input,
 172  	 * as the xdr functions may not advance the input
 173  	 * pointer the full entsize; rather than get tricky
 174  	 * we just advance it below.
 175  	 */
 176  	struct buffer input;
 177  	buffer_clone(&input, pinput);
 178  	if (bit64){
 179  		phdr->p_type = xdr->get32(&input);
 180  		phdr->p_flags = xdr->get32(&input);
 181  		phdr->p_offset = xdr->get64(&input);
 182  		phdr->p_vaddr = xdr->get64(&input);
 183  		phdr->p_paddr = xdr->get64(&input);
 184  		phdr->p_filesz = xdr->get64(&input);
 185  		phdr->p_memsz = xdr->get64(&input);
 186  		phdr->p_align = xdr->get64(&input);
 187  	} else {
 188  		phdr->p_type = xdr->get32(&input);
 189  		phdr->p_offset = xdr->get32(&input);
 190  		phdr->p_vaddr = xdr->get32(&input);
 191  		phdr->p_paddr = xdr->get32(&input);
 192  		phdr->p_filesz = xdr->get32(&input);
 193  		phdr->p_memsz = xdr->get32(&input);
 194  		phdr->p_flags = xdr->get32(&input);
 195  		phdr->p_align = xdr->get32(&input);
 196  	}
 197  	buffer_seek(pinput, entsize);
 198  }
 199  
 200  static void
 201  elf_shdr(struct buffer *pinput, Elf64_Shdr *shdr,
 202  	 int entsize, struct xdr *xdr, int bit64)
 203  {
 204  	/*
 205  	 * The entsize need not be sizeof(*shdr).
 206  	 * Hence, it is easier to keep a copy of the input,
 207  	 * as the xdr functions may not advance the input
 208  	 * pointer the full entsize; rather than get tricky
 209  	 * we just advance it below.
 210  	 */
 211  	struct buffer input = *pinput;
 212  	if (bit64){
 213  		shdr->sh_name = xdr->get32(&input);
 214  		shdr->sh_type = xdr->get32(&input);
 215  		shdr->sh_flags = xdr->get64(&input);
 216  		shdr->sh_addr = xdr->get64(&input);
 217  		shdr->sh_offset = xdr->get64(&input);
 218  		shdr->sh_size= xdr->get64(&input);
 219  		shdr->sh_link = xdr->get32(&input);
 220  		shdr->sh_info = xdr->get32(&input);
 221  		shdr->sh_addralign = xdr->get64(&input);
 222  		shdr->sh_entsize = xdr->get64(&input);
 223  	} else {
 224  		shdr->sh_name = xdr->get32(&input);
 225  		shdr->sh_type = xdr->get32(&input);
 226  		shdr->sh_flags = xdr->get32(&input);
 227  		shdr->sh_addr = xdr->get32(&input);
 228  		shdr->sh_offset = xdr->get32(&input);
 229  		shdr->sh_size = xdr->get32(&input);
 230  		shdr->sh_link = xdr->get32(&input);
 231  		shdr->sh_info = xdr->get32(&input);
 232  		shdr->sh_addralign = xdr->get32(&input);
 233  		shdr->sh_entsize = xdr->get32(&input);
 234  	}
 235  	buffer_seek(pinput, entsize);
 236  }
 237  
 238  static int
 239  phdr_read(const struct buffer *in, struct parsed_elf *pelf,
 240            struct xdr *xdr, int bit64)
 241  {
 242  	struct buffer b;
 243  	Elf64_Phdr *phdr;
 244  	Elf64_Ehdr *ehdr;
 245  	int i;
 246  
 247  	ehdr = &pelf->ehdr;
 248  	/* cons up an input buffer for the headers.
 249  	 * Note that the program headers can be anywhere,
 250  	 * per the ELF spec, You'd be surprised how many ELF
 251  	 * readers miss this little detail.
 252  	 */
 253  	buffer_splice(&b, in, ehdr->e_phoff,
 254  		      (uint32_t)ehdr->e_phentsize * ehdr->e_phnum);
 255  	if (check_size(in, ehdr->e_phoff, buffer_size(&b), "program headers"))
 256  		return -1;
 257  
 258  	/* gather up all the phdrs.
 259  	 * We do them all at once because there is more
 260  	 * than one loop over all the phdrs.
 261  	 */
 262  	phdr = calloc(ehdr->e_phnum, sizeof(*phdr));
 263  	for (i = 0; i < ehdr->e_phnum; i++) {
 264  		DEBUG("Parsing segment %d\n", i);
 265  		elf_phdr(&b, &phdr[i], ehdr->e_phentsize, xdr, bit64);
 266  
 267  		/* Ensure the contents are valid within the elf file. */
 268  		if (check_size(in, phdr[i].p_offset, phdr[i].p_filesz,
 269  	                  "segment contents")) {
 270  			free(phdr);
 271  			return -1;
 272  		}
 273  	}
 274  
 275  	pelf->phdr = phdr;
 276  
 277  	return 0;
 278  }
 279  
 280  static int
 281  shdr_read(const struct buffer *in, struct parsed_elf *pelf,
 282            struct xdr *xdr, int bit64)
 283  {
 284  	struct buffer b;
 285  	Elf64_Shdr *shdr;
 286  	Elf64_Ehdr *ehdr;
 287  	int i;
 288  
 289  	ehdr = &pelf->ehdr;
 290  
 291  	/* cons up an input buffer for the section headers.
 292  	 * Note that the section headers can be anywhere,
 293  	 * per the ELF spec, You'd be surprised how many ELF
 294  	 * readers miss this little detail.
 295  	 */
 296  	buffer_splice(&b, in, ehdr->e_shoff,
 297  		      (uint32_t)ehdr->e_shentsize * ehdr->e_shnum);
 298  	if (check_size(in, ehdr->e_shoff, buffer_size(&b), "section headers"))
 299  		return -1;
 300  
 301  	/* gather up all the shdrs. */
 302  	shdr = calloc(ehdr->e_shnum, sizeof(*shdr));
 303  	for (i = 0; i < ehdr->e_shnum; i++) {
 304  		DEBUG("Parsing section %d\n", i);
 305  		elf_shdr(&b, &shdr[i], ehdr->e_shentsize, xdr, bit64);
 306  	}
 307  
 308  	pelf->shdr = shdr;
 309  
 310  	return 0;
 311  }
 312  
 313  static int
 314  reloc_read(const struct buffer *in, struct parsed_elf *pelf,
 315             struct xdr *xdr, int bit64)
 316  {
 317  	struct buffer b;
 318  	Elf64_Word i;
 319  	Elf64_Ehdr *ehdr;
 320  
 321  	ehdr = &pelf->ehdr;
 322  	pelf->relocs = calloc(ehdr->e_shnum, sizeof(Elf64_Rela *));
 323  
 324  	/* Allocate array for each section that contains relocation entries. */
 325  	for (i = 0; i < ehdr->e_shnum; i++) {
 326  		Elf64_Shdr *shdr;
 327  		Elf64_Rela *rela;
 328  		Elf64_Xword j;
 329  		Elf64_Xword nrelocs;
 330  		int is_rela;
 331  
 332  		shdr = &pelf->shdr[i];
 333  
 334  		/* Only process REL and RELA sections. */
 335  		if (shdr->sh_type != SHT_REL && shdr->sh_type != SHT_RELA)
 336  			continue;
 337  
 338  		DEBUG("Checking relocation section %u\n", i);
 339  
 340  		/* Ensure the section that relocations apply is a valid. */
 341  		if (shdr->sh_info >= ehdr->e_shnum ||
 342  		    shdr->sh_info == SHN_UNDEF) {
 343  			ERROR("Relocations apply to an invalid section: %u\n",
 344  			      shdr[i].sh_info);
 345  			return -1;
 346  		}
 347  
 348  		is_rela = shdr->sh_type == SHT_RELA;
 349  
 350  		/* Determine the number relocations in this section. */
 351  		nrelocs = shdr->sh_size / shdr->sh_entsize;
 352  
 353  		pelf->relocs[i] = calloc(nrelocs, sizeof(Elf64_Rela));
 354  
 355  		buffer_splice(&b, in, shdr->sh_offset, shdr->sh_size);
 356  		if (check_size(in, shdr->sh_offset, buffer_size(&b),
 357  		               "relocation section")) {
 358  			ERROR("Relocation section %u failed.\n", i);
 359  			return -1;
 360  		}
 361  
 362  		rela = pelf->relocs[i];
 363  		for (j = 0; j < nrelocs; j++) {
 364  			if (bit64) {
 365  				rela->r_offset = xdr->get64(&b);
 366  				rela->r_info = xdr->get64(&b);
 367  				if (is_rela)
 368  					rela->r_addend = xdr->get64(&b);
 369  			} else {
 370  				uint32_t r_info;
 371  
 372  				rela->r_offset = xdr->get32(&b);
 373  				r_info = xdr->get32(&b);
 374  				rela->r_info = ELF64_R_INFO(ELF32_R_SYM(r_info),
 375  				                          ELF32_R_TYPE(r_info));
 376  				if (is_rela)
 377  					rela->r_addend = xdr->get32(&b);
 378  			}
 379  			rela++;
 380  		}
 381  	}
 382  
 383  	return 0;
 384  }
 385  
 386  static int strtab_read(const struct buffer *in, struct parsed_elf *pelf)
 387  {
 388  	Elf64_Ehdr *ehdr;
 389  	Elf64_Word i;
 390  
 391  	ehdr = &pelf->ehdr;
 392  
 393  	if (ehdr->e_shstrndx >= ehdr->e_shnum) {
 394  		ERROR("Section header string table index out of range: %d\n",
 395  		      ehdr->e_shstrndx);
 396  		return -1;
 397  	}
 398  
 399  	/* For each section of type SHT_STRTAB create a symtab buffer. */
 400  	pelf->strtabs = calloc(ehdr->e_shnum, sizeof(struct buffer *));
 401  
 402  	for (i = 0; i < ehdr->e_shnum; i++) {
 403  		struct buffer *b;
 404  		Elf64_Shdr *shdr = &pelf->shdr[i];
 405  
 406  		if (shdr->sh_type != SHT_STRTAB)
 407  			continue;
 408  
 409  		b = calloc(1, sizeof(*b));
 410  		buffer_splice(b, in, shdr->sh_offset, shdr->sh_size);
 411  		if (check_size(in, shdr->sh_offset, buffer_size(b), "strtab")) {
 412  			ERROR("STRTAB section not within bounds: %d\n", i);
 413  			free(b);
 414  			return -1;
 415  		}
 416  		pelf->strtabs[i] = b;
 417  	}
 418  
 419  	return 0;
 420  }
 421  
 422  static int
 423  symtab_read(const struct buffer *in, struct parsed_elf *pelf,
 424              struct xdr *xdr, int bit64)
 425  {
 426  	Elf64_Ehdr *ehdr;
 427  	Elf64_Shdr *shdr;
 428  	Elf64_Half shnum;
 429  	Elf64_Xword i;
 430  	Elf64_Xword nsyms;
 431  	Elf64_Sym *sym;
 432  	struct buffer b;
 433  
 434  	ehdr = &pelf->ehdr;
 435  
 436  	shdr = NULL;
 437  	for (shnum = 0; shnum < ehdr->e_shnum; shnum++) {
 438  		if (pelf->shdr[shnum].sh_type != SHT_SYMTAB)
 439  			continue;
 440  
 441  		if (shdr != NULL) {
 442  			ERROR("Multiple symbol sections found. %u and %u\n",
 443  			      (unsigned int)(shdr - pelf->shdr), shnum);
 444  			return -1;
 445  		}
 446  
 447  		shdr = &pelf->shdr[shnum];
 448  	}
 449  
 450  	if (shdr == NULL) {
 451  		ERROR("No symbol table found.\n");
 452  		return -1;
 453  	}
 454  
 455  	buffer_splice(&b, in, shdr->sh_offset, shdr->sh_size);
 456  	if (check_size(in, shdr->sh_offset, buffer_size(&b), "symtab"))
 457  		return -1;
 458  
 459  	nsyms = shdr->sh_size / shdr->sh_entsize;
 460  
 461  	pelf->syms = calloc(nsyms, sizeof(Elf64_Sym));
 462  
 463  	for (i = 0; i < nsyms; i++) {
 464  		sym = &pelf->syms[i];
 465  
 466  		if (bit64) {
 467  			sym->st_name = xdr->get32(&b);
 468  			sym->st_info = xdr->get8(&b);
 469  			sym->st_other = xdr->get8(&b);
 470  			sym->st_shndx = xdr->get16(&b);
 471  			sym->st_value = xdr->get64(&b);
 472  			sym->st_size = xdr->get64(&b);
 473  		} else {
 474  			sym->st_name = xdr->get32(&b);
 475  			sym->st_value = xdr->get32(&b);
 476  			sym->st_size = xdr->get32(&b);
 477  			sym->st_info = xdr->get8(&b);
 478  			sym->st_other = xdr->get8(&b);
 479  			sym->st_shndx = xdr->get16(&b);
 480  		}
 481  	}
 482  
 483  	return 0;
 484  }
 485  
 486  int parse_elf(const struct buffer *pinput, struct parsed_elf *pelf, int flags)
 487  {
 488  	struct xdr *xdr = &xdr_le;
 489  	int bit64 = 0;
 490  	struct buffer input;
 491  	Elf64_Ehdr *ehdr;
 492  
 493  	/* Zero out the parsed elf structure. */
 494  	memset(pelf, 0, sizeof(*pelf));
 495  
 496  	if (!iself(buffer_get(pinput))) {
 497  		DEBUG("The stage file is not in ELF format!\n");
 498  		return -1;
 499  	}
 500  
 501  	buffer_clone(&input, pinput);
 502  	ehdr = &pelf->ehdr;
 503  	elf_eident(&input, ehdr);
 504  	bit64 = ehdr->e_ident[EI_CLASS] == ELFCLASS64;
 505  	/* Assume LE unless we are sure otherwise.
 506  	 * We're not going to take on the task of
 507  	 * fully validating the ELF file. That way
 508  	 * lies madness.
 509  	 */
 510  	if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
 511  		xdr = &xdr_be;
 512  
 513  	elf_ehdr(&input, ehdr, xdr, bit64);
 514  
 515  	/* Relocation processing requires section header parsing. */
 516  	if (flags & ELF_PARSE_RELOC)
 517  		flags |= ELF_PARSE_SHDR;
 518  
 519  	/* String table processing requires section header parsing. */
 520  	if (flags & ELF_PARSE_STRTAB)
 521  		flags |= ELF_PARSE_SHDR;
 522  
 523  	/* Symbole table processing requires section header parsing. */
 524  	if (flags & ELF_PARSE_SYMTAB)
 525  		flags |= ELF_PARSE_SHDR;
 526  
 527  	if ((flags & ELF_PARSE_PHDR) && phdr_read(pinput, pelf, xdr, bit64))
 528  		goto fail;
 529  
 530  	if ((flags & ELF_PARSE_SHDR) && shdr_read(pinput, pelf, xdr, bit64))
 531  		goto fail;
 532  
 533  	if ((flags & ELF_PARSE_RELOC) && reloc_read(pinput, pelf, xdr, bit64))
 534  		goto fail;
 535  
 536  	if ((flags & ELF_PARSE_STRTAB) && strtab_read(pinput, pelf))
 537  		goto fail;
 538  
 539  	if ((flags & ELF_PARSE_SYMTAB) && symtab_read(pinput, pelf, xdr, bit64))
 540  		goto fail;
 541  
 542  	return 0;
 543  
 544  fail:
 545  	parsed_elf_destroy(pelf);
 546  	return -1;
 547  }
 548  
 549  void parsed_elf_destroy(struct parsed_elf *pelf)
 550  {
 551  	Elf64_Half i;
 552  
 553  	free(pelf->phdr);
 554  	free(pelf->shdr);
 555  	if (pelf->relocs != NULL) {
 556  		for (i = 0; i < pelf->ehdr.e_shnum; i++)
 557  			free(pelf->relocs[i]);
 558  	}
 559  	free(pelf->relocs);
 560  
 561  	if (pelf->strtabs != NULL) {
 562  		for (i = 0; i < pelf->ehdr.e_shnum; i++)
 563  			free(pelf->strtabs[i]);
 564  	}
 565  	free(pelf->strtabs);
 566  	free(pelf->syms);
 567  }
 568  
 569  /* Get the headers from the buffer.
 570   * Return -1 in the event of an error.
 571   * The section headers are optional; if NULL
 572   * is passed in for pshdr they won't be parsed.
 573   * We don't (yet) make payload parsing optional
 574   * because we've never seen a use case.
 575   */
 576  int
 577  elf_headers(const struct buffer *pinput,
 578  	    Elf64_Ehdr *ehdr,
 579  	    Elf64_Phdr **pphdr,
 580  	    Elf64_Shdr **pshdr)
 581  {
 582  	struct parsed_elf pelf;
 583  	int flags;
 584  
 585  	flags = ELF_PARSE_PHDR;
 586  
 587  	if (pshdr != NULL)
 588  		flags |= ELF_PARSE_SHDR;
 589  
 590  	if (parse_elf(pinput, &pelf, flags))
 591  		return -1;
 592  
 593  	/* Copy out the parsed elf header. */
 594  	memcpy(ehdr, &pelf.ehdr, sizeof(*ehdr));
 595  
 596  	*pphdr = calloc(ehdr->e_phnum, sizeof(Elf64_Phdr));
 597  	memcpy(*pphdr, pelf.phdr, ehdr->e_phnum * sizeof(Elf64_Phdr));
 598  
 599  	if (pshdr != NULL) {
 600  		*pshdr = calloc(ehdr->e_shnum, sizeof(Elf64_Shdr));
 601  		memcpy(*pshdr, pelf.shdr, ehdr->e_shnum * sizeof(Elf64_Shdr));
 602  	}
 603  
 604  	parsed_elf_destroy(&pelf);
 605  
 606  	return 0;
 607  }
 608  
 609  /* ELF Writing  Support
 610   *
 611   * The ELF file is written according to the following layout:
 612   * +------------------+
 613   * |    ELF Header    |
 614   * +------------------+
 615   * | Section  Headers |
 616   * +------------------+
 617   * | Program  Headers |
 618   * +------------------+
 619   * |   String table   |
 620   * +------------------+ <- 4KiB Aligned
 621   * |     Code/Data    |
 622   * +------------------+
 623   */
 624  
 625  void elf_init_eheader(Elf64_Ehdr *ehdr, int machine, int nbits, int endian)
 626  {
 627  	memset(ehdr, 0, sizeof(*ehdr));
 628  	ehdr->e_ident[EI_MAG0] = ELFMAG0;
 629  	ehdr->e_ident[EI_MAG1] = ELFMAG1;
 630  	ehdr->e_ident[EI_MAG2] = ELFMAG2;
 631  	ehdr->e_ident[EI_MAG3] = ELFMAG3;
 632  	ehdr->e_ident[EI_CLASS] = nbits;
 633  	ehdr->e_ident[EI_DATA] = endian;
 634  	ehdr->e_ident[EI_VERSION] = EV_CURRENT;
 635  	ehdr->e_type = ET_EXEC;
 636  	ehdr->e_machine = machine;
 637  	ehdr->e_version = EV_CURRENT;
 638  	if (nbits == ELFCLASS64) {
 639  		ehdr->e_ehsize = sizeof(Elf64_Ehdr);
 640  		ehdr->e_phentsize = sizeof(Elf64_Phdr);
 641  		ehdr->e_shentsize = sizeof(Elf64_Shdr);
 642  	} else {
 643  		ehdr->e_ehsize = sizeof(Elf32_Ehdr);
 644  		ehdr->e_phentsize = sizeof(Elf32_Phdr);
 645  		ehdr->e_shentsize = sizeof(Elf32_Shdr);
 646  	}
 647  }
 648  
 649  /* Arbitrary maximum number of sections. */
 650  #define MAX_SECTIONS 16
 651  struct elf_writer_section {
 652  	Elf64_Shdr shdr;
 653  	struct buffer content;
 654  	const char *name;
 655  };
 656  
 657  struct elf_writer_string_table {
 658  	size_t next_offset;
 659  	size_t max_size;
 660  	char *buffer;
 661  };
 662  
 663  struct elf_writer_sym_table {
 664  	size_t max_entries;
 665  	size_t num_entries;
 666  	Elf64_Sym *syms;
 667  };
 668  
 669  #define MAX_REL_NAME 32
 670  struct elf_writer_rel {
 671  	size_t num_entries;
 672  	size_t max_entries;
 673  	Elf64_Rel *rels;
 674  	struct elf_writer_section *sec;
 675  	char name[MAX_REL_NAME];
 676  };
 677  
 678  struct elf_writer
 679  {
 680  	Elf64_Ehdr ehdr;
 681  	struct xdr *xdr;
 682  	size_t num_secs;
 683  	struct elf_writer_section sections[MAX_SECTIONS];
 684  	struct elf_writer_rel rel_sections[MAX_SECTIONS];
 685  	Elf64_Phdr *phdrs;
 686  	struct elf_writer_section *shstrtab_sec;
 687  	struct elf_writer_section *strtab_sec;
 688  	struct elf_writer_section *symtab_sec;
 689  	struct elf_writer_string_table strtab;
 690  	struct elf_writer_sym_table symtab;
 691  	int bit64;
 692  };
 693  
 694  static size_t section_index(struct elf_writer *ew,
 695  					struct elf_writer_section *sec)
 696  {
 697  	return sec - &ew->sections[0];
 698  }
 699  
 700  static struct elf_writer_section *last_section(struct elf_writer *ew)
 701  {
 702  	return &ew->sections[ew->num_secs - 1];
 703  }
 704  
 705  static void strtab_init(struct elf_writer *ew, size_t size)
 706  {
 707  	struct buffer b;
 708  	Elf64_Shdr shdr;
 709  
 710  	/* Start adding strings after the initial NUL entry. */
 711  	ew->strtab.next_offset = 1;
 712  	ew->strtab.max_size = size;
 713  	ew->strtab.buffer = calloc(1, ew->strtab.max_size);
 714  
 715  	buffer_init(&b, NULL, ew->strtab.buffer, ew->strtab.max_size);
 716  	memset(&shdr, 0, sizeof(shdr));
 717  	shdr.sh_type = SHT_STRTAB;
 718  	shdr.sh_addralign = 1;
 719  	shdr.sh_size = ew->strtab.max_size;
 720  	elf_writer_add_section(ew, &shdr, &b, ".strtab");
 721  	ew->strtab_sec = last_section(ew);
 722  }
 723  
 724  static void symtab_init(struct elf_writer *ew, size_t max_entries)
 725  {
 726  	struct buffer b;
 727  	Elf64_Shdr shdr;
 728  
 729  	memset(&shdr, 0, sizeof(shdr));
 730  	shdr.sh_type = SHT_SYMTAB;
 731  
 732  	if (ew->bit64) {
 733  		shdr.sh_entsize = sizeof(Elf64_Sym);
 734  		shdr.sh_addralign = sizeof(Elf64_Addr);
 735  	} else {
 736  		shdr.sh_entsize = sizeof(Elf32_Sym);
 737  		shdr.sh_addralign = sizeof(Elf32_Addr);
 738  	}
 739  
 740  	shdr.sh_size = shdr.sh_entsize * max_entries;
 741  
 742  	ew->symtab.syms = calloc(max_entries, sizeof(Elf64_Sym));
 743  	ew->symtab.num_entries = 1;
 744  	ew->symtab.max_entries = max_entries;
 745  
 746  	buffer_init(&b, NULL, ew->symtab.syms, shdr.sh_size);
 747  
 748  	elf_writer_add_section(ew, &shdr, &b, ".symtab");
 749  	ew->symtab_sec = last_section(ew);
 750  }
 751  
 752  struct elf_writer *elf_writer_init(const Elf64_Ehdr *ehdr)
 753  {
 754  	struct elf_writer *ew;
 755  	Elf64_Shdr shdr;
 756  	struct buffer empty_buffer;
 757  
 758  	if (!iself(ehdr))
 759  		return NULL;
 760  
 761  	ew = calloc(1, sizeof(*ew));
 762  
 763  	memcpy(&ew->ehdr, ehdr, sizeof(ew->ehdr));
 764  
 765  	ew->bit64 = ew->ehdr.e_ident[EI_CLASS] == ELFCLASS64;
 766  
 767  	/* Set the endinan ops. */
 768  	if (ew->ehdr.e_ident[EI_DATA] == ELFDATA2MSB)
 769  		ew->xdr = &xdr_be;
 770  	else
 771  		ew->xdr = &xdr_le;
 772  
 773  	/* Reset count and offsets */
 774  	ew->ehdr.e_phoff = 0;
 775  	ew->ehdr.e_shoff = 0;
 776  	ew->ehdr.e_shnum = 0;
 777  	ew->ehdr.e_phnum = 0;
 778  
 779  	memset(&empty_buffer, 0, sizeof(empty_buffer));
 780  	memset(&shdr, 0, sizeof(shdr));
 781  
 782  	/* Add SHT_NULL section header. */
 783  	shdr.sh_type = SHT_NULL;
 784  	elf_writer_add_section(ew, &shdr, &empty_buffer, NULL);
 785  
 786  	/* Add section header string table and maintain reference to it.  */
 787  	shdr.sh_type = SHT_STRTAB;
 788  	elf_writer_add_section(ew, &shdr, &empty_buffer, ".shstrtab");
 789  	ew->shstrtab_sec = last_section(ew);
 790  	ew->ehdr.e_shstrndx = section_index(ew, ew->shstrtab_sec);
 791  
 792  	/* Add a small string table and symbol table. */
 793  	strtab_init(ew, 4096);
 794  	symtab_init(ew, 100);
 795  
 796  	return ew;
 797  }
 798  
 799  /*
 800   * Clean up any internal state represented by ew. Aftewards the elf_writer
 801   * is invalid.
 802   * It is safe to call elf_writer_destroy with ew as NULL. It returns without
 803   * performing any action.
 804   */
 805  void elf_writer_destroy(struct elf_writer *ew)
 806  {
 807  	int i;
 808  	if (ew == NULL)
 809  		return;
 810  	if (ew->phdrs != NULL)
 811  		free(ew->phdrs);
 812  	free(ew->strtab.buffer);
 813  	free(ew->symtab.syms);
 814  	for (i = 0; i < MAX_SECTIONS; i++)
 815  		free(ew->rel_sections[i].rels);
 816  	free(ew);
 817  }
 818  
 819  /*
 820   * Add a section to the ELF file. Section type, flags, and memsize are
 821   * maintained from the passed in Elf64_Shdr. The buffer represents the
 822   * content of the section while the name is the name of section itself.
 823   * Returns < 0 on error, 0 on success.
 824   */
 825  int elf_writer_add_section(struct elf_writer *ew, const Elf64_Shdr *shdr,
 826                             struct buffer *contents, const char *name)
 827  {
 828  	struct elf_writer_section *newsh;
 829  
 830  	if (ew->num_secs == MAX_SECTIONS)
 831  		return -1;
 832  
 833  	newsh = &ew->sections[ew->num_secs];
 834  	ew->num_secs++;
 835  
 836  	memcpy(&newsh->shdr, shdr, sizeof(newsh->shdr));
 837  	newsh->shdr.sh_offset = 0;
 838  
 839  	newsh->name = name;
 840  	if (contents != NULL)
 841  		buffer_clone(&newsh->content, contents);
 842  
 843  	return 0;
 844  }
 845  
 846  static void ehdr_write(struct elf_writer *ew, struct buffer *m)
 847  {
 848  	int i;
 849  
 850  	for (i = 0; i < EI_NIDENT; i++)
 851  		ew->xdr->put8(m, ew->ehdr.e_ident[i]);
 852  	ew->xdr->put16(m, ew->ehdr.e_type);
 853  	ew->xdr->put16(m, ew->ehdr.e_machine);
 854  	ew->xdr->put32(m, ew->ehdr.e_version);
 855  	if (ew->bit64) {
 856  		ew->xdr->put64(m, ew->ehdr.e_entry);
 857  		ew->xdr->put64(m, ew->ehdr.e_phoff);
 858  		ew->xdr->put64(m, ew->ehdr.e_shoff);
 859  	} else {
 860  		ew->xdr->put32(m, ew->ehdr.e_entry);
 861  		ew->xdr->put32(m, ew->ehdr.e_phoff);
 862  		ew->xdr->put32(m, ew->ehdr.e_shoff);
 863  	}
 864  	ew->xdr->put32(m, ew->ehdr.e_flags);
 865  	ew->xdr->put16(m, ew->ehdr.e_ehsize);
 866  	ew->xdr->put16(m, ew->ehdr.e_phentsize);
 867  	ew->xdr->put16(m, ew->ehdr.e_phnum);
 868  	ew->xdr->put16(m, ew->ehdr.e_shentsize);
 869  	ew->xdr->put16(m, ew->ehdr.e_shnum);
 870  	ew->xdr->put16(m, ew->ehdr.e_shstrndx);
 871  }
 872  
 873  static void shdr_write(struct elf_writer *ew, size_t n, struct buffer *m)
 874  {
 875  	struct xdr *xdr = ew->xdr;
 876  	int bit64 = ew->bit64;
 877  	struct elf_writer_section *sec = &ew->sections[n];
 878  	Elf64_Shdr *shdr = &sec->shdr;
 879  
 880  	xdr->put32(m, shdr->sh_name);
 881  	xdr->put32(m, shdr->sh_type);
 882  	if (bit64) {
 883  		xdr->put64(m, shdr->sh_flags);
 884  		xdr->put64(m, shdr->sh_addr);
 885  		xdr->put64(m, shdr->sh_offset);
 886  		xdr->put64(m, shdr->sh_size);
 887  		xdr->put32(m, shdr->sh_link);
 888  		xdr->put32(m, shdr->sh_info);
 889  		xdr->put64(m, shdr->sh_addralign);
 890  		xdr->put64(m, shdr->sh_entsize);
 891  	} else {
 892  		xdr->put32(m, shdr->sh_flags);
 893  		xdr->put32(m, shdr->sh_addr);
 894  		xdr->put32(m, shdr->sh_offset);
 895  		xdr->put32(m, shdr->sh_size);
 896  		xdr->put32(m, shdr->sh_link);
 897  		xdr->put32(m, shdr->sh_info);
 898  		xdr->put32(m, shdr->sh_addralign);
 899  		xdr->put32(m, shdr->sh_entsize);
 900  	}
 901  }
 902  
 903  static void
 904  phdr_write(struct elf_writer *ew, struct buffer *m, Elf64_Phdr *phdr)
 905  {
 906  	if (ew->bit64) {
 907  		ew->xdr->put32(m, phdr->p_type);
 908  		ew->xdr->put32(m, phdr->p_flags);
 909  		ew->xdr->put64(m, phdr->p_offset);
 910  		ew->xdr->put64(m, phdr->p_vaddr);
 911  		ew->xdr->put64(m, phdr->p_paddr);
 912  		ew->xdr->put64(m, phdr->p_filesz);
 913  		ew->xdr->put64(m, phdr->p_memsz);
 914  		ew->xdr->put64(m, phdr->p_align);
 915  	} else {
 916  		ew->xdr->put32(m, phdr->p_type);
 917  		ew->xdr->put32(m, phdr->p_offset);
 918  		ew->xdr->put32(m, phdr->p_vaddr);
 919  		ew->xdr->put32(m, phdr->p_paddr);
 920  		ew->xdr->put32(m, phdr->p_filesz);
 921  		ew->xdr->put32(m, phdr->p_memsz);
 922  		ew->xdr->put32(m, phdr->p_flags);
 923  		ew->xdr->put32(m, phdr->p_align);
 924  	}
 925  
 926  }
 927  
 928  static int section_consecutive(struct elf_writer *ew, Elf64_Half secidx)
 929  {
 930  	Elf64_Half i;
 931  	struct elf_writer_section *prev_alloc = NULL;
 932  
 933  	if (secidx == 0)
 934  		return 0;
 935  
 936  	for (i = 0; i < secidx; i++) {
 937  		if (ew->sections[i].shdr.sh_flags & SHF_ALLOC)
 938  			prev_alloc = &ew->sections[i];
 939  	}
 940  
 941  	if (prev_alloc == NULL)
 942  		return 0;
 943  
 944  	if (prev_alloc->shdr.sh_addr + prev_alloc->shdr.sh_size ==
 945  	    ew->sections[secidx].shdr.sh_addr)
 946  		return 1;
 947  
 948  	return 0;
 949  }
 950  
 951  static void write_phdrs(struct elf_writer *ew, struct buffer *phdrs)
 952  {
 953  	Elf64_Half i;
 954  	Elf64_Phdr phdr;
 955  	size_t num_written = 0;
 956  	size_t num_needs_write = 0;
 957  
 958  	for (i = 0; i < ew->num_secs; i++) {
 959  		struct elf_writer_section *sec = &ew->sections[i];
 960  
 961  		if (!(sec->shdr.sh_flags & SHF_ALLOC))
 962  			continue;
 963  
 964  		if (!section_consecutive(ew, i)) {
 965  			/* Write out previously set phdr. */
 966  			if (num_needs_write != num_written) {
 967  				phdr_write(ew, phdrs, &phdr);
 968  				num_written++;
 969  			}
 970  			phdr.p_type = PT_LOAD;
 971  			phdr.p_offset = sec->shdr.sh_offset;
 972  			phdr.p_vaddr = sec->shdr.sh_addr;
 973  			phdr.p_paddr = sec->shdr.sh_addr;
 974  			phdr.p_filesz = buffer_size(&sec->content);
 975  			phdr.p_memsz = sec->shdr.sh_size;
 976  			phdr.p_flags = 0;
 977  			if (sec->shdr.sh_flags & SHF_EXECINSTR)
 978  				phdr.p_flags |= PF_X | PF_R;
 979  			if (sec->shdr.sh_flags & SHF_WRITE)
 980  				phdr.p_flags |= PF_W;
 981  			phdr.p_align = sec->shdr.sh_addralign;
 982  			num_needs_write++;
 983  
 984  		} else {
 985  			/* Accumulate file size and memsize. The assumption
 986  			 * is that each section is either NOBITS or full
 987  			 * (sh_size == file size). This is standard in that
 988  			 * an ELF section doesn't have a file size component. */
 989  			if (sec->shdr.sh_flags & SHF_EXECINSTR)
 990  				phdr.p_flags |= PF_X | PF_R;
 991  			if (sec->shdr.sh_flags & SHF_WRITE)
 992  				phdr.p_flags |= PF_W;
 993  			phdr.p_filesz += buffer_size(&sec->content);
 994  			phdr.p_memsz += sec->shdr.sh_size;
 995  		}
 996  	}
 997  
 998  	/* Write out the last phdr. */
 999  	if (num_needs_write != num_written) {
1000  		phdr_write(ew, phdrs, &phdr);
1001  		num_written++;
1002  	}
1003  	assert(num_written == ew->ehdr.e_phnum);
1004  }
1005  
1006  static void fixup_symbol_table(struct elf_writer *ew)
1007  {
1008  	struct elf_writer_section *sec = ew->symtab_sec;
1009  
1010  	/* If there is only the NULL section, mark section as inactive. */
1011  	if (ew->symtab.num_entries == 1) {
1012  		sec->shdr.sh_type = SHT_NULL;
1013  		sec->shdr.sh_size = 0;
1014  	} else {
1015  		size_t i;
1016  		struct buffer wr;
1017  
1018  		buffer_clone(&wr, &sec->content);
1019  		/* To appease xdr. */
1020  		buffer_set_size(&wr, 0);
1021  		for (i = 0; i < ew->symtab.num_entries; i++) {
1022  			/* Create local copy as were over-writing backing
1023  			 * store of the symbol. */
1024  			Elf64_Sym sym = ew->symtab.syms[i];
1025  			if (ew->bit64) {
1026  				ew->xdr->put32(&wr, sym.st_name);
1027  				ew->xdr->put8(&wr, sym.st_info);
1028  				ew->xdr->put8(&wr, sym.st_other);
1029  				ew->xdr->put16(&wr, sym.st_shndx);
1030  				ew->xdr->put64(&wr, sym.st_value);
1031  				ew->xdr->put64(&wr, sym.st_size);
1032  			} else {
1033  				ew->xdr->put32(&wr, sym.st_name);
1034  				ew->xdr->put32(&wr, sym.st_value);
1035  				ew->xdr->put32(&wr, sym.st_size);
1036  				ew->xdr->put8(&wr, sym.st_info);
1037  				ew->xdr->put8(&wr, sym.st_other);
1038  				ew->xdr->put16(&wr, sym.st_shndx);
1039  			}
1040  		}
1041  
1042  		/* Update section size. */
1043  		sec->shdr.sh_size = sec->shdr.sh_entsize;
1044  		sec->shdr.sh_size *= ew->symtab.num_entries;
1045  
1046  		/* Fix up sh_link to point to string table. */
1047  		sec->shdr.sh_link = section_index(ew, ew->strtab_sec);
1048  		/* sh_info is supposed to be 1 greater than symbol table
1049  		 * index of last local binding. Just use max symbols. */
1050  		sec->shdr.sh_info = ew->symtab.num_entries;
1051  	}
1052  
1053  	buffer_set_size(&sec->content, sec->shdr.sh_size);
1054  }
1055  
1056  static void fixup_relocations(struct elf_writer *ew)
1057  {
1058  	int i;
1059  	Elf64_Xword type;
1060  
1061  	switch (ew->ehdr.e_machine) {
1062  	case EM_386:
1063  		type = R_386_32;
1064  		break;
1065  	case EM_X86_64:
1066  		type =  R_AMD64_64;
1067  		break;
1068  	case EM_ARM:
1069  		type = R_ARM_ABS32;
1070  		break;
1071  	case EM_AARCH64:
1072  		type = R_AARCH64_ABS64;
1073  		break;
1074  	case EM_MIPS:
1075  		type = R_MIPS_32;
1076  		break;
1077  	case EM_RISCV:
1078  		type = R_RISCV_32;
1079  		break;
1080  	case EM_PPC64:
1081  		type = R_PPC64_ADDR32;
1082  		break;
1083  	default:
1084  		ERROR("Unable to handle relocations for e_machine %x\n",
1085  			ew->ehdr.e_machine);
1086  		return;
1087  	}
1088  
1089  	for (i = 0; i < MAX_SECTIONS; i++) {
1090  		struct elf_writer_rel *rel_sec = &ew->rel_sections[i];
1091  		struct elf_writer_section *sec = rel_sec->sec;
1092  		struct buffer writer;
1093  		size_t j;
1094  
1095  		if (sec == NULL)
1096  			continue;
1097  
1098  		/* Update section header size as well as content size. */
1099  		buffer_init(&sec->content, sec->content.name, rel_sec->rels,
1100  				rel_sec->num_entries * sec->shdr.sh_entsize);
1101  		sec->shdr.sh_size = buffer_size(&sec->content);
1102  		buffer_clone(&writer, &sec->content);
1103  		/* To make xdr happy. */
1104  		buffer_set_size(&writer, 0);
1105  
1106  		for (j = 0; j < ew->rel_sections[i].num_entries; j++) {
1107  			/* Make copy as we're overwriting backing store. */
1108  			Elf64_Rel rel = rel_sec->rels[j];
1109  			rel.r_info = ELF64_R_INFO(ELF64_R_SYM(rel.r_info),
1110  						  ELF64_R_TYPE(type));
1111  
1112  			if (ew->bit64) {
1113  				ew->xdr->put64(&writer, rel.r_offset);
1114  				ew->xdr->put64(&writer, rel.r_info);
1115  			} else {
1116  				Elf32_Rel rel32;
1117  				rel32.r_offset = rel.r_offset;
1118  				rel32.r_info =
1119  					ELF32_R_INFO(ELF64_R_SYM(rel.r_info),
1120  						     ELF64_R_TYPE(rel.r_info));
1121  				ew->xdr->put32(&writer, rel32.r_offset);
1122  				ew->xdr->put32(&writer, rel32.r_info);
1123  			}
1124  		}
1125  	}
1126  }
1127  
1128  /*
1129   * Serialize the ELF file to the output buffer. Return < 0 on error,
1130   * 0 on success.
1131   */
1132  int elf_writer_serialize(struct elf_writer *ew, struct buffer *out)
1133  {
1134  	Elf64_Half i;
1135  	Elf64_Xword metadata_size;
1136  	Elf64_Xword program_size;
1137  	Elf64_Off shstroffset;
1138  	size_t shstrlen;
1139  	struct buffer metadata;
1140  	struct buffer phdrs;
1141  	struct buffer data;
1142  	struct buffer *strtab;
1143  
1144  	INFO("Writing %zu sections.\n", ew->num_secs);
1145  
1146  	/* Perform any necessary work for special sections. */
1147  	fixup_symbol_table(ew);
1148  	fixup_relocations(ew);
1149  
1150  	/* Determine size of sections to be written. */
1151  	program_size = 0;
1152  	/* Start with 1 byte for first byte of section header string table. */
1153  	shstrlen = 1;
1154  	for (i = 0; i < ew->num_secs; i++) {
1155  		struct elf_writer_section *sec = &ew->sections[i];
1156  
1157  		if (sec->shdr.sh_flags & SHF_ALLOC) {
1158  			if (!section_consecutive(ew, i))
1159  				ew->ehdr.e_phnum++;
1160  		}
1161  
1162  		program_size += buffer_size(&sec->content);
1163  
1164  		/* Keep track of the length sections' names. */
1165  		if (sec->name != NULL) {
1166  			sec->shdr.sh_name = shstrlen;
1167  			shstrlen += strlen(sec->name) + 1;
1168  		}
1169  	}
1170  	ew->ehdr.e_shnum = ew->num_secs;
1171  	metadata_size = 0;
1172  	metadata_size += ew->ehdr.e_ehsize;
1173  	metadata_size += (Elf64_Xword)ew->ehdr.e_shnum * ew->ehdr.e_shentsize;
1174  	metadata_size += (Elf64_Xword)ew->ehdr.e_phnum * ew->ehdr.e_phentsize;
1175  	shstroffset = metadata_size;
1176  	/* Align up section header string size and metadata size to 4KiB */
1177  	metadata_size = ALIGN_UP(metadata_size + shstrlen, 4096);
1178  
1179  	if (buffer_create(out, metadata_size + program_size, "elfout")) {
1180  		ERROR("Could not create output buffer for ELF.\n");
1181  		return -1;
1182  	}
1183  
1184  	INFO("Created %zu output buffer for ELF file.\n", buffer_size(out));
1185  
1186  	/*
1187  	 * Write out ELF header. Section headers come right after ELF header
1188  	 * followed by the program headers. Buffers need to be created first
1189  	 * to do the writing.
1190  	 */
1191  	ew->ehdr.e_shoff = ew->ehdr.e_ehsize;
1192  	ew->ehdr.e_phoff = ew->ehdr.e_shoff +
1193  			   (Elf64_Off)ew->ehdr.e_shnum * ew->ehdr.e_shentsize;
1194  
1195  	buffer_splice(&metadata, out, 0, metadata_size);
1196  	buffer_splice(&phdrs, out, ew->ehdr.e_phoff,
1197  		      (uint32_t)ew->ehdr.e_phnum * ew->ehdr.e_phentsize);
1198  	buffer_splice(&data, out, metadata_size, program_size);
1199  	/* Set up the section header string table contents. */
1200  	strtab = &ew->shstrtab_sec->content;
1201  	buffer_splice(strtab, out, shstroffset, shstrlen);
1202  	ew->shstrtab_sec->shdr.sh_size = shstrlen;
1203  
1204  	/* Reset current locations. */
1205  	buffer_set_size(&metadata, 0);
1206  	buffer_set_size(&data, 0);
1207  	buffer_set_size(&phdrs, 0);
1208  	buffer_set_size(strtab, 0);
1209  
1210  	/* ELF Header */
1211  	ehdr_write(ew, &metadata);
1212  
1213  	/* Write out section headers, section strings, section content, and
1214  	 * program headers. */
1215  	ew->xdr->put8(strtab, 0);
1216  	for (i = 0; i < ew->num_secs; i++) {
1217  		struct elf_writer_section *sec = &ew->sections[i];
1218  
1219  		/* Update section offsets. Be sure to not update SHN_UNDEF. */
1220  		if (sec == ew->shstrtab_sec)
1221  			sec->shdr.sh_offset = shstroffset;
1222  		else if (i != SHN_UNDEF)
1223  			sec->shdr.sh_offset = buffer_size(&data) +
1224  			                      metadata_size;
1225  
1226  		shdr_write(ew, i, &metadata);
1227  
1228  		/* Add section name to string table. */
1229  		if (sec->name != NULL)
1230  			bputs(strtab, sec->name, strlen(sec->name) + 1);
1231  
1232  		/* Output section data for all sections but SHN_UNDEF and
1233  		 * section header string table. */
1234  		if (i != SHN_UNDEF && sec != ew->shstrtab_sec)
1235  			bputs(&data, buffer_get(&sec->content),
1236  			      buffer_size(&sec->content));
1237  	}
1238  
1239  	write_phdrs(ew, &phdrs);
1240  
1241  	return 0;
1242  }
1243  
1244  /* Add a string to the string table returning index on success, < 0 on error. */
1245  static int elf_writer_add_string(struct elf_writer *ew, const char *new)
1246  {
1247  	size_t current_offset;
1248  	size_t new_len;
1249  
1250  	for (current_offset = 0; current_offset < ew->strtab.next_offset; ) {
1251  		const char *str = ew->strtab.buffer + current_offset;
1252  		size_t len = strlen(str) + 1;
1253  
1254  		if (!strcmp(str, new))
1255  			return current_offset;
1256  		current_offset += len;
1257  	}
1258  
1259  	new_len = strlen(new) + 1;
1260  
1261  	if (current_offset + new_len > ew->strtab.max_size) {
1262  		ERROR("No space for string in .strtab.\n");
1263  		return -1;
1264  	}
1265  
1266  	memcpy(ew->strtab.buffer + current_offset, new, new_len);
1267  	ew->strtab.next_offset = current_offset + new_len;
1268  
1269  	return current_offset;
1270  }
1271  
1272  static int elf_writer_section_index(struct elf_writer *ew, const char *name)
1273  {
1274  	size_t i;
1275  
1276  	for (i = 0; i < ew->num_secs; i++) {
1277  		if (ew->sections[i].name == NULL)
1278  			continue;
1279  		if (!strcmp(ew->sections[i].name, name))
1280  			return i;
1281  	}
1282  
1283  	ERROR("ELF Section not found: %s\n", name);
1284  
1285  	return -1;
1286  }
1287  
1288  int elf_writer_add_symbol(struct elf_writer *ew, const char *name,
1289  				const char *section_name,
1290  				Elf64_Addr value, Elf64_Word size,
1291  				int binding, int type)
1292  {
1293  	int i;
1294  	Elf64_Sym sym = {
1295  		.st_value = value,
1296  		.st_size = size,
1297  		.st_info = ELF64_ST_INFO(binding, type),
1298  	};
1299  
1300  	if (ew->symtab.max_entries == ew->symtab.num_entries) {
1301  		ERROR("No more symbol entries left.\n");
1302  		return -1;
1303  	}
1304  
1305  	i = elf_writer_add_string(ew, name);
1306  	if (i < 0)
1307  		return -1;
1308  	sym.st_name = i;
1309  
1310  	i = elf_writer_section_index(ew, section_name);
1311  	if (i < 0)
1312  		return -1;
1313  	sym.st_shndx = i;
1314  
1315  	ew->symtab.syms[ew->symtab.num_entries++] = sym;
1316  
1317  	return 0;
1318  }
1319  
1320  static int elf_sym_index(struct elf_writer *ew, const char *sym)
1321  {
1322  	int j;
1323  	size_t i;
1324  	Elf64_Word st_name;
1325  
1326  	/* Determine index of symbol in the string table. */
1327  	j = elf_writer_add_string(ew, sym);
1328  	if (j < 0)
1329  		return -1;
1330  
1331  	st_name = j;
1332  
1333  	for (i = 0; i < ew->symtab.num_entries; i++)
1334  		if (ew->symtab.syms[i].st_name == st_name)
1335  			return i;
1336  
1337  	return -1;
1338  }
1339  
1340  static struct elf_writer_rel *rel_section(struct elf_writer *ew,
1341  						const Elf64_Rel *r)
1342  {
1343  	Elf64_Sym *sym;
1344  	struct elf_writer_rel *rel;
1345  	Elf64_Shdr shdr;
1346  	struct buffer b;
1347  
1348  	sym = &ew->symtab.syms[ELF64_R_SYM(r->r_info)];
1349  
1350  	/* Determine if section has been initialized yet. */
1351  	rel = &ew->rel_sections[sym->st_shndx];
1352  	if (rel->sec != NULL)
1353  		return rel;
1354  
1355  	memset(&shdr, 0, sizeof(shdr));
1356  	shdr.sh_type = SHT_REL;
1357  	shdr.sh_link = section_index(ew, ew->symtab_sec);
1358  	shdr.sh_info = sym->st_shndx;
1359  
1360  	if (ew->bit64) {
1361  		shdr.sh_addralign = sizeof(Elf64_Addr);
1362  		shdr.sh_entsize = sizeof(Elf64_Rel);
1363  	} else {
1364  		shdr.sh_addralign = sizeof(Elf32_Addr);
1365  		shdr.sh_entsize = sizeof(Elf32_Rel);
1366  	}
1367  
1368  	if ((strlen(".rel") + strlen(ew->sections[sym->st_shndx].name) + 1) >
1369  	    MAX_REL_NAME) {
1370  		ERROR("Rel Section name won't fit\n");
1371  		return NULL;
1372  	}
1373  
1374  	strcat(rel->name, ".rel");
1375  	strcat(rel->name, ew->sections[sym->st_shndx].name);
1376  	buffer_init(&b, rel->name, NULL, 0);
1377  
1378  	elf_writer_add_section(ew, &shdr, &b, rel->name);
1379  	rel->sec = last_section(ew);
1380  
1381  	return rel;
1382  }
1383  
1384  static int add_rel(struct elf_writer_rel *rel_sec, const Elf64_Rel *rel)
1385  {
1386  	if (rel_sec->num_entries == rel_sec->max_entries) {
1387  		size_t num = rel_sec->max_entries * 2;
1388  		Elf64_Rel *old_rels;
1389  
1390  		if (num == 0)
1391  			num = 128;
1392  
1393  		old_rels = rel_sec->rels;
1394  		rel_sec->rels = calloc(num, sizeof(Elf64_Rel));
1395  
1396  		memcpy(rel_sec->rels, old_rels,
1397  			rel_sec->num_entries * sizeof(Elf64_Rel));
1398  		free(old_rels);
1399  
1400  		rel_sec->max_entries = num;
1401  	}
1402  
1403  	rel_sec->rels[rel_sec->num_entries] = *rel;
1404  	rel_sec->num_entries++;
1405  
1406  	return 0;
1407  }
1408  
1409  int elf_writer_add_rel(struct elf_writer *ew, const char *sym, Elf64_Addr addr)
1410  {
1411  	Elf64_Rel rel;
1412  	Elf64_Xword sym_info;
1413  	int sym_index;
1414  	struct elf_writer_rel *rel_sec;
1415  
1416  	sym_index = elf_sym_index(ew, sym);
1417  
1418  	if (sym_index < 0) {
1419  		ERROR("Unable to locate symbol: %s\n", sym);
1420  		return -1;
1421  	}
1422  
1423  	sym_info = sym_index;
1424  
1425  	/* The relocation type will get fixed prior to serialization. */
1426  	rel.r_offset = addr;
1427  	rel.r_info = ELF64_R_INFO(sym_info, 0);
1428  
1429  	rel_sec = rel_section(ew, &rel);
1430  
1431  	if (rel_sec == NULL)
1432  		return -1;
1433  
1434  	return add_rel(rel_sec, &rel);
1435  }
1436  
1437  int elf_program_file_size_align(const struct buffer *input, size_t *file_size, size_t *align)
1438  {
1439  	Elf64_Ehdr ehdr;
1440  	Elf64_Phdr *phdr;
1441  	int i;
1442  	size_t loadable_file_size = 0;
1443  	size_t align_size = 0;
1444  
1445  	if (elf_headers(input, &ehdr, &phdr, NULL))
1446  		return -1;
1447  
1448  	for (i = 0; i < ehdr.e_phnum; i++) {
1449  		if (phdr[i].p_type != PT_LOAD)
1450  			continue;
1451  		loadable_file_size += phdr[i].p_filesz;
1452  		align_size = MAX(align_size, phdr[i].p_align);
1453  	}
1454  
1455  	*file_size = loadable_file_size;
1456  	*align = align_size;
1457  
1458  	free(phdr);
1459  
1460  	return 0;
1461  }