Imported Upstream version 1.2
[platform/upstream/libunwind.git] / src / arm / Gex_tables.c
index 8004fb5..34706cf 100644 (file)
@@ -30,14 +30,14 @@ http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038a/IHI0038A_ehabi.pdf
 
 #include "libunwind_i.h"
 
-#define ARM_EXBUF_START(x)     (((x) >> 4) & 0x0f)
-#define ARM_EXBUF_COUNT(x)     ((x) & 0x0f)
-#define ARM_EXBUF_END(x)       (ARM_EXBUF_START(x) + ARM_EXBUF_COUNT(x))
+#define ARM_EXBUF_START(x)      (((x) >> 4) & 0x0f)
+#define ARM_EXBUF_COUNT(x)      ((x) & 0x0f)
+#define ARM_EXBUF_END(x)        (ARM_EXBUF_START(x) + ARM_EXBUF_COUNT(x))
 
-#define ARM_EXIDX_CANT_UNWIND  0x00000001
-#define ARM_EXIDX_COMPACT      0x80000000
+#define ARM_EXIDX_CANT_UNWIND   0x00000001
+#define ARM_EXIDX_COMPACT       0x80000000
 
-#define ARM_EXTBL_OP_FINISH    0xb0
+#define ARM_EXTBL_OP_FINISH     0xb0
 
 enum arm_exbuf_cmd_flags {
   ARM_EXIDX_VFP_SHIFT_16 = 1 << 16,
@@ -61,7 +61,7 @@ prel31_read (uint32_t prel31)
 
 static inline int
 prel31_to_addr (unw_addr_space_t as, void *arg, unw_word_t prel31,
-               unw_word_t *val)
+                unw_word_t *val)
 {
   unw_word_t offset;
 
@@ -88,7 +88,7 @@ arm_exidx_apply_cmd (struct arm_exbuf_data *edata, struct dwarf_cursor *c)
     case ARM_EXIDX_CMD_FINISH:
       /* Set LR to PC if not set already.  */
       if (DWARF_IS_NULL_LOC (c->loc[UNW_ARM_R15]))
-       c->loc[UNW_ARM_R15] = c->loc[UNW_ARM_R14];
+        c->loc[UNW_ARM_R15] = c->loc[UNW_ARM_R14];
       /* Set IP.  */
       dwarf_get (c, c->loc[UNW_ARM_R15], &c->ip);
       break;
@@ -102,15 +102,15 @@ arm_exidx_apply_cmd (struct arm_exbuf_data *edata, struct dwarf_cursor *c)
       break;
     case ARM_EXIDX_CMD_REG_POP:
       for (i = 0; i < 16; i++)
-       if (edata->data & (1 << i))
-         {
-           Debug (2, "pop {r%d}\n", i);
-           c->loc[UNW_ARM_R0 + i] = DWARF_LOC (c->cfa, 0);
-           c->cfa += 4;
-         }
+        if (edata->data & (1 << i))
+          {
+            Debug (2, "pop {r%d}\n", i);
+            c->loc[UNW_ARM_R0 + i] = DWARF_LOC (c->cfa, 0);
+            c->cfa += 4;
+          }
       /* Set cfa in case the SP got popped. */
       if (edata->data & (1 << 13))
-       dwarf_get (c, c->loc[UNW_ARM_R13], &c->cfa);
+        dwarf_get (c, c->loc[UNW_ARM_R13], &c->cfa);
       break;
     case ARM_EXIDX_CMD_REG_TO_SP:
       assert (edata->data < 16);
@@ -121,20 +121,20 @@ arm_exidx_apply_cmd (struct arm_exbuf_data *edata, struct dwarf_cursor *c)
     case ARM_EXIDX_CMD_VFP_POP:
       /* Skip VFP registers, but be sure to adjust stack */
       for (i = ARM_EXBUF_START (edata->data); i <= ARM_EXBUF_END (edata->data);
-          i++)
-       c->cfa += 8;
+           i++)
+        c->cfa += 8;
       if (!(edata->data & ARM_EXIDX_VFP_DOUBLE))
