summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimm Bäder <tbaeder@redhat.com>2021-01-08 09:09:55 +0100
committerMark Wielaard <mark@klomp.org>2021-01-28 22:03:40 +0100
commit67a912f0b81047d42881be3c40c8404c2711711c (patch)
tree561d7be0fb08c169fdc337e6b4d0db4f51a9890e
parentstrip: Remove no_symtab_updates() function (diff)
downloadelfutils-67a912f0b81047d42881be3c40c8404c2711711c.tar.gz
elfutils-67a912f0b81047d42881be3c40c8404c2711711c.tar.bz2
elfutils-67a912f0b81047d42881be3c40c8404c2711711c.tar.xz
elf-from-memory: Restructure code to get rid of nested handle_segment()
Use one loop for both 32 and 64 bit case. This allows for only one call site of the old handle_segment(), which we can then inline into the for loop. Signed-off-by: Timm Bäder <tbaeder@redhat.com>
-rw-r--r--libdwfl/ChangeLog7
-rw-r--r--libdwfl/elf-from-memory.c81
2 files changed, 41 insertions, 47 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index f9f6f01f..f17eafe7 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,10 @@
12021-01-08 Timm Bäder <tbaeder@redhat.com>
2
3 * elf-from-memory.c (elf_from_remote_memory): Use if instead of
4 switch on class. Set new vaddr, memsz, offset and filesz
5 variables. Inline handle_segment function check and set loadbase,
6 found_base, segments_end and segments_end_mem directly.
7
12020-12-16 Dmitry V. Levin <ldv@altlinux.org> 82020-12-16 Dmitry V. Levin <ldv@altlinux.org>
2 9
3 * argp-std.c (_): Remove. 10 * argp-std.c (_): Remove.
diff --git a/libdwfl/elf-from-memory.c b/libdwfl/elf-from-memory.c
index c54c1b99..933ab864 100644
--- a/libdwfl/elf-from-memory.c
+++ b/libdwfl/elf-from-memory.c
@@ -223,61 +223,48 @@ elf_from_remote_memory (GElf_Addr ehdr_vma,
223 bool found_base = false; 223 bool found_base = false;
224 Elf32_Phdr (*p32)[phnum] = phdrsp; 224 Elf32_Phdr (*p32)[phnum] = phdrsp;
225 Elf64_Phdr (*p64)[phnum] = phdrsp; 225 Elf64_Phdr (*p64)[phnum] = phdrsp;
226 switch (ehdr.e32.e_ident[EI_CLASS]) 226
227 if (class32)
227 { 228 {
228 /* Sanity checks segments and calculates segment_end, 229 if (! elf32_xlatetom (&xlateto, &xlatefrom, ehdr.e32.e_ident[EI_DATA]))
229 segments_end, segments_end_mem and loadbase (if not 230 goto libelf_error;
230 found_base yet). Returns true if sanity checking failed, 231 }
231 false otherwise. */ 232 else
232 inline bool handle_segment (GElf_Addr vaddr, GElf_Off offset, 233 {
233 GElf_Xword filesz, GElf_Xword memsz) 234 if (! elf64_xlatetom (&xlateto, &xlatefrom, ehdr.e64.e_ident[EI_DATA]))
234 { 235 goto libelf_error;
235 /* Sanity check the segment load aligns with the pagesize. */ 236 }
236 if (((vaddr - offset) & (pagesize - 1)) != 0)
237 return true;
238 237
239 GElf_Off segment_end = ((offset + filesz + pagesize - 1) 238 for (uint_fast16_t i = 0; i < phnum; ++i)
240 & -pagesize); 239 {
240 GElf_Word type = class32 ? (*p32)[i].p_type : (*p64)[i].p_type;
241 241
242 if (segment_end > (GElf_Off) contents_size) 242 if (type != PT_LOAD)
243 contents_size = segment_end; 243 continue;
244 244
245 if (!found_base && (offset & -pagesize) == 0) 245 GElf_Addr vaddr = class32 ? (*p32)[i].p_vaddr : (*p64)[i].p_vaddr;
246 { 246 GElf_Xword memsz = class32 ? (*p32)[i].p_memsz : (*p64)[i].p_memsz;
247 loadbase = ehdr_vma - (vaddr & -pagesize); 247 GElf_Off offset = class32 ? (*p32)[i].p_offset : (*p64)[i].p_offset;
248 found_base = true; 248 GElf_Xword filesz = class32 ? (*p32)[i].p_filesz : (*p64)[i].p_filesz;
249 }
250 249
251 segments_end = offset + filesz; 250 /* Sanity check the segment load aligns with the pagesize. */
252 segments_end_mem = offset + memsz; 251 if (((vaddr - offset) & (pagesize - 1)) != 0)
253 return false; 252 goto bad_elf;
254 }
255 253
256 case ELFCLASS32: 254 GElf_Off segment_end = ((offset + filesz + pagesize - 1)
257 if (elf32_xlatetom (&xlateto, &xlatefrom, 255 & -pagesize);
258 ehdr.e32.e_ident[EI_DATA]) == NULL)
259 goto libelf_error;
260 for (uint_fast16_t i = 0; i < phnum; ++i)
261 if ((*p32)[i].p_type == PT_LOAD)
262 if (handle_segment ((*p32)[i].p_vaddr, (*p32)[i].p_offset,
263 (*p32)[i].p_filesz, (*p32)[i].p_memsz))
264 goto bad_elf;
265 break;
266 256
267 case ELFCLASS64: 257 if (segment_end > (GElf_Off) contents_size)
268 if (elf64_xlatetom (&xlateto, &xlatefrom, 258 contents_size = segment_end;
269 ehdr.e64.e_ident[EI_DATA]) == NULL)
270 goto libelf_error;
271 for (uint_fast16_t i = 0; i < phnum; ++i)
272 if ((*p64)[i].p_type == PT_LOAD)
273 if (handle_segment ((*p64)[i].p_vaddr, (*p64)[i].p_offset,
274 (*p64)[i].p_filesz, (*p64)[i].p_memsz))
275 goto bad_elf;
276 break;
277 259
278 default: 260 if (!found_base && (offset & -pagesize) == 0)
279 abort (); 261 {
280 break; 262 loadbase = ehdr_vma - (vaddr & -pagesize);
263 found_base = true;
264 }
265
266 segments_end = offset + filesz;
267 segments_end_mem = offset + memsz;
281 } 268 }
282 269
283 /* Trim the last segment so we don't bother with zeros in the last page 270 /* Trim the last segment so we don't bother with zeros in the last page