daily update
[deliverable/binutils-gdb.git] / bfd / elfarm-nabi.c
index 38778b73be3a4bfdd16df7bf76f95dbcbda0dbb9..7ced68073652ba6965a7ad6f31482de314caab3c 100644 (file)
@@ -1,5 +1,5 @@
 /* 32-bit ELF support for ARM new abi option.
 /* 32-bit ELF support for ARM new abi option.
-   Copyright 1999 Free Software Foundation, Inc.
+   Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
 
    This file is part of BFD, the Binary File Descriptor library.
 
 
 static reloc_howto_type * elf32_arm_reloc_type_lookup
   PARAMS ((bfd * abfd, bfd_reloc_code_real_type code));
 
 static reloc_howto_type * elf32_arm_reloc_type_lookup
   PARAMS ((bfd * abfd, bfd_reloc_code_real_type code));
+static boolean elf32_arm_nabi_grok_prstatus
+  PARAMS ((bfd *abfd, Elf_Internal_Note *note));
+static boolean elf32_arm_nabi_grok_psinfo
+  PARAMS ((bfd *abfd, Elf_Internal_Note *note));
+
+/* Note: code such as elf32_arm_reloc_type_lookup expect to use e.g.
+   R_ARM_PC24 as an index into this, and find the R_ARM_PC24 HOWTO
+   in that slot.  */
 
 static reloc_howto_type elf32_arm_howto_table[] =
 {
 
 static reloc_howto_type elf32_arm_howto_table[] =
 {
@@ -262,36 +270,36 @@ static reloc_howto_type elf32_arm_howto_table[] =
         0x00000000,            /* dst_mask */
         false),                /* pcrel_offset */
 
         0x00000000,            /* dst_mask */
         false),                /* pcrel_offset */
 
-  /* These next two relocs are defined, but I do not know what they do.  */
-  
+  /* BLX instruction for the ARM.  */
   HOWTO (R_ARM_XPC25,          /* type */
   HOWTO (R_ARM_XPC25,          /* type */
-        0,                     /* rightshift */
-        0,                     /* size (0 = byte, 1 = short, 2 = long) */
-        0,                     /* bitsize */
-        false,                 /* pc_relative */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        25,                    /* bitsize */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_XPC25",         /* name */
         false,                 /* partial_inplace */
         0,                     /* bitpos */
         complain_overflow_signed,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_XPC25",         /* name */
         false,                 /* partial_inplace */
-        0x00000000,            /* src_mask */
-        0x00000000,            /* dst_mask */
-        false),                /* pcrel_offset */
+        0x00ffffff,            /* src_mask */
+        0x00ffffff,            /* dst_mask */
+        true),                 /* pcrel_offset */
 
 
+  /* BLX instruction for the Thumb.  */
   HOWTO (R_ARM_THM_XPC22,      /* type */
   HOWTO (R_ARM_THM_XPC22,      /* type */
-        0,                     /* rightshift */
-        0,                     /* size (0 = byte, 1 = short, 2 = long) */
-        0,                     /* bitsize */
-        false,                 /* pc_relative */
+        2,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        22,                    /* bitsize */
+        true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_XPC22",     /* name */
         false,                 /* partial_inplace */
         0,                     /* bitpos */
         complain_overflow_signed,/* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_ARM_THM_XPC22",     /* name */
         false,                 /* partial_inplace */
-        0x00000000,            /* src_mask */
-        0x00000000,            /* dst_mask */
-        false),                /* pcrel_offset */
-  
+        0x07ff07ff,            /* src_mask */
+        0x07ff07ff,            /* dst_mask */
+        true),                 /* pcrel_offset */
+
   /* These next three relocs are not defined, but we need to fill the space.  */
 
   HOWTO (R_ARM_NONE,           /* type */
   /* These next three relocs are not defined, but we need to fill the space.  */
 
   HOWTO (R_ARM_NONE,           /* type */
@@ -337,7 +345,7 @@ static reloc_howto_type elf32_arm_howto_table[] =
         false),                /* pcrel_offset */
 
   /* Relocs used in ARM Linux */
         false),                /* pcrel_offset */
 
   /* Relocs used in ARM Linux */
-  
+
   HOWTO (R_ARM_COPY,           /* type */
          0,                     /* rightshift */
          2,                     /* size (0 = byte, 1 = short, 2 = long) */
   HOWTO (R_ARM_COPY,           /* type */
          0,                     /* rightshift */
          2,                     /* size (0 = byte, 1 = short, 2 = long) */
@@ -365,7 +373,7 @@ static reloc_howto_type elf32_arm_howto_table[] =
          0xffffffff,           /* src_mask */
          0xffffffff,           /* dst_mask */
          false),                /* pcrel_offset */
          0xffffffff,           /* src_mask */
          0xffffffff,           /* dst_mask */
          false),                /* pcrel_offset */