-       c->cfa += 4;
+        c->cfa += 4;
       break;
     case ARM_EXIDX_CMD_WREG_POP:
       for (i = ARM_EXBUF_START (edata->data); i <= ARM_EXBUF_END (edata->data);
-          i++)
-       c->cfa += 8;
+           i++)
+        c->cfa += 8;
       break;
     case ARM_EXIDX_CMD_WCGR_POP:
       for (i = 0; i < 4; i++)
-       if (edata->data & (1 << i))
-         c->cfa += 4;
+        if (edata->data & (1 << i))
+          c->cfa += 4;
       break;
     case ARM_EXIDX_CMD_REFUSED:
     case ARM_EXIDX_CMD_RESERVED:
@@ -163,119 +163,119 @@ arm_exidx_decode (const uint8_t *buf, uint8_t len, struct dwarf_cursor *c)
     {
       uint8_t op = READ_OP ();
       if ((op & 0xc0) == 0x00)
-       {
-         edata.cmd = ARM_EXIDX_CMD_DATA_POP;
-         edata.data = (((int)op & 0x3f) << 2) + 4;
-       }
+        {
+          edata.cmd = ARM_EXIDX_CMD_DATA_POP;
+          edata.data = (((int)op & 0x3f) << 2) + 4;
+        }
       else if ((op & 0xc0) == 0x40)
-       {
-         edata.cmd = ARM_EXIDX_CMD_DATA_PUSH;
-         edata.data = (((int)op & 0x3f) << 2) + 4;
-       }
+        {
+          edata.cmd = ARM_EXIDX_CMD_DATA_PUSH;
+          edata.data = (((int)op & 0x3f) << 2) + 4;
+        }
       else if ((op & 0xf0) == 0x80)
-       {
-         uint8_t op2 = READ_OP ();
-         if (op == 0x80 && op2 == 0x00)
-           edata.cmd = ARM_EXIDX_CMD_REFUSED;
-         else
-           {
-             edata.cmd = ARM_EXIDX_CMD_REG_POP;
-             edata.data = ((op & 0xf) << 8) | op2;
-             edata.data = edata.data << 4;
-           }
-       }
+        {
+          uint8_t op2 = READ_OP ();
+          if (op == 0x80 && op2 == 0x00)
+            edata.cmd = ARM_EXIDX_CMD_REFUSED;
+          else
+            {
+              edata.cmd = ARM_EXIDX_CMD_REG_POP;
+              edata.data = ((op & 0xf) << 8) | op2;
+              edata.data = edata.data << 4;
+            }
+        }
       else if ((op & 0xf0) == 0x90)
-       {
-         if (op == 0x9d || op == 0x9f)
-           edata.cmd = ARM_EXIDX_CMD_RESERVED;
-         else
-           {
-             edata.cmd = ARM_EXIDX_CMD_REG_TO_SP;
-             edata.data = op & 0x0f;
-           }
-       }
+        {
+          if (op == 0x9d || op == 0x9f)
+            edata.cmd = ARM_EXIDX_CMD_RESERVED;
+          else
+            {
+              edata.cmd = ARM_EXIDX_CMD_REG_TO_SP;
+              edata.data = op & 0x0f;
+            }
+        }
       else if ((op & 0xf0) == 0xa0)
-       {
-         unsigned end = (op & 0x07);
-         edata.data = (1 << (end + 1)) - 1;
-         edata.data = edata.data << 4;
-         if (op & 0x08)
-           edata.data |= 1 << 14;
-         edata.cmd = ARM_EXIDX_CMD_REG_POP;
-       }
+        {
+          unsigned end = (op & 0x07);
+          edata.data = (1 << (end + 1)) - 1;
+          edata.data = edata.data << 4;
+          if (op & 0x08)
+            edata.data |= 1 << 14;
+          edata.cmd = ARM_EXIDX_CMD_REG_POP;
+        }
       else if (op == ARM_EXTBL_OP_FINISH)
-       {
-         edata.cmd = ARM_EXIDX_CMD_FINISH;
-         buf = end;
-       }
+        {
+          edata.cmd = ARM_EXIDX_CMD_FINISH;
+          buf = end;
+        }
       else if (op == 0xb1)
-       {
-         uint8_t op2 = READ_OP ();
-         if (op2 == 0 || (op2 & 0xf0))
-           edata.cmd = ARM_EXIDX_CMD_RESERVED;
-         else
-           {
-             edata.cmd = ARM_EXIDX_CMD_REG_POP;
-             edata.data = op2 & 0x0f;
-           }
-       }
+        {
+          uint8_t op2 = READ_OP ();
+          if (op2 == 0 || (op2 & 0xf0))
+            edata.cmd = ARM_EXIDX_CMD_RESERVED;
+          else
+            {
+              edata.cmd = ARM_EXIDX_CMD_REG_POP;
+              edata.data = op2 & 0x0f;
+            }
+        }
       else if (op == 0xb2)
-       {
-         uint32_t offset = 0;
-         uint8_t byte, shift = 0;
-         do
-           {
-             byte = READ_OP ();
-             offset |= (byte & 0x7f) << shift;
-             shift += 7;
-           }
-         while (byte & 0x80);
-         edata.data = offset * 4 + 0x204;
-         edata.cmd = ARM_EXIDX_CMD_DATA_POP;
-       }
+        {
+          uint32_t offset = 0;
+          uint8_t byte, shift = 0;
+          do
+            {
+              byte = READ_OP ();
+              offset |= (byte & 0x7f) << shift;
+              shift += 7;
+            }
+          while (byte & 0x80);
+          edata.data = offset * 4 + 0x204;
+          edata.cmd = ARM_EXIDX_CMD_DATA_POP;
+        }
       else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
-       {
-         edata.cmd = ARM_EXIDX_CMD_VFP_POP;
-         edata.data = READ_OP ();
-         if (op == 0xc8)
-           edata.data |= ARM_EXIDX_VFP_SHIFT_16;
-         if (op != 0xb3)
-           edata.data |= ARM_EXIDX_VFP_DOUBLE;
-       }
+        {
+          edata.cmd = ARM_EXIDX_CMD_VFP_POP;
+          edata.data = READ_OP ();
+          if (op == 0xc8)
+            edata.data |= ARM_EXIDX_VFP_SHIFT_16;
+          if (op != 0xb3)
+            edata.data |= ARM_EXIDX_VFP_DOUBLE;
+        }
       else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
-       {
-         edata.cmd = ARM_EXIDX_CMD_VFP_POP;
-         edata.data = 0x80 | (op & 0x07);
-         if ((op & 0xf8) == 0xd0)
-           edata.data |= ARM_EXIDX_VFP_DOUBLE;
-       }
+        {
+          edata.cmd = ARM_EXIDX_CMD_VFP_POP;
+          edata.data = 0x80 | (op & 0x07);
+          if ((op & 0xf8) == 0xd0)
+            edata.data |= ARM_EXIDX_VFP_DOUBLE;
+        }
       else if (op >= 0xc0 && op <= 0xc5)
-       {
-         edata.cmd = ARM_EXIDX_CMD_WREG_POP;
-         edata.data = 0xa0 | (op & 0x07);
-       }
+        {
+          edata.cmd = ARM_EXIDX_CMD_WREG_POP;
+          edata.data = 0xa0 | (op & 0x07);
+        }
       else if (op == 0xc6)
-       {
-         edata.cmd = ARM_EXIDX_CMD_WREG_POP;
-         edata.data = READ_OP ();
-       }
+        {
+          edata.cmd = ARM_EXIDX_CMD_WREG_POP;
+          edata.data = READ_OP ();
+        }
       else if (op == 0xc7)
-       {
-         uint8_t op2 = READ_OP ();
-         if (op2 == 0 || (op2 & 0xf0))
-           edata.cmd = ARM_EXIDX_CMD_RESERVED;
-         else
-           {
-             edata.cmd = ARM_EXIDX_CMD_WCGR_POP;
-             edata.data = op2 & 0x0f;
-           }
-       }
+        {
+          uint8_t op2 = READ_OP ();
+          if (op2 == 0 || (op2 & 0xf0))
+            edata.cmd = ARM_EXIDX_CMD_RESERVED;
+          else
+            {
+              edata.cmd = ARM_EXIDX_CMD_WCGR_POP;
+              edata.data = op2 & 0x0f;
+            }
+        }
       else
-       edata.cmd = ARM_EXIDX_CMD_RESERVED;
+        edata.cmd = ARM_EXIDX_CMD_RESERVED;
 
       ret = arm_exidx_apply_cmd (&edata, c);
       if (ret < 0)
-       return ret;
+        return ret;
     }
   return 0;
 }
