summaryrefslogtreecommitdiff
path: root/libdw/dwarf_ranges.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2009-06-14 20:19:45 -0700
committerUlrich Drepper <drepper@redhat.com>2009-06-14 20:19:45 -0700
commit99d2372b25d1231d786b70278478c7a112f2b27c (patch)
treeca307d5078971fdef16f324e8ffd32b25ddd0df1 /libdw/dwarf_ranges.c
parentf189493154d0041deced00e6a99cc5426dc9d260 (diff)
downloadelfutils-99d2372b25d1231d786b70278478c7a112f2b27c.tar.gz
Squashed commit of the following:
commit 77abb31cb8d55980ef92260917a7ecdd228b1a44 Author: Petr Machata <pmachata@redhat.com> Date: Mon Jun 8 15:46:16 2009 +0200 Fix a bug in offset checking commit b794eac4f8d3e08101b5d2924523b1259bbc1b17 Author: Petr Machata <pmachata@redhat.com> Date: Wed Jun 3 16:00:01 2009 +0200 Cosmetic, get rid of defining several variables per line commit a23938fe35d515a3d75a51f6204771f3cf6c9ec4 Author: Petr Machata <pmachata@redhat.com> Date: Wed Jun 3 15:50:03 2009 +0200 Restructure the code to decrease the binary size commit 7c301e3d4e8584dfb3174855fb6af3d5791dfeed Author: Petr Machata <pmachata@redhat.com> Date: Mon Jun 1 19:43:28 2009 +0200 Shuffle a couple pieces of code around to make the code smaller commit 6325323482c2a3e17409d32c7feec9461be26614 Merge: 83ac53d... e94b1b2... Author: Petr Machata <pmachata@redhat.com> Date: Fri May 22 08:49:07 2009 +0200 Merge branch 'master' of ssh://pmachata@git.fedorahosted.org/git/elfutils into pmachata/reader_hooks Conflicts: libdw/ChangeLog commit 83ac53db400945c074e77ec9904efe550903a0e2 Author: Petr Machata <pmachata@redhat.com> Date: Fri May 22 08:40:25 2009 +0200 Call reloc hook with the original address, not incremented commit f1996388745566abc1ca1c1700b3b7eded208575 Author: Petr Machata <pmachata@redhat.com> Date: Wed May 6 16:53:03 2009 +0200 Rewrite boundary checking logic so that it's immune to arithmetic overflow * ... also get rid of some code redundancy. commit 0c1df732822d83548edd0d005f3450281ed1701b Author: Petr Machata <pmachata@redhat.com> Date: Wed May 6 16:25:09 2009 +0200 __libdw_read_offset* take extra argument for header size checks * also presence of debug data and buffer is checked in __libdw_in_section commit 6fb192e360f842cacb34a90c03cd0524cccc3dec Author: Petr Machata <pmachata@redhat.com> Date: Wed May 6 15:51:20 2009 +0200 Check for presence of data before loading the offset commit a2e7612b165d83dd241225f87075fa4f58d18781 Author: Petr Machata <pmachata@redhat.com> Date: Wed May 6 15:04:16 2009 +0200 Cosmetic changes commit 8b1aad2c2f6c8dc02b3e704e4f386c1827e385cb Author: Petr Machata <pmachata@redhat.com> Date: Tue May 5 15:34:13 2009 +0200 Improve reader hook functions a bit * ... so that they are closer match to what's need on call sites commit 3854b7fbab2fe331711365f94a295af82164d0d2 Author: Petr Machata <pmachata@redhat.com> Date: Tue May 5 14:33:50 2009 +0200 Fixes in use of reader hooks in __libdw_formptr and dwarf_formudata * and a bit more commit 335075596b6acef6e59919155e2b087e690a572d Author: Petr Machata <pmachata@redhat.com> Date: Tue May 5 14:32:39 2009 +0200 Rename __libdw_read_udata_addr to __libdw_formptr commit 8273a2adaf8cb2ee203926af2849e4f96f8a6eaf Author: Petr Machata <pmachata@redhat.com> Date: Tue May 5 02:53:40 2009 +0200 Introduce __libdw_read_udata_address * the use in dwarf_ranges is iffy, there's a functionality mismatch. Need to find some better way commit 1c897f4abde1530038d332f4fc03a596a24f6aaf Author: Petr Machata <pmachata@redhat.com> Date: Mon May 4 18:09:13 2009 +0200 ChangeLog entries for previous commit commit 90d7c39454468b91c0fd6514a4e8d821222d6adb Author: Petr Machata <pmachata@redhat.com> Date: Mon May 4 18:07:54 2009 +0200 Fix bugs, introduce __libdw_read_begin_end_pair_inc commit 9b3923f5b69a3e56590769435c4693f057acdc1f Merge: 6200ba6... 589b3d3... Author: Petr Machata <pmachata@redhat.com> Date: Mon May 4 12:22:21 2009 +0200 Merge branch 'master' of ssh://pmachata@git.fedorahosted.org/git/elfutils into pmachata/reader_hooks commit 6200ba62aa9ea3cb9318f73a27181907a528dbe4 Author: Petr Machata <pmachata@redhat.com> Date: Wed Apr 29 15:31:28 2009 +0200 dwarf_getlocation_addr uses read hooks commit ecbb8cdd8b500e37dc34fc246b912f704fe31ca4 Author: Petr Machata <pmachata@redhat.com> Date: Wed Apr 29 15:16:09 2009 +0200 dwarf_ranges and dwarf_formref use read hooks commit cb8f67b29a896c2660c10aa1028a9dbb377553e9 Author: Petr Machata <pmachata@redhat.com> Date: Tue Apr 28 18:39:04 2009 +0200 Convert several new functions to use read hooks commit b130453eb16a8cf042915e312cc5f189b8b92c01 Author: Petr Machata <pmachata@redhat.com> Date: Tue Apr 28 18:38:27 2009 +0200 Add length read hooks commit bd885ff694817b965231d99f1ab867947998e734 Author: Petr Machata <pmachata@redhat.com> Date: Tue Apr 28 18:36:17 2009 +0200 Constify read hook arguments commit 66fe03f1e489a88b89a15c9e13f9bd33db2729b1 Author: Petr Machata <pmachata@redhat.com> Date: Tue Apr 28 16:11:05 2009 +0200 Change type of return value of offset read hooks to Dwarf_Off commit 22b36e00cc228f5a966f84ca3323e5d652923ce8 Merge: 5b3534b... a7cb532... Author: Petr Machata <pmachata@redhat.com> Date: Mon Apr 27 19:05:25 2009 +0200 Merge branch 'master' of ssh://pmachata@git.fedorahosted.org/git/elfutils into pmachata/reader_hooks commit 5b3534b62cbd45fe4f11dd1be3e492237938cce0 Author: Petr Machata <pmachata@redhat.com> Date: Mon Apr 27 18:53:06 2009 +0200 Rewrites in read hooks * Have the checking and reading logic itself in the header so that it gets optimized out/inlined. Call external relocating hook from there, there will presumably be more work to do, and we presumably don't want to keep this in the header. commit 9e265d71d0eb900e76d6fdb0196ef4fc6507f3a7 Merge: 1783089... 300f3a4... Author: Petr Machata <pmachata@redhat.com> Date: Thu Apr 23 17:45:25 2009 +0200 Merge branch 'master' of ssh://pmachata@git.fedorahosted.org/git/elfutils into pmachata/reader_hooks commit 1783089b184ddea2081bbe5ac4e80420cb6b0803 Author: Petr Machata <pmachata@redhat.com> Date: Thu Apr 23 17:44:48 2009 +0200 Use the new reader hooks in several places commit 11c3d97a5b40ea15edf324092b03da3050610d01 Author: Petr Machata <pmachata@redhat.com> Date: Thu Apr 23 17:40:03 2009 +0200 Introduce reader hooks
Diffstat (limited to 'libdw/dwarf_ranges.c')
-rw-r--r--libdw/dwarf_ranges.c105
1 files changed, 71 insertions, 34 deletions
diff --git a/libdw/dwarf_ranges.c b/libdw/dwarf_ranges.c
index 1eef617b..50fb6ba2 100644
--- a/libdw/dwarf_ranges.c
+++ b/libdw/dwarf_ranges.c
@@ -55,6 +55,52 @@
#include <dwarf.h>
#include <assert.h>
+/* Read up begin/end pair and increment read pointer.
+ - If it's normal range record, set up `*beginp' and `*endp' and return 0.
+ - If it's base address selection record, set up `*basep' and return 1.
+ - If it's end of rangelist, don't set anything and return 2
+ - If an error occurs, don't set anything and return -1. */
+internal_function int
+__libdw_read_begin_end_pair_inc (Dwarf *dbg, int sec_index,
+ unsigned char **addrp, int width,
+ Dwarf_Addr *beginp, Dwarf_Addr *endp,
+ Dwarf_Addr *basep)
+{
+ Dwarf_Addr escape = (width == 8 ? (Elf64_Addr) -1
+ : (Elf64_Addr) (Elf32_Addr) -1);
+ Dwarf_Addr begin;
+ Dwarf_Addr end;
+
+ unsigned char *addr = *addrp;
+ bool begin_relocated = READ_AND_RELOCATE (__libdw_relocate_address, begin);
+ bool end_relocated = READ_AND_RELOCATE (__libdw_relocate_address, end);
+ *addrp = addr;
+
+ /* Unrelocated escape for begin means base address selection. */
+ if (begin == escape && !begin_relocated)
+ {
+ if (unlikely (end == escape))
+ {
+ __libdw_seterrno (DWARF_E_INVALID_DWARF);
+ return -1;
+ }
+
+ if (basep != NULL)
+ *basep = end;
+ return 1;
+ }
+
+ /* Unrelocated pair of zeroes means end of range list. */
+ if (begin == 0 && end == 0 && !begin_relocated && !end_relocated)
+ return 2;
+
+ /* Don't check for begin_relocated == end_relocated. Serve the data
+ to the client even though it may be buggy. */
+ *beginp = begin;
+ *endp = end;
+
+ return 0;
+}
ptrdiff_t
dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep,
@@ -80,11 +126,12 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep,
const Elf_Data *d = die->cu->dbg->sectiondata[IDX_debug_ranges];
if (d == NULL && offset != 0)
{
- no_ranges:
__libdw_seterrno (DWARF_E_NO_DEBUG_RANGES);
return -1;
}
+ unsigned char *readp;
+ unsigned char *readendp;
if (offset == 0)
{
Dwarf_Attribute attr_mem;
@@ -94,14 +141,12 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep,
/* No PC attributes in this DIE at all, so an empty range list. */
return 0;
- /* Must have the form data4 or data8 which act as an offset. */
Dwarf_Word start_offset;
- if (INTUSE(dwarf_formudata) (attr, &start_offset) != 0)
+ if ((readp = __libdw_formptr (attr, IDX_debug_ranges,
+ DWARF_E_NO_DEBUG_RANGES,
+ &readendp, &start_offset)) == NULL)
return -1;
- if (d == NULL)
- goto no_ranges;
-
offset = start_offset;
assert ((Dwarf_Word) offset == start_offset);
@@ -127,45 +172,37 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep,
return -1;
}
}
- else if (offset < 0 || (size_t) offset >= d->d_size)
+ else
{
- __libdw_seterrno (DWARF_E_INVALID_OFFSET);
- return -1l;
- }
+ if (__libdw_offset_in_section (die->cu->dbg,
+ IDX_debug_ranges, offset, 1))
+ return -1l;
- unsigned char *readp = d->d_buf + offset;
+ readp = d->d_buf + offset;
+ readendp = d->d_buf + d->d_size;
+ }
next:
- if ((unsigned char *) d->d_buf + d->d_size - readp
- < die->cu->address_size * 2)
+ if (readendp - readp < die->cu->address_size * 2)
goto invalid;
Dwarf_Addr begin;
Dwarf_Addr end;
- if (die->cu->address_size == 8)
- {
- begin = read_8ubyte_unaligned_inc (die->cu->dbg, readp);
- end = read_8ubyte_unaligned_inc (die->cu->dbg, readp);
- if (begin == (uint64_t) -1l) /* Base address entry. */
- {
- *basep = end;
- goto next;
- }
- }
- else
+
+ switch (__libdw_read_begin_end_pair_inc (die->cu->dbg, IDX_debug_ranges,
+ &readp, die->cu->address_size,
+ &begin, &end, basep))
{
- begin = read_4ubyte_unaligned_inc (die->cu->dbg, readp);
- end = read_4ubyte_unaligned_inc (die->cu->dbg, readp);
- if (begin == (uint32_t) -1) /* Base address entry. */
- {
- *basep = end;
- goto next;
- }
+ case 0:
+ break;
+ case 1:
+ goto next;
+ case 2:
+ return 0;
+ default:
+ return -1l;
}
- if (begin == 0 && end == 0) /* End of list entry. */
- return 0;
-
/* We have an address range entry. */
*startp = *basep + begin;
*endp = *basep + end;