-         
+
   HOWTO (R_ARM_JUMP_SLOT,      /* type */
          0,                     /* rightshift */
          2,                     /* size (0 = byte, 1 = short, 2 = long) */
   HOWTO (R_ARM_JUMP_SLOT,      /* type */
          0,                     /* rightshift */
          2,                     /* size (0 = byte, 1 = short, 2 = long) */
@@ -379,7 +387,7 @@ static reloc_howto_type elf32_arm_howto_table[] =
          0xffffffff,           /* src_mask */
          0xffffffff,           /* dst_mask */
          false),                /* pcrel_offset */
          0xffffffff,           /* src_mask */
          0xffffffff,           /* dst_mask */
          false),                /* pcrel_offset */
-         
+
   HOWTO (R_ARM_RELATIVE,       /* type */
          0,                     /* rightshift */
          2,                     /* size (0 = byte, 1 = short, 2 = long) */
   HOWTO (R_ARM_RELATIVE,       /* type */
          0,                     /* rightshift */
          2,                     /* size (0 = byte, 1 = short, 2 = long) */
@@ -393,7 +401,7 @@ static reloc_howto_type elf32_arm_howto_table[] =
          0xffffffff,           /* src_mask */
          0xffffffff,           /* dst_mask */
          false),                /* pcrel_offset */
          0xffffffff,           /* src_mask */
          0xffffffff,           /* dst_mask */
          false),                /* pcrel_offset */
-         
+
   HOWTO (R_ARM_GOTOFF,         /* type */
          0,                     /* rightshift */
          2,                     /* size (0 = byte, 1 = short, 2 = long) */
   HOWTO (R_ARM_GOTOFF,         /* type */
          0,                     /* rightshift */
          2,                     /* size (0 = byte, 1 = short, 2 = long) */
@@ -407,7 +415,7 @@ static reloc_howto_type elf32_arm_howto_table[] =
          0xffffffff,           /* src_mask */
          0xffffffff,           /* dst_mask */
          false),                /* pcrel_offset */
          0xffffffff,           /* src_mask */
          0xffffffff,           /* dst_mask */
          false),                /* pcrel_offset */
-         
+
   HOWTO (R_ARM_GOTPC,          /* type */
          0,                     /* rightshift */
          2,                     /* size (0 = byte, 1 = short, 2 = long) */
   HOWTO (R_ARM_GOTPC,          /* type */
          0,                     /* rightshift */
          2,                     /* size (0 = byte, 1 = short, 2 = long) */
@@ -421,7 +429,7 @@ static reloc_howto_type elf32_arm_howto_table[] =
          0xffffffff,           /* src_mask */
          0xffffffff,           /* dst_mask */
          true),                        /* pcrel_offset */
          0xffffffff,           /* src_mask */
          0xffffffff,           /* dst_mask */
          true),                        /* pcrel_offset */
-         
+
   HOWTO (R_ARM_GOT32,          /* type */
          0,                     /* rightshift */
          2,                     /* size (0 = byte, 1 = short, 2 = long) */
   HOWTO (R_ARM_GOT32,          /* type */
          0,                     /* rightshift */
          2,                     /* size (0 = byte, 1 = short, 2 = long) */
@@ -435,7 +443,7 @@ static reloc_howto_type elf32_arm_howto_table[] =
          0xffffffff,           /* src_mask */
          0xffffffff,           /* dst_mask */
          false),               /* pcrel_offset */
          0xffffffff,           /* src_mask */
          0xffffffff,           /* dst_mask */
          false),               /* pcrel_offset */
-         
+
   HOWTO (R_ARM_PLT32,          /* type */
          2,                     /* rightshift */
          2,                     /* size (0 = byte, 1 = short, 2 = long) */
   HOWTO (R_ARM_PLT32,          /* type */
          2,                     /* rightshift */
          2,                     /* size (0 = byte, 1 = short, 2 = long) */
@@ -449,8 +457,8 @@ static reloc_howto_type elf32_arm_howto_table[] =
          0x00ffffff,           /* src_mask */
          0x00ffffff,           /* dst_mask */
          true),                        /* pcrel_offset */
          0x00ffffff,           /* src_mask */
          0x00ffffff,           /* dst_mask */
          true),                        /* pcrel_offset */