@@ -299,7 +299,7 @@ arm_exidx_extract (struct dwarf_cursor *c, uint8_t *buf)
        * if set to 0x1: the function cannot be unwound (EXIDX_CANTUNWIND)
        * if bit 31 is one: this is a table entry itself (ARM_EXIDX_COMPACT)
        * if bit 31 is zero: this is a prel31 offset of the start of the
-        table entry for this function  */
+         table entry for this function  */
   if (prel31_to_addr(c->as, c->as_arg, entry, &addr) < 0)
     return -UNW_EINVAL;
 
@@ -314,7 +314,7 @@ arm_exidx_extract (struct dwarf_cursor *c, uint8_t *buf)
   else if (data & ARM_EXIDX_COMPACT)
     {
       Debug (2, "%p compact model %d [%8.8x]\n", (void *)addr,
-            (data >> 24) & 0x7f, data);
+             (data >> 24) & 0x7f, data);
       buf[nbuf++] = data >> 16;
       buf[nbuf++] = data >> 8;
       buf[nbuf++] = data;
@@ -328,51 +328,51 @@ arm_exidx_extract (struct dwarf_cursor *c, uint8_t *buf)
         return -UNW_EINVAL;
 
       if ((*c->as->acc.access_mem)(c->as, extbl_data, &data, 0, c->as_arg) < 0)
