1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1988 AT&T */ 28 /* All Rights Reserved */ 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #include <stdlib.h> 33 #include "libelf.h" 34 #include "decl.h" 35 #include "msg.h" 36 37 38 Elf_Data * 39 elf_rawdata(Elf_Scn * scn, Elf_Data * data) 40 { 41 Dnode * d = (Dnode *)data; 42 Dnode * raw; 43 Elf_Data * rc; 44 Elf * elf; 45 46 if (scn == 0) 47 return (0); 48 elf = scn->s_elf; 49 READLOCKS(elf, scn) 50 if ((scn->s_myflags & SF_READY) == 0) { 51 UPGRADELOCKS(elf, scn) 52 if ((scn->s_myflags & SF_READY) == 0) 53 (void) _elf_cookscn(scn); 54 DOWNGRADELOCKS(elf, scn) 55 } 56 57 if (d == 0) 58 d = scn->s_hdnode; 59 else 60 d = d->db_next; 61 62 if (d == 0) { 63 READUNLOCKS(elf, scn) 64 return (0); 65 } 66 67 if (d->db_scn != scn) { 68 _elf_seterr(EREQ_DATA, 0); 69 READUNLOCKS(elf, scn) 70 return (0); 71 } 72 73 /* 74 * The data may come from a previously constructed Dbuf, 75 * from the file's raw memory image, or the file system. 76 * "Empty" regions get an empty buffer. 77 */ 78 79 if (d->db_raw != 0) { 80 rc = &d->db_raw->db_data; 81 READUNLOCKS(elf, scn) 82 return (rc); 83 } 84 85 if ((raw = _elf_dnode()) == 0) { 86 READUNLOCKS(elf, scn) 87 return (0); 88 } 89 raw->db_myflags |= DBF_READY; 90 if ((d->db_off == 0) || (d->db_fsz == 0)) { 91 d->db_raw = raw; 92 raw->db_data.d_size = d->db_shsz; 93 rc = &raw->db_data; 94 READUNLOCKS(elf, scn) 95 return (rc); 96 } 97 98 /* 99 * validate the region 100 */ 101 102 if ((d->db_off < 0) || 103 (d->db_off >= elf->ed_fsz) || 104 (elf->ed_fsz - d->db_off < d->db_fsz)) { 105 _elf_seterr(EFMT_DATA, 0); 106 free(raw); 107 READUNLOCKS(elf, scn) 108 return (0); 109 } 110 raw->db_data.d_size = d->db_fsz; 111 if (elf->ed_raw != 0) { 112 raw->db_data.d_buf = (Elf_Void *)(elf->ed_raw + d->db_off); 113 d->db_raw = raw; 114 rc = &raw->db_data; 115 READUNLOCKS(elf, scn) 116 return (rc); 117 } 118 raw->db_buf = (Elf_Void *)_elf_read(elf->ed_fd, 119 elf->ed_baseoff + d->db_off, d->db_fsz); 120 if (raw->db_buf == 0) { 121 free(raw); 122 READUNLOCKS(elf, scn) 123 return (0); 124 } 125 raw->db_data.d_buf = raw->db_buf; 126 d->db_raw = raw; 127 rc = &raw->db_data; 128 READUNLOCKS(elf, scn) 129 return (rc); 130 } 131