1 /* Return converted data from raw chunk of ELF file.
2 Copyright (C) 2007 Red Hat, Inc.
3 This file is part of elfutils.
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
8 * the GNU Lesser General Public License as published by the Free
9 Software Foundation; either version 3 of the License, or (at
10 your option) any later version
14 * the GNU General Public License as published by the Free
15 Software Foundation; either version 2 of the License, or (at
16 your option) any later version
18 or both in parallel, as here.
20 elfutils is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
25 You should have received copies of the GNU General Public License and
26 the GNU Lesser General Public License along with this program. If
27 not, see <http://www.gnu.org/licenses/>. */
44 elf_getdata_rawchunk (elf, offset, size, type)
50 if (unlikely (elf == NULL))
53 if (unlikely (elf->kind != ELF_K_ELF))
55 /* No valid descriptor. */
56 __libelf_seterrno (ELF_E_INVALID_HANDLE);
60 if (unlikely (offset < 0 || offset + (off64_t) size < offset
61 || offset + size > elf->maximum_size))
63 /* Invalid request. */
64 __libelf_seterrno (ELF_E_INVALID_OP);
68 if (type >= ELF_T_NUM)
70 __libelf_seterrno (ELF_E_UNKNOWN_TYPE);
74 /* Get the raw bytes from the file. */
77 Elf_Data *result = NULL;
79 rwlock_rdlock (elf->lock);
81 /* If the file is mmap'ed we can use it directly. */
82 if (elf->map_address != NULL)
83 rawchunk = elf->map_address + elf->start_offset + offset;
86 /* We allocate the memory and read the data from the file. */
87 rawchunk = malloc (size);
91 __libelf_seterrno (ELF_E_NOMEM);
95 /* Read the file content. */
96 if (unlikely ((size_t) pread_retry (elf->fildes, rawchunk, size,
97 elf->start_offset + offset)
100 /* Something went wrong. */
102 __libelf_seterrno (ELF_E_READ_ERROR);
106 flags = ELF_F_MALLOCED;
109 /* Copy and/or convert the data as needed for aligned native-order access. */
110 size_t align = __libelf_type_align (elf->class, type);
112 if (elf->state.elf32.ehdr->e_ident[EI_DATA] == MY_ELFDATA)
114 if (((uintptr_t) rawchunk & (align - 1)) == 0)
115 /* No need to copy, we can use the raw data. */
119 /* A malloc'd block is always sufficiently aligned. */
122 buffer = malloc (size);
123 if (unlikely (buffer == NULL))
125 flags = ELF_F_MALLOCED;
127 /* The copy will be appropriately aligned for direct access. */
128 memcpy (buffer, rawchunk, size);
137 buffer = malloc (size);
138 if (unlikely (buffer == NULL))
140 flags = ELF_F_MALLOCED;
143 /* Call the conversion function. */
144 (*__elf_xfctstom[LIBELF_EV_IDX][LIBELF_EV_IDX][elf->class - 1][type])
145 (buffer, rawchunk, size, 0);
148 /* Allocate the dummy container to point at this buffer. */
149 Elf_Data_Chunk *chunk = calloc (1, sizeof *chunk);
157 chunk->dummy_scn.elf = elf;
158 chunk->dummy_scn.flags = flags;
159 chunk->data.s = &chunk->dummy_scn;
160 chunk->data.d.d_buf = buffer;
161 chunk->data.d.d_size = size;
162 chunk->data.d.d_type = type;
163 chunk->data.d.d_align = align;
164 chunk->data.d.d_version = __libelf_version;
166 rwlock_unlock (elf->lock);
167 rwlock_wrlock (elf->lock);
169 chunk->next = elf->state.elf.rawchunks;
170 elf->state.elf.rawchunks = chunk;
171 result = &chunk->data.d;
174 rwlock_unlock (elf->lock);