-       return -UNW_EINVAL;
+        return -UNW_EINVAL;
 
       if (data & ARM_EXIDX_COMPACT)
-       {
-         int pers = (data >> 24) & 0x0f;
-         Debug (2, "%p compact model %d [%8.8x]\n", (void *)addr, pers, data);
-         if (pers == 1 || pers == 2)
-           {
-             n_table_words = (data >> 16) & 0xff;
-             extbl_data += 4;
-           }
-         else
-           buf[nbuf++] = data >> 16;
-         buf[nbuf++] = data >> 8;
-         buf[nbuf++] = data;
-       }
+        {
+          int pers = (data >> 24) & 0x0f;
+          Debug (2, "%p compact model %d [%8.8x]\n", (void *)addr, pers, data);
+          if (pers == 1 || pers == 2)
+            {
+              n_table_words = (data >> 16) & 0xff;
+              extbl_data += 4;
+            }
+          else
+            buf[nbuf++] = data >> 16;
+          buf[nbuf++] = data >> 8;
+          buf[nbuf++] = data;
+        }
       else
-       {
-         unw_word_t pers;
-         if (prel31_to_addr (c->as, c->as_arg, extbl_data, &pers) < 0)
-           return -UNW_EINVAL;
-         Debug (2, "%p Personality routine: %8p\n", (void *)addr,
-                (void *)pers);
-         if ((*c->as->acc.access_mem)(c->as, extbl_data + 4, &data, 0,
-                                      c->as_arg) < 0)
-           return -UNW_EINVAL;
-         n_table_words = data >> 24;
-         buf[nbuf++] = data >> 16;
-         buf[nbuf++] = data >> 8;
-         buf[nbuf++] = data;
-         extbl_data += 8;
-       }
+        {
+          unw_word_t pers;
+          if (prel31_to_addr (c->as, c->as_arg, extbl_data, &pers) < 0)
+            return -UNW_EINVAL;
+          Debug (2, "%p Personality routine: %8p\n", (void *)addr,
+                 (void *)pers);
+          if ((*c->as->acc.access_mem)(c->as, extbl_data + 4, &data, 0,
+                                       c->as_arg) < 0)
+            return -UNW_EINVAL;
+          n_table_words = data >> 24;
+          buf[nbuf++] = data >> 16;
+          buf[nbuf++] = data >> 8;
+          buf[nbuf++] = data;
+          extbl_data += 8;
+        }
       assert (n_table_words <= 5);
       unsigned j;
       for (j = 0; j < n_table_words; j++)
