From: Roland McGrath Date: Wed, 16 Jun 2010 05:17:20 +0000 (-0700) Subject: Handle DWARF4 .debug_frame format. X-Git-Tag: elfutils-0.148~22 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9bcd2657ab6a761e9b218a3b3ba578756b6f7a23;p=platform%2Fupstream%2Felfutils.git Handle DWARF4 .debug_frame format. --- diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 780c747..d6ea6c6 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,5 +1,7 @@ 2010-06-15 Roland McGrath + * dwarf_next_cfi.c: Handle version 4 format. + * dwarf_getsrclines.c: Handle version 4 format. 2010-06-01 Roland McGrath diff --git a/libdw/dwarf_next_cfi.c b/libdw/dwarf_next_cfi.c index d5d4cfd..1ffa669 100644 --- a/libdw/dwarf_next_cfi.c +++ b/libdw/dwarf_next_cfi.c @@ -1,5 +1,5 @@ /* Advance to next CFI entry. - Copyright (C) 2009 Red Hat, Inc. + Copyright (C) 2009-2010 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@ -145,25 +145,48 @@ dwarf_next_cfi (e_ident, data, eh_frame_p, off, next_off, entry) /* Read the version stamp. Always an 8-bit value. */ uint8_t version = *bytes++; - if (version != 1 && version != 3) + if (version != 1 && (unlikely (version < 3) || unlikely (version > 4))) goto invalid; entry->cie.augmentation = (const char *) bytes; bytes = memchr (bytes, '\0', limit - bytes); - if (bytes == NULL) + if (unlikely (bytes == NULL)) goto invalid; ++bytes; + /* The address size for CFI is implicit in the ELF class. */ + unsigned int address_size = e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; + unsigned int segment_size = 0; + if (version >= 4) + { + if (unlikely (limit - bytes < 5)) + goto invalid; + /* XXX We don't actually support address_size not matching the class. + To do so, we'd have to return it here so that intern_new_cie + could use it choose a specific fde_encoding. */ + if (unlikely (*bytes != address_size)) + { + __libdw_seterrno (DWARF_E_VERSION); + return -1; + } + address_size = *bytes++; + segment_size = *bytes++; + /* We don't actually support segment selectors. We'd have to + roll this into the fde_encoding bits or something. */ + if (unlikely (segment_size != 0)) + { + __libdw_seterrno (DWARF_E_VERSION); + return -1; + } + } + const char *ap = entry->cie.augmentation; /* g++ v2 "eh" has pointer immediately following augmentation string, so it must be handled first. */ if (unlikely (ap[0] == 'e' && ap[1] == 'h')) { - /* The address size for CFI is implicit in the ELF class. */ - unsigned int address_size = e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8; - ap += 2; bytes += address_size; }