10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
51836Srie * Common Development and Distribution License (the "License").
61836Srie * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate
220Sstevel@tonic-gate /*
23*9144SRod.Evans@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
276812Sraf /*
286812Sraf * Copyright (c) 1988 AT&T
296812Sraf * All Rights Reserved
306812Sraf */
310Sstevel@tonic-gate
320Sstevel@tonic-gate #include <sys/mman.h>
330Sstevel@tonic-gate #include <stdio.h>
340Sstevel@tonic-gate #include <stdlib.h>
350Sstevel@tonic-gate #include <unistd.h>
360Sstevel@tonic-gate #include <libelf.h>
370Sstevel@tonic-gate #include <errno.h>
380Sstevel@tonic-gate #include "decl.h"
390Sstevel@tonic-gate #include "msg.h"
400Sstevel@tonic-gate
410Sstevel@tonic-gate /*
420Sstevel@tonic-gate * File output
430Sstevel@tonic-gate * These functions write output files.
440Sstevel@tonic-gate * On SVR4 and newer systems use mmap(2). On older systems (or on
450Sstevel@tonic-gate * file systems that don't support mmap), use write(2).
460Sstevel@tonic-gate */
470Sstevel@tonic-gate
480Sstevel@tonic-gate
490Sstevel@tonic-gate char *
_elf_outmap(int fd,size_t sz,unsigned int * pflag)500Sstevel@tonic-gate _elf_outmap(int fd, size_t sz, unsigned int *pflag)
510Sstevel@tonic-gate {
520Sstevel@tonic-gate char *p;
530Sstevel@tonic-gate
540Sstevel@tonic-gate /*
550Sstevel@tonic-gate * Note: Some NFS implementations do not provide from enlarging a file
560Sstevel@tonic-gate * via ftruncate(), thus this may fail with ENOSUP. In this case the
570Sstevel@tonic-gate * fall through to the calloc() mechanism will occur.
580Sstevel@tonic-gate */
590Sstevel@tonic-gate if ((!*pflag) && (ftruncate(fd, (off_t)sz) == 0) &&
600Sstevel@tonic-gate (p = mmap((char *)0, sz, PROT_READ+PROT_WRITE,
610Sstevel@tonic-gate MAP_SHARED, fd, (off_t)0)) != (char *)-1) {
620Sstevel@tonic-gate *pflag = 1;
630Sstevel@tonic-gate return (p);
640Sstevel@tonic-gate }
650Sstevel@tonic-gate
660Sstevel@tonic-gate *pflag = 0;
670Sstevel@tonic-gate
680Sstevel@tonic-gate /*
690Sstevel@tonic-gate * If mmap fails, try calloc. Some file systems don't mmap. Note, we
700Sstevel@tonic-gate * use calloc rather than malloc, as ld(1) assumes that the backing
710Sstevel@tonic-gate * storage it is working with is zero filled.
720Sstevel@tonic-gate */
730Sstevel@tonic-gate if ((p = (char *)calloc(1, sz)) == 0)
740Sstevel@tonic-gate _elf_seterr(EMEM_OUT, errno);
750Sstevel@tonic-gate return (p);
760Sstevel@tonic-gate }
770Sstevel@tonic-gate
780Sstevel@tonic-gate
790Sstevel@tonic-gate size_t
_elf_outsync(int fd,char * p,size_t sz,unsigned int flag)800Sstevel@tonic-gate _elf_outsync(int fd, char *p, size_t sz, unsigned int flag)
810Sstevel@tonic-gate {
820Sstevel@tonic-gate if (flag != 0) {
830Sstevel@tonic-gate int err;
84*9144SRod.Evans@Sun.COM
85*9144SRod.Evans@Sun.COM if ((fd = msync(p, sz, MS_ASYNC)) == -1)
860Sstevel@tonic-gate err = errno;
870Sstevel@tonic-gate (void) munmap(p, sz);
880Sstevel@tonic-gate if (fd == 0)
890Sstevel@tonic-gate return (sz);
900Sstevel@tonic-gate _elf_seterr(EIO_SYNC, err);
910Sstevel@tonic-gate return (0);
920Sstevel@tonic-gate }
931836Srie if ((lseek(fd, 0L, SEEK_SET) == 0) &&
94*9144SRod.Evans@Sun.COM (write(fd, p, sz) == sz)) {
951836Srie (void) free(p);
961836Srie return (sz);
970Sstevel@tonic-gate }
980Sstevel@tonic-gate _elf_seterr(EIO_WRITE, errno);
990Sstevel@tonic-gate return (0);
1000Sstevel@tonic-gate }
101