-       {
-         if ((*c->as->acc.access_mem)(c->as, extbl_data, &data, 0,
-                                      c->as_arg) < 0)
-           return -UNW_EINVAL;
-         extbl_data += 4;
-         buf[nbuf++] = data >> 24;
-         buf[nbuf++] = data >> 16;
-         buf[nbuf++] = data >> 8;
-         buf[nbuf++] = data >> 0;
-       }
+        {
+          if ((*c->as->acc.access_mem)(c->as, extbl_data, &data, 0,
+                                       c->as_arg) < 0)
+            return -UNW_EINVAL;
+          extbl_data += 4;
+          buf[nbuf++] = data >> 24;
+          buf[nbuf++] = data >> 16;
+          buf[nbuf++] = data >> 8;
+          buf[nbuf++] = data >> 0;
+        }
     }
 
   if (nbuf > 0 && buf[nbuf - 1] != ARM_EXTBL_OP_FINISH)
@@ -383,71 +383,71 @@ arm_exidx_extract (struct dwarf_cursor *c, uint8_t *buf)
 
 PROTECTED int
 tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
-                            unw_dyn_info_t *di, unw_proc_info_t *pi,
-                            int need_unwind_info, void *arg)
+                             unw_dyn_info_t *di, unw_proc_info_t *pi,
+                             int need_unwind_info, void *arg)
 {
   if (UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX)
       && di->format == UNW_INFO_FORMAT_ARM_EXIDX)
     {
       /* The .ARM.exidx section contains a sorted list of key-value pairs -
-        the unwind entries.  The 'key' is a prel31 offset to the start of a
-        function.  We binary search this section in order to find the
-        appropriate unwind entry.  */
+         the unwind entries.  The 'key' is a prel31 offset to the start of a
+         function.  We binary search this section in order to find the
+         appropriate unwind entry.  */
       unw_word_t first = di->u.rti.table_data;
       unw_word_t last = di->u.rti.table_data + di->u.rti.table_len - 8;
       unw_word_t entry, val;
 
       if (prel31_to_addr (as, arg, first, &val) < 0 || ip < val)
-       return -UNW_ENOINFO;
+        return -UNW_ENOINFO;
 
       if (prel31_to_addr (as, arg, last, &val) < 0)
-       return -UNW_EINVAL;
+        return -UNW_EINVAL;
 
       if (ip >= val)
-       {
-         entry = last;
+        {
+          entry = last;
 
-         if (prel31_to_addr (as, arg, last, &pi->start_ip) < 0)
-           return -UNW_EINVAL;
+          if (prel31_to_addr (as, arg, last, &pi->start_ip) < 0)
+            return -UNW_EINVAL;
 
-         pi->end_ip = di->end_ip -1;
-       }
+          pi->end_ip = di->end_ip -1;
+        }
       else
-       {
-         while (first < last - 8)
-           {
-             entry = first + (((last - first) / 8 + 1) >> 1) * 8;
+        {
+          while (first < last - 8)
+            {
+              entry = first + (((last - first) / 8 + 1) >> 1) * 8;
 
-             if (prel31_to_addr (as, arg, entry, &val) < 0)
-               return -UNW_EINVAL;
+              if (prel31_to_addr (as, arg, entry, &val) < 0)
+                return -UNW_EINVAL;
 
-             if (ip < val)
-               last = entry;
-             else
-               first = entry;
-           }
+              if (ip < val)
+                last = entry;
+              else
+                first = entry;
+            }
 
-         entry = first;
+          entry = first;
 
-         if (prel31_to_addr (as, arg, entry, &pi->start_ip) < 0)
-           return -UNW_EINVAL;
+          if (prel31_to_addr (as, arg, entry, &pi->start_ip) < 0)
+            return -UNW_EINVAL;
 
-         if (prel31_to_addr (as, arg, entry + 8, &pi->end_ip) < 0)
-           return -UNW_EINVAL;
+          if (prel31_to_addr (as, arg, entry + 8, &pi->end_ip) < 0)
+            return -UNW_EINVAL;
 
-         pi->end_ip--;
-       }
+          pi->end_ip--;
+        }
 
       if (need_unwind_info)
-       {
-         pi->unwind_info_size = 8;
-         pi->unwind_info = (void *) entry;
-         pi->format = UNW_INFO_FORMAT_ARM_EXIDX;
-       }
+        {
+          pi->unwind_info_size = 8;
+          pi->unwind_info = (void *) entry;
+          pi->format = UNW_INFO_FORMAT_ARM_EXIDX;
+        }
       return 0;
     }
   else if (UNW_TRY_METHOD(UNW_ARM_METHOD_DWARF)
-          && di->format != UNW_INFO_FORMAT_ARM_EXIDX)
+           && di->format != UNW_INFO_FORMAT_ARM_EXIDX)
     return dwarf_search_unwind_table (as, ip, di, pi, need_unwind_info, arg);
 
   return -UNW_ENOINFO; 