-  
-  /* End of relocs used in ARM Linux */ 
+
+  /* End of relocs used in ARM Linux */
 
   HOWTO (R_ARM_RREL32,         /* type */
         0,                     /* rightshift */
 
   HOWTO (R_ARM_RREL32,         /* type */
         0,                     /* rightshift */
@@ -574,7 +582,9 @@ static reloc_howto_type elf32_arm_thm_pc9_howto =
         0x000000ff,            /* dst_mask */
         true);                 /* pcrel_offset */
 
         0x000000ff,            /* dst_mask */
         true);                 /* pcrel_offset */
 
+static void elf32_arm_info_to_howto
+  PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
+
 static void
 elf32_arm_info_to_howto (abfd, bfd_reloc, elf_reloc)
      bfd * abfd ATTRIBUTE_UNUSED;
 static void
 elf32_arm_info_to_howto (abfd, bfd_reloc, elf_reloc)
      bfd * abfd ATTRIBUTE_UNUSED;
@@ -582,7 +592,7 @@ elf32_arm_info_to_howto (abfd, bfd_reloc, elf_reloc)
      Elf32_Internal_Rel * elf_reloc;
 {
   unsigned int r_type;
      Elf32_Internal_Rel * elf_reloc;
 {
   unsigned int r_type;
-  
+
   r_type = ELF32_R_TYPE (elf_reloc->r_info);
 
   switch (r_type)
   r_type = ELF32_R_TYPE (elf_reloc->r_info);
 
   switch (r_type)
@@ -590,19 +600,19 @@ elf32_arm_info_to_howto (abfd, bfd_reloc, elf_reloc)
     case R_ARM_GNU_VTINHERIT:
       bfd_reloc->howto = & elf32_arm_vtinherit_howto;
       break;
     case R_ARM_GNU_VTINHERIT:
       bfd_reloc->howto = & elf32_arm_vtinherit_howto;
       break;
-      
+
     case R_ARM_GNU_VTENTRY:
       bfd_reloc->howto = & elf32_arm_vtentry_howto;
       break;
     case R_ARM_GNU_VTENTRY:
       bfd_reloc->howto = & elf32_arm_vtentry_howto;
       break;
-      
+
     case R_ARM_THM_PC11:
       bfd_reloc->howto = & elf32_arm_thm_pc11_howto;
       break;
     case R_ARM_THM_PC11:
       bfd_reloc->howto = & elf32_arm_thm_pc11_howto;
       break;
-      
+
     case R_ARM_THM_PC9:
       bfd_reloc->howto = & elf32_arm_thm_pc9_howto;
       break;
     case R_ARM_THM_PC9:
       bfd_reloc->howto = & elf32_arm_thm_pc9_howto;
       break;
-      
+
     default:
       if (r_type >= NUM_ELEM (elf32_arm_howto_table))
        bfd_reloc->howto = NULL;
     default:
       if (r_type >= NUM_ELEM (elf32_arm_howto_table))
        bfd_reloc->howto = NULL;
@@ -611,7 +621,7 @@ elf32_arm_info_to_howto (abfd, bfd_reloc, elf_reloc)
       break;
     }
 }
       break;
     }
 }
-  
+
 struct elf32_arm_reloc_map
   {
     bfd_reloc_code_real_type  bfd_reloc_val;
 struct elf32_arm_reloc_map
   {
     bfd_reloc_code_real_type  bfd_reloc_val;
@@ -619,25 +629,27 @@ struct elf32_arm_reloc_map
   };
 
 static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
   };
 
 static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
