2722387f30847b828b57ba9ca59d2b47ee9244ecrie/*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * CDDL HEADER START
2722387f30847b828b57ba9ca59d2b47ee9244ecrie *
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * The contents of this file are subject to the terms of the
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Common Development and Distribution License (the "License").
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * You may not use this file except in compliance with the License.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie *
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * or http://www.opensolaris.org/os/licensing.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * See the License for the specific language governing permissions
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * and limitations under the License.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie *
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * When distributing Covered Code, include this CDDL HEADER in each
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * If applicable, add the following below this CDDL HEADER, with the
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * fields enclosed by brackets "[]" replaced with your own identifying
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * information: Portions Copyright [yyyy] [name of copyright owner]
2722387f30847b828b57ba9ca59d2b47ee9244ecrie *
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * CDDL HEADER END
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie/*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Use is subject to license terms.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#pragma ident "%Z%%M% %I% %E% SMI"
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#include <sys/types.h>
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#include <sys/stat.h>
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#include <sys/mman.h>
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#include <unistd.h>
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#include <fcntl.h>
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#include <libgen.h>
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#include <errno.h>
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#include <libelf.h>
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#include <stdio.h>
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#include <strings.h>
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#include <msg.h>
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#include <machdep.h>
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#include <_libelf.h>
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#include <_elfwrap.h>
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie/*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * This module is compiled to support 32-bit and 64-bit class objects. Define
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * the necessary interfaces for these classes.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#if defined(_ELF64)
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#define input input64
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#define output output64
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#else
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#define input input32
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#define output output32
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#endif
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecriestatic StdSec_t StdSecs[] = {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie { MSG_ORIG(MSG_SCN_SYMTAB), SHT_SYMTAB, 0 },
2722387f30847b828b57ba9ca59d2b47ee9244ecrie { MSG_ORIG(MSG_SCN_STRTAB), SHT_STRTAB, SHF_STRINGS},
2722387f30847b828b57ba9ca59d2b47ee9244ecrie { MSG_ORIG(MSG_SCN_SHSTRTAB), SHT_STRTAB, SHF_STRINGS},
2722387f30847b828b57ba9ca59d2b47ee9244ecrie { NULL, 0, 0 }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie};
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie/*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Process all input files. These contain the data that will be assigned to a
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * new ELF section.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrieint
2722387f30847b828b57ba9ca59d2b47ee9244ecrieinput(int argc, char **argv, const char *prog, const char *ofile,
2722387f30847b828b57ba9ca59d2b47ee9244ecrie ObjDesc_t *odp)
2722387f30847b828b57ba9ca59d2b47ee9244ecrie{
2722387f30847b828b57ba9ca59d2b47ee9244ecrie OutSec_t outsec;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie StdSec_t *stdsecs;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie size_t ndx, cnt;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie int ret = 0, fd = -1;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Make sure we have access to read each input file, and prepare an
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * output section descriptor for each. Note, we assign section indexes
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * starting at 1, as section index 0 is special, and is created by
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * libelf.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie for (ndx = 1; argc; argc--, argv++, ndx++) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie char *file = *argv;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie struct stat status;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie size_t namesz;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Close any previously opened file.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if (fd != -1)
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) close(fd);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Identify the section.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie outsec.os_name = basename(file);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie outsec.os_type = SHT_PROGBITS;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie outsec.os_flags = SHF_ALLOC;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie outsec.os_ndx = ndx;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if ((fd = open(file, O_RDONLY)) == -1) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie int err = errno;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) fprintf(stderr, MSG_INTL(MSG_ERR_OPEN),
2722387f30847b828b57ba9ca59d2b47ee9244ecrie prog, file, strerror(err));
2722387f30847b828b57ba9ca59d2b47ee9244ecrie ret = 1;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie continue;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if (fstat(fd, &status) == -1) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie int err = errno;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) fprintf(stderr, MSG_INTL(MSG_ERR_FSTAT),
2722387f30847b828b57ba9ca59d2b47ee9244ecrie prog, file, strerror(err));
2722387f30847b828b57ba9ca59d2b47ee9244ecrie ret = 1;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie continue;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if ((outsec.os_size = status.st_size) == 0) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) fprintf(stderr, MSG_INTL(MSG_WARN_ZERO),
2722387f30847b828b57ba9ca59d2b47ee9244ecrie prog, file);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie continue;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if ((outsec.os_addr = mmap(0, outsec.os_size, PROT_READ,
2722387f30847b828b57ba9ca59d2b47ee9244ecrie MAP_PRIVATE, fd, 0)) == MAP_FAILED) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie int err = errno;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) fprintf(stderr, MSG_INTL(MSG_ERR_MMAP),
2722387f30847b828b57ba9ca59d2b47ee9244ecrie prog, file, strerror(err));
2722387f30847b828b57ba9ca59d2b47ee9244ecrie ret = 1;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie continue;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if (alist_append(&(odp->od_outsecs), &outsec, sizeof (OutSec_t),
2722387f30847b828b57ba9ca59d2b47ee9244ecrie AL_CNT_WOSECS) == 0) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie int err = errno;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) fprintf(stderr, MSG_INTL(MSG_ERR_ALLOC),
2722387f30847b828b57ba9ca59d2b47ee9244ecrie prog, file, strerror(err));
2722387f30847b828b57ba9ca59d2b47ee9244ecrie return (1);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Each data section contributes:
2722387f30847b828b57ba9ca59d2b47ee9244ecrie *
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * i. its basename, prefixed with a "dot", to the .shstrtab.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * ii. a section symbol.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * iii. a data symbol, using the basename, with an
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * appended "_data" string.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * iv. a data size symbol, using the basename with an
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * appended "_size" string.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie namesz = strlen(outsec.os_name) + 1;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie odp->od_symtabno += 3;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie odp->od_strtabsz += (namesz + MSG_STR_START_SIZE);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie odp->od_strtabsz += (namesz + MSG_STR_END_SIZE);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie odp->od_shstrtabsz += (namesz + MSG_STR_DOT_SIZE);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if (fd != -1)
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) close(fd);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * If an error occurred, or no input files contributed data, bail now.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if (ret || (odp->od_outsecs == NULL))
2722387f30847b828b57ba9ca59d2b47ee9244ecrie return (1);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Create section descriptors for .symtab, .strtab, and .shstrtab.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie for (cnt = 0, stdsecs = &StdSecs[cnt]; stdsecs->ss_name; cnt++,
2722387f30847b828b57ba9ca59d2b47ee9244ecrie ndx++, stdsecs = &StdSecs[cnt]) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Identify the section.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie outsec.os_name = stdsecs->ss_name;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie outsec.os_type = stdsecs->ss_type;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie outsec.os_flags = stdsecs->ss_flags;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie outsec.os_ndx = ndx;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie outsec.os_size = 0;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie outsec.os_addr = 0;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if (alist_append(&(odp->od_outsecs), &outsec, sizeof (OutSec_t),
2722387f30847b828b57ba9ca59d2b47ee9244ecrie AL_CNT_WOSECS) == 0) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie int err = errno;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) fprintf(stderr, MSG_INTL(MSG_ERR_ALLOC),
2722387f30847b828b57ba9ca59d2b47ee9244ecrie prog, outsec.os_name, strerror(err));
2722387f30847b828b57ba9ca59d2b47ee9244ecrie return (1);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Each standard section contributes:
2722387f30847b828b57ba9ca59d2b47ee9244ecrie *
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * i. its section name to the .shstrtab.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * ii. a section symbol.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie odp->od_symtabno++;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie odp->od_shstrtabsz += (strlen(outsec.os_name) + 1);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * The symbol table requires an initial NULL entry and a following
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * FILE entry. Both string tables require an initial NULL byte.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * The .strtab requires room for the output file name (STT_FILE).
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie odp->od_symtabno += 2;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie odp->od_strtabsz += strlen(ofile) + 2;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie odp->od_shstrtabsz++;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie return (0);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie}
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie/*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Having captured all input data, create the output file.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrieint
2722387f30847b828b57ba9ca59d2b47ee9244ecrieoutput(const char *prog, int fd, const char *ofile, ushort_t mach,
2722387f30847b828b57ba9ca59d2b47ee9244ecrie ObjDesc_t *odp)
2722387f30847b828b57ba9ca59d2b47ee9244ecrie{
2722387f30847b828b57ba9ca59d2b47ee9244ecrie Aliste off;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie Elf *melf, *oelf;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie Ehdr *ehdr;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie Sym *symtab, *secsymtabent, *glbsymtabent;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie char *strtab, *strtabent, *shstrtab, *shstrtabent;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie OutSec_t *outsec, *outsymtab, *outstrtab, *outshstrtab;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie size_t len;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie TargDesc_t tdesc;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Obtain any target specific ELF information.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if (mach == 0)
2722387f30847b828b57ba9ca59d2b47ee9244ecrie mach = M_MACH;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie switch (mach) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#if !defined(lint)
2722387f30847b828b57ba9ca59d2b47ee9244ecrie case EM_SPARC:
2722387f30847b828b57ba9ca59d2b47ee9244ecrie target_init_sparc(&tdesc);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie break;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie case EM_SPARCV9:
2722387f30847b828b57ba9ca59d2b47ee9244ecrie target_init_sparcv9(&tdesc);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie break;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie case EM_386:
2722387f30847b828b57ba9ca59d2b47ee9244ecrie target_init_i386(&tdesc);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie break;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie case EM_AMD64:
2722387f30847b828b57ba9ca59d2b47ee9244ecrie target_init_amd64(&tdesc);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie break;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#else
2722387f30847b828b57ba9ca59d2b47ee9244ecrie default:
2722387f30847b828b57ba9ca59d2b47ee9244ecrie target_init(&tdesc);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie break;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie#endif
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Create a new ELF descriptor for the new output file.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if ((oelf = elf_begin(fd, ELF_C_WRITE, 0)) == NULL) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) fprintf(stderr, MSG_INTL(MSG_ELF_BEGIN), prog,
2722387f30847b828b57ba9ca59d2b47ee9244ecrie elf_errmsg(elf_errno()));
2722387f30847b828b57ba9ca59d2b47ee9244ecrie return (1);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Create and initialize the new ELF header.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if ((ehdr = elf_newehdr(oelf)) == NULL) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) fprintf(stderr, MSG_INTL(MSG_ELF_NEWEHDR), prog,
2722387f30847b828b57ba9ca59d2b47ee9244ecrie elf_errmsg(elf_errno()));
2722387f30847b828b57ba9ca59d2b47ee9244ecrie return (1);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Note, the ELF header is initialized to reflect the host running
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * elfwrap(1) rather than the target. Using host byte order allows
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * elfwrap(1) to create the object data. Prior to the final update,
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * the output ELF header is modified to reflect the target, causing
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * libelf to produce the output object using the correct byte order
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * and other target information.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie ehdr->e_ident[EI_DATA] = M_DATA;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie ehdr->e_type = ET_REL;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie ehdr->e_version = EV_CURRENT;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Create the required number of new sections, their associated section
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * header, and an initial data buffer.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie for (ALIST_TRAVERSE(odp->od_outsecs, off, outsec)) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie Elf_Scn *scn;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie Elf_Data *data;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie Shdr *shdr;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if ((scn = elf_newscn(oelf)) == NULL) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) fprintf(stderr, MSG_INTL(MSG_ELF_NEWSCN),
2722387f30847b828b57ba9ca59d2b47ee9244ecrie prog, outsec->os_name, elf_errmsg(elf_errno()));
2722387f30847b828b57ba9ca59d2b47ee9244ecrie return (1);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if ((shdr = elf_getshdr(scn)) == NULL) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) fprintf(stderr, MSG_INTL(MSG_ELF_GETSHDR),
2722387f30847b828b57ba9ca59d2b47ee9244ecrie prog, outsec->os_name, elf_errmsg(elf_errno()));
2722387f30847b828b57ba9ca59d2b47ee9244ecrie return (1);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Assign the section type and flags.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie shdr->sh_type = outsec->os_type;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie shdr->sh_flags = outsec->os_flags;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if ((data = elf_newdata(scn)) == NULL) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) fprintf(stderr, MSG_INTL(MSG_ELF_NEWDATA),
2722387f30847b828b57ba9ca59d2b47ee9244ecrie prog, outsec->os_name, elf_errmsg(elf_errno()));
2722387f30847b828b57ba9ca59d2b47ee9244ecrie return (1);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie switch (shdr->sh_type) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie case SHT_PROGBITS:
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * If this is a PROGBITS section, then the data
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * originates from an input file. Assign the data
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * buffer to this input file and provide a default
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * alignment.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie data->d_buf = outsec->os_addr;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie data->d_type = ELF_T_BYTE;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie data->d_size = outsec->os_size;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie data->d_align = tdesc.td_align;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie break;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie case SHT_SYMTAB:
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * If this is the symbol table, use the symbol count to
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * reserve sufficient space for the symbols we need.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie data->d_buf = 0;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie data->d_type = ELF_T_SYM;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie data->d_size = (odp->od_symtabno * tdesc.td_symsz);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie data->d_align = tdesc.td_align;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie break;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie case SHT_STRTAB:
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * If this is a string table, use the table size to
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * reserve sufficient space for the strings we need.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie data->d_buf = 0;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie data->d_type = ELF_T_BYTE;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if (strcmp(outsec->os_name, MSG_ORIG(MSG_SCN_STRTAB)))
2722387f30847b828b57ba9ca59d2b47ee9244ecrie data->d_size = odp->od_shstrtabsz;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie else
2722387f30847b828b57ba9ca59d2b47ee9244ecrie data->d_size = odp->od_strtabsz;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie data->d_align = 1;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie break;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Write the ELF data into a memory image.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if ((elf_update(oelf, ELF_C_WRIMAGE)) == -1) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) fprintf(stderr, MSG_INTL(MSG_ELF_UPDATE), prog,
2722387f30847b828b57ba9ca59d2b47ee9244ecrie elf_errmsg(elf_errno()));
2722387f30847b828b57ba9ca59d2b47ee9244ecrie return (1);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Assign an ELF descriptor to the memory image.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if ((melf = elf_begin(0, ELF_C_IMAGE, oelf)) == NULL) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) fprintf(stderr, MSG_INTL(MSG_ELF_BEGIN), prog,
2722387f30847b828b57ba9ca59d2b47ee9244ecrie elf_errmsg(elf_errno()));
2722387f30847b828b57ba9ca59d2b47ee9244ecrie return (1);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Get the ELF header from the memory image.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if ((ehdr = elf_getehdr(melf)) == NULL) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) fprintf(stderr, MSG_INTL(MSG_ELF_GETEHDR), prog,
2722387f30847b828b57ba9ca59d2b47ee9244ecrie elf_errmsg(elf_errno()));
2722387f30847b828b57ba9ca59d2b47ee9244ecrie return (1);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Read the section header and data from the new sections of the
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * memory image.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie for (ALIST_TRAVERSE(odp->od_outsecs, off, outsec)) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie Elf_Scn *scn;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie Shdr *shdr;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if ((scn = elf_getscn(melf, outsec->os_ndx)) == NULL) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) fprintf(stderr, MSG_INTL(MSG_ELF_GETSCN),
2722387f30847b828b57ba9ca59d2b47ee9244ecrie prog, outsec->os_name, elf_errmsg(elf_errno()));
2722387f30847b828b57ba9ca59d2b47ee9244ecrie return (1);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if ((outsec->os_shdr = shdr = elf_getshdr(scn)) == NULL) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) fprintf(stderr, MSG_INTL(MSG_ELF_GETSHDR),
2722387f30847b828b57ba9ca59d2b47ee9244ecrie prog, outsec->os_name, elf_errmsg(elf_errno()));
2722387f30847b828b57ba9ca59d2b47ee9244ecrie return (1);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if ((outsec->os_data = elf_getdata(scn, NULL)) == NULL) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) fprintf(stderr, MSG_INTL(MSG_ELF_GETDATA),
2722387f30847b828b57ba9ca59d2b47ee9244ecrie prog, outsec->os_name, elf_errmsg(elf_errno()));
2722387f30847b828b57ba9ca59d2b47ee9244ecrie return (1);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if (shdr->sh_type == SHT_PROGBITS)
2722387f30847b828b57ba9ca59d2b47ee9244ecrie continue;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Remember the symbol table and string tables, so that they
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * can be filled in later.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if (shdr->sh_type == SHT_SYMTAB) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie outsymtab = outsec;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie symtab = (Sym *)outsec->os_data->d_buf;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie } else if (shdr->sh_type == SHT_STRTAB) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if (strcmp(outsec->os_name, MSG_ORIG(MSG_SCN_STRTAB))) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie outshstrtab = outsec;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie shstrtab = (char *)outsec->os_data->d_buf;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie } else {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie outstrtab = outsec;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie strtab = (char *)outsec->os_data->d_buf;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Update the ELF header with the .shstrtab index.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie ehdr->e_shstrndx = outshstrtab->os_ndx;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Set up the string table entries, and skip the first byte.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie strtabent = strtab;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie strtabent++;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie shstrtabent = shstrtab;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie shstrtabent++;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Skip the first symbol table entry. Write a FILE entry, and set
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * up for adding sections and data symbols. Associate the symbol
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * table with the string table.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie secsymtabent = symtab;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie secsymtabent++;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie secsymtabent->st_name = (strtabent - strtab);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie secsymtabent->st_info = ELF_ST_INFO(STB_LOCAL, STT_NOTYPE);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie secsymtabent->st_shndx = SHN_ABS;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie secsymtabent++;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie glbsymtabent = secsymtabent;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie glbsymtabent += alist_nitems(odp->od_outsecs);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie outsymtab->os_shdr->sh_link = outstrtab->os_ndx;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Write the output file name to the .strtab.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie len = strlen(ofile) + 1;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) memcpy(strtabent, ofile, len);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie strtabent += len;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Rescan all the new sections, adding symbols and strings as required.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie for (ALIST_TRAVERSE(odp->od_outsecs, off, outsec)) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie size_t alen;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Create a section symbol.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie secsymtabent->st_info = ELF_ST_INFO(STB_LOCAL, STT_SECTION);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie secsymtabent->st_shndx = outsec->os_ndx;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie secsymtabent++;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Store the section name, (with an appended "." if the section
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * name is derived from the input file name), and point the
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * section header to this name.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie outsec->os_shdr->sh_name = (shstrtabent - shstrtab);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if (outsec->os_shdr->sh_type == SHT_PROGBITS) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) memcpy(shstrtabent, MSG_ORIG(MSG_STR_DOT),
2722387f30847b828b57ba9ca59d2b47ee9244ecrie MSG_STR_DOT_SIZE);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie shstrtabent += MSG_STR_DOT_SIZE;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie len = strlen(outsec->os_name) + 1;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) memcpy(shstrtabent, outsec->os_name, len);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie shstrtabent += len;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if (outsec->os_shdr->sh_type != SHT_PROGBITS)
2722387f30847b828b57ba9ca59d2b47ee9244ecrie continue;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Add a symbol pointing to this PROGBITS section. The value
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * is the base offset of this section, which can only be 0.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * The size of the symbol can be taken straight from the section
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * header information (that libelf generated).
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie glbsymtabent->st_name = (strtabent - strtab);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie glbsymtabent->st_info = ELF_ST_INFO(STB_GLOBAL, STT_OBJECT);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie glbsymtabent->st_shndx = outsec->os_ndx;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie glbsymtabent->st_size = outsec->os_shdr->sh_size;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie glbsymtabent++;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Store this symbol name (with an appended "_data") in the
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * string table.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie len--;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) memcpy(strtabent, outsec->os_name, len);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie strtabent += len;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie alen = (MSG_STR_START_SIZE + 1);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) memcpy(strtabent, MSG_ORIG(MSG_STR_START), alen);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie strtabent += alen;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Add a symbol indicating the size of this PROGBITS section.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie glbsymtabent->st_name = (strtabent - strtab);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie glbsymtabent->st_info = ELF_ST_INFO(STB_GLOBAL, STT_OBJECT);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie glbsymtabent->st_shndx = outsec->os_ndx;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie glbsymtabent->st_value = outsec->os_shdr->sh_size;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie glbsymtabent++;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Store this symbol name (with an appended "_end") in the
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * string table.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) memcpy(strtabent, outsec->os_name, len);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie strtabent += len;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie alen = (MSG_STR_END_SIZE + 1);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) memcpy(strtabent, MSG_ORIG(MSG_STR_END), alen);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie strtabent += alen;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Update the .symtab section header with the index of the first
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * non-local symbol. The only locals written are the section symbols.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie outsymtab->os_shdr->sh_info = (secsymtabent - symtab);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Having updated the image following the byte order of elfwrap(), seed
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * the ELF header with the appropriate target information.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie ehdr->e_ident[EI_CLASS] = tdesc.td_class;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie ehdr->e_ident[EI_DATA] = tdesc.td_data;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie ehdr->e_machine = tdesc.td_mach;
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * If the output relocatable object is targeted to a machine with a
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * different byte order than the host running elfwrap(1), swap the data
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * to the target byte order.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if ((_elf_sys_encoding() != ehdr->e_ident[EI_DATA]) &&
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (_elf_swap_wrimage(melf) != 0)) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) fprintf(stderr, MSG_INTL(MSG_ELF_SWAP_WRIMAGE), prog,
2722387f30847b828b57ba9ca59d2b47ee9244ecrie elf_errmsg(elf_errno()));
2722387f30847b828b57ba9ca59d2b47ee9244ecrie return (1);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) elf_end(melf);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie /*
2722387f30847b828b57ba9ca59d2b47ee9244ecrie * Finally, write the updated memory image out to disc.
2722387f30847b828b57ba9ca59d2b47ee9244ecrie */
2722387f30847b828b57ba9ca59d2b47ee9244ecrie if ((elf_update(oelf, ELF_C_WRITE)) == -1) {
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) fprintf(stderr, MSG_INTL(MSG_ELF_UPDATE), prog,
2722387f30847b828b57ba9ca59d2b47ee9244ecrie elf_errmsg(elf_errno()));
2722387f30847b828b57ba9ca59d2b47ee9244ecrie return (1);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie }
2722387f30847b828b57ba9ca59d2b47ee9244ecrie (void) elf_end(oelf);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie
2722387f30847b828b57ba9ca59d2b47ee9244ecrie return (0);
2722387f30847b828b57ba9ca59d2b47ee9244ecrie}