@@ -469,20 +469,20 @@ arm_phdr_cb (struct dl_phdr_info *info, size_t size, void *data)
   for (n = info->dlpi_phnum; --n >= 0; phdr++)
     {
       switch (phdr->p_type)
-       {
-       case PT_LOAD:
-         if (cb_data->ip >= phdr->p_vaddr + info->dlpi_addr &&
-             cb_data->ip < phdr->p_vaddr + info->dlpi_addr + phdr->p_memsz)
-           p_text = phdr;
-         break;
-
-       case PT_ARM_EXIDX:
-         p_arm_exidx = phdr;
-         break;
-
-       default:
-         break;
-       }
+        {
+        case PT_LOAD:
+          if (cb_data->ip >= phdr->p_vaddr + info->dlpi_addr &&
+              cb_data->ip < phdr->p_vaddr + info->dlpi_addr + phdr->p_memsz)
+            p_text = phdr;
+          break;
+
+        case PT_ARM_EXIDX:
+          p_arm_exidx = phdr;
+          break;
+
+        default:
+          break;
+        }
     }
 
   if (p_text && p_arm_exidx)
@@ -501,7 +501,7 @@ arm_phdr_cb (struct dl_phdr_info *info, size_t size, void *data)
 
 HIDDEN int
 arm_find_proc_info (unw_addr_space_t as, unw_word_t ip,
-                   unw_proc_info_t *pi, int need_unwind_info, void *arg)
+                    unw_proc_info_t *pi, int need_unwind_info, void *arg)
 {
   int ret = -1;
   intrmask_t saved_mask;
@@ -524,14 +524,14 @@ arm_find_proc_info (unw_addr_space_t as, unw_word_t ip,
       SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL);
 
       if (cb_data.single_fde)
-       /* already got the result in *pi */
-       return 0;
+        /* already got the result in *pi */
+        return 0;
 
       if (cb_data.di_debug.format != -1)
-       ret = tdep_search_unwind_table (as, ip, &cb_data.di_debug, pi,
-                                       need_unwind_info, arg);
+        ret = tdep_search_unwind_table (as, ip, &cb_data.di_debug, pi,
+                                        need_unwind_info, arg);
       else
-       ret = -UNW_ENOINFO;
+        ret = -UNW_ENOINFO;
     }
 
   if (ret < 0 && UNW_TRY_METHOD (UNW_ARM_METHOD_EXIDX))
@@ -548,10 +548,10 @@ arm_find_proc_info (unw_addr_space_t as, unw_word_t ip,
       SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL);
 
       if (cb_data.di.format != -1)
-       ret = tdep_search_unwind_table (as, ip, &cb_data.di, pi,
-                                       need_unwind_info, arg);
+        ret = tdep_search_unwind_table (as, ip, &cb_data.di, pi,
+                                        need_unwind_info, arg);
       else
-       ret = -UNW_ENOINFO;
+        ret = -UNW_ENOINFO;
     }
 
   if (ret < 0)