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 #include <stdlib.h> 31 #include "libelf.h" 32 #include "decl.h" 33 #include "msg.h" 34 35 36 Elf_Data * 37 elf_rawdata(Elf_Scn * scn, Elf_Data * data) 38 { 39 Dnode * d = (Dnode *)data; 40 Dnode * raw; 41 Elf_Data * rc; 42 Elf * elf; 43 44 if (scn == 0) 45 return (0); 46 elf = scn->s_elf; 47 READLOCKS(elf, scn) 48 if ((scn->s_myflags & SF_READY) == 0) { 49 UPGRADELOCKS(elf, scn) 50 if ((scn->s_myflags & SF_READY) == 0) 51 (void) _elf_cookscn(scn); 52 DOWNGRADELOCKS(elf, scn) 53 } 54 55 if (d == 0) 56 d = scn->s_hdnode; 57 else 58 d = d->db_next; 59 60 if (d == 0) { 61 READUNLOCKS(elf, scn) 62 return (0); 63 } 64 65 if (d->db_scn != scn) { 66 _elf_seterr(EREQ_DATA, 0); 67 READUNLOCKS(elf, scn) 68 return (0); 69 } 70 71 /* 72 * The data may come from a previously constructed Dbuf, 73 * from the file's raw memory image, or the file system. 74 * "Empty" regions get an empty buffer. 75 */ 76 77 if (d->db_raw != 0) { 78 rc = &d->db_raw->db_data; 79 READUNLOCKS(elf, scn) 80 return (rc); 81 } 82 83 if ((raw = _elf_dnode()) == 0) { 84 READUNLOCKS(elf, scn) 85 return (0); 86 } 87 raw->db_myflags |= DBF_READY; 88 if ((d->db_off == 0) || (d->db_fsz == 0)) { 89 d->db_raw = raw; 90 raw->db_data.d_size = d->db_shsz; 91 rc = &raw->db_data; 92 READUNLOCKS(elf, scn) 93 return (rc); 94 } 95 96 /* 97 * validate the region 98 */ 99 100 if ((d->db_off < 0) || 101 (d->db_off >= elf->ed_fsz) || 102 (elf->ed_fsz - d->db_off < d->db_fsz)) { 103 _elf_seterr(EFMT_DATA, 0); 104 free(raw); 105 READUNLOCKS(elf, scn) 106 return (0); 107 } 108 raw->db_data.d_size = d->db_fsz; 109 if (elf->ed_raw != 0) { 110 raw->db_data.d_buf = (Elf_Void *)(elf->ed_raw + d->db_off); 111 d->db_raw = raw; 112 rc = &raw->db_data; 113 READUNLOCKS(elf, scn) 114 return (rc); 115 } 116 raw->db_buf = (Elf_Void *)_elf_read(elf->ed_fd, 117 elf->ed_baseoff + d->db_off, d->db_fsz); 118 if (raw->db_buf == 0) { 119 free(raw); 120 READUNLOCKS(elf, scn) 121 return (0); 122 } 123 raw->db_data.d_buf = raw->db_buf; 124 d->db_raw = raw; 125 rc = &raw->db_data; 126 READUNLOCKS(elf, scn) 127 return (rc); 128 } 129