-{
-  {BFD_RELOC_NONE,                 R_ARM_NONE},
-  {BFD_RELOC_ARM_PCREL_BRANCH,     R_ARM_PC24},
-  {BFD_RELOC_32,                   R_ARM_ABS32},
-  {BFD_RELOC_32_PCREL,             R_ARM_REL32},
-  {BFD_RELOC_8,                    R_ARM_ABS8},
-  {BFD_RELOC_16,                   R_ARM_ABS16},
-  {BFD_RELOC_ARM_OFFSET_IMM,       R_ARM_ABS12},
-  {BFD_RELOC_ARM_THUMB_OFFSET,     R_ARM_THM_ABS5},
-  {BFD_RELOC_THUMB_PCREL_BRANCH23, R_ARM_THM_PC22},
-  {BFD_RELOC_ARM_COPY,             R_ARM_COPY},
-  {BFD_RELOC_ARM_GLOB_DAT,         R_ARM_GLOB_DAT},
-  {BFD_RELOC_ARM_JUMP_SLOT,        R_ARM_JUMP_SLOT},
-  {BFD_RELOC_ARM_RELATIVE,         R_ARM_RELATIVE},
-  {BFD_RELOC_ARM_GOTOFF,           R_ARM_GOTOFF},
-  {BFD_RELOC_ARM_GOTPC,            R_ARM_GOTPC},
-  {BFD_RELOC_ARM_GOT32,            R_ARM_GOT32},
-  {BFD_RELOC_ARM_PLT32,            R_ARM_PLT32}
-};
+  {
+    {BFD_RELOC_NONE,                 R_ARM_NONE},
+    {BFD_RELOC_ARM_PCREL_BRANCH,     R_ARM_PC24},
+    {BFD_RELOC_ARM_PCREL_BLX,        R_ARM_XPC25},
+    {BFD_RELOC_THUMB_PCREL_BLX,      R_ARM_THM_XPC22},
+    {BFD_RELOC_32,                   R_ARM_ABS32},
+    {BFD_RELOC_32_PCREL,             R_ARM_REL32},
+    {BFD_RELOC_8,                    R_ARM_ABS8},
+    {BFD_RELOC_16,                   R_ARM_ABS16},
+    {BFD_RELOC_ARM_OFFSET_IMM,       R_ARM_ABS12},
+    {BFD_RELOC_ARM_THUMB_OFFSET,     R_ARM_THM_ABS5},
+    {BFD_RELOC_THUMB_PCREL_BRANCH23, R_ARM_THM_PC22},
+    {BFD_RELOC_ARM_COPY,             R_ARM_COPY},
+    {BFD_RELOC_ARM_GLOB_DAT,         R_ARM_GLOB_DAT},
+    {BFD_RELOC_ARM_JUMP_SLOT,        R_ARM_JUMP_SLOT},
+    {BFD_RELOC_ARM_RELATIVE,         R_ARM_RELATIVE},
+    {BFD_RELOC_ARM_GOTOFF,           R_ARM_GOTOFF},
+    {BFD_RELOC_ARM_GOTPC,            R_ARM_GOTPC},
+    {BFD_RELOC_ARM_GOT32,            R_ARM_GOT32},
+    {BFD_RELOC_ARM_PLT32,            R_ARM_PLT32}
+  };
 
 static reloc_howto_type *
 elf32_arm_reloc_type_lookup (abfd, code)
 
 static reloc_howto_type *
 elf32_arm_reloc_type_lookup (abfd, code)
@@ -664,9 +676,77 @@ elf32_arm_reloc_type_lookup (abfd, code)
       for (i = 0; i < NUM_ELEM (elf32_arm_reloc_map); i ++)
        if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
          return & elf32_arm_howto_table[elf32_arm_reloc_map[i].elf_reloc_val];
       for (i = 0; i < NUM_ELEM (elf32_arm_reloc_map); i ++)
        if (elf32_arm_reloc_map[i].bfd_reloc_val == code)
          return & elf32_arm_howto_table[elf32_arm_reloc_map[i].elf_reloc_val];
-      
+
       return NULL;
    }
 }
 
       return NULL;
    }
 }
 
+/* Support for core dump NOTE sections */
+static boolean
+elf32_arm_nabi_grok_prstatus (abfd, note)
+     bfd *abfd;
+     Elf_Internal_Note *note;
+{
+  int offset;
+  size_t raw_size;
+
+  switch (note->descsz)
+    {
+      default:
+       return false;
+
+      case 148:                /* Linux/ARM 32-bit*/
+       /* pr_cursig */
+       elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
+
+       /* pr_pid */
+       elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
+
+       /* pr_reg */
+       offset = 72;
+       raw_size = 72;
+
+       break;
+    }
+
+  /* Make a ".reg/999" section.  */
+  return _bfd_elfcore_make_pseudosection (abfd, ".reg",
+                                         raw_size, note->descpos + offset);
+}
+
+static boolean
+elf32_arm_nabi_grok_psinfo (abfd, note)
+     bfd *abfd;
+     Elf_Internal_Note *note;
+{
+  switch (note->descsz)
+    {
+      default:
+       return false;
+
+      case 124:                /* Linux/ARM elf_prpsinfo */
+       elf_tdata (abfd)->core_program
+        = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
+       elf_tdata (abfd)->core_command
+        = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
+    }
+
+  /* Note that for some reason, a spurious space is tacked
+     onto the end of the args in some (at least one anyway)
+     implementations, so strip it off if it exists.  */
+
+  {
+    char *command = elf_tdata (abfd)->core_command;
+    int n = strlen (command);
+
+    if (0 < n && command[n - 1] == ' ')
+      command[n - 1] = '\0';
+  }
+
+  return true;
+}
+
+#define elf_backend_grok_prstatus      elf32_arm_nabi_grok_prstatus
+#define elf_backend_grok_psinfo                elf32_arm_nabi_grok_psinfo
+
 #include "elf32-arm.h"
 #include "elf32-arm.h"
This page took 0.027632 seconds and 4 git commands to generate.