xref: /onnv-gate/usr/src/cmd/sgs/libelf/common/output.c (revision 9144:82542ec040b5)
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