bfd_vma        rva_bias)
 {
   unsigned long entry, addr, size;
+  bfd_byte * leaf;
 
   if (data + 8 >= regions->section_end)
     return regions->section_end + 1;
                                            regions, rva_bias);
     }
 
-  if (regions->section_start + entry + 16 >= regions->section_end)
+  leaf = regions->section_start + entry;
+
+  if (leaf + 16 >= regions->section_end
+      /* PR 17512: file: 055dff7e.  */
+      || leaf < regions->section_start)
     return regions->section_end + 1;
 
   fprintf (file, _("%03x %*.s  Leaf: Addr: %#08lx, Size: %#08lx, Codepage: %d\n"),
-          (int) (entry),
-          indent, " ",
-          addr = (long) bfd_get_32 (abfd, regions->section_start + entry),
-          size = (long) bfd_get_32 (abfd, regions->section_start + entry + 4),
-          (int) bfd_get_32 (abfd, regions->section_start + entry + 8));
+          (int) (entry), indent, " ",
+          addr = (long) bfd_get_32 (abfd, leaf),
+          size = (long) bfd_get_32 (abfd, leaf + 4),
+          (int) bfd_get_32 (abfd, leaf + 8));
 
   /* Check that the reserved entry is 0.  */
-  if (bfd_get_32 (abfd, regions->section_start + entry + 12) != 0
+  if (bfd_get_32 (abfd, leaf + 12) != 0
       /* And that the data address/size is valid too.  */
       || (regions->section_start + (addr - rva_bias) + size > regions->section_end))
     return regions->section_end + 1;
   if (entry->value.leaf == NULL)
     return dataend;
 
-  addr = bfd_get_32 (abfd, datastart + val);
-  size = entry->value.leaf->size = bfd_get_32 (abfd, datastart + val + 4);
-  entry->value.leaf->codepage = bfd_get_32 (abfd, datastart + val + 8);
+  data = datastart + val;
+  if (data < datastart || data >= dataend)
+    return dataend;
+
+  addr = bfd_get_32 (abfd, data);
+  size = entry->value.leaf->size = bfd_get_32 (abfd, data + 4);
+  entry->value.leaf->codepage = bfd_get_32 (abfd, data + 8);
+  /* FIXME: We assume that the reserved field (data + 12) is OK.  */
 
   entry->value.leaf->data = bfd_malloc (size);
   if (entry->value.leaf->data == NULL)
 
            {
              unsigned int reg, op, opa;
              unsigned long temp;
+             unsigned char * new_start;
 
              op = *start++;
              opa = op & 0x3f;
                  break;
                case DW_CFA_def_cfa_expression:
                  temp = LEB ();
-                 if (start + temp < start)
+                 new_start = start + temp;
+                 if (new_start < start)
                    {
                      warn (_("Corrupt CFA_def expression value: %lu\n"), temp);
                      start = block_end;
                    }
                  else
-                   start += temp;
+                   start = new_start;
                  break;
                case DW_CFA_expression:
                case DW_CFA_val_expression:
                  reg = LEB ();
                  temp = LEB ();
-                 if (start + temp < start)
+                 new_start = start + temp;
+                 if (new_start < start)
                    {
                      /* PR 17512: file:306-192417-0.005.  */ 
                      warn (_("Corrupt CFA expression value: %lu\n"), temp);
                      start = block_end;
                    }
                  else
-                   start += temp;
+                   start = new_start;
                  if (frame_need_space (fc, reg) >= 0)
                    fc->col_type[reg] = DW_CFA_undefined;
                  break;