Merge branch 'master' into merge-job
[deliverable/binutils-gdb.git] / bfd / elf32-msp430.c
index 9f2a3d07b8ec8e4b93381f008eba01d448ea281b..184f01d4ee4bbe8e3739ac7eb42322ea46a384ab 100644 (file)
@@ -1,5 +1,5 @@
 /*  MSP430-specific support for 32-bit ELF
-    Copyright (C) 2002-2018 Free Software Foundation, Inc.
+    Copyright (C) 2002-2020 Free Software Foundation, Inc.
     Contributed by Dmitry Diky <diwil@mail.ru>
 
     This file is part of BFD, the Binary File Descriptor library.
@@ -26,6 +26,9 @@
 #include "elf-bfd.h"
 #include "elf/msp430.h"
 
+/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
+#define OCTETS_PER_BYTE(ABFD, SEC) 1
+
 static bfd_reloc_status_type
 rl78_sym_diff_handler (bfd * abfd,
                       arelent * reloc,
@@ -36,7 +39,7 @@ rl78_sym_diff_handler (bfd * abfd,
                       char ** error_message ATTRIBUTE_UNUSED)
 {
   bfd_size_type octets;
-  octets = reloc->address * bfd_octets_per_byte (abfd);
+  octets = reloc->address * OCTETS_PER_BYTE (abfd, input_sec);
 
   /* Catch the case where bfd_install_relocation would return
      bfd_reloc_outofrange because the SYM_DIFF reloc is being used in a very
@@ -631,7 +634,7 @@ bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
 
 /* Set the howto pointer for an MSP430 ELF reloc.  */
 
-static void
+static bfd_boolean
 msp430_info_to_howto_rela (bfd * abfd,
                           arelent * cache_ptr,
                           Elf_Internal_Rela * dst)
@@ -647,20 +650,23 @@ msp430_info_to_howto_rela (bfd * abfd,
          /* xgettext:c-format */
          _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
                              abfd, r_type);
-         r_type = 0;
+         bfd_set_error (bfd_error_bad_value);
+         return FALSE;
        }
       cache_ptr->howto = elf_msp430x_howto_table + r_type;
-      return;
     }
-
-  if (r_type >= (unsigned int) R_MSP430_max)
+  else if (r_type >= (unsigned int) R_MSP430_max)
     {
       /* xgettext:c-format */
       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
                          abfd, r_type);
-      r_type = 0;
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
     }
-  cache_ptr->howto = &elf_msp430_howto_table[r_type];
+  else
+    cache_ptr->howto = &elf_msp430_howto_table[r_type];
+
+  return TRUE;
 }
 
 /* Look through the relocs for a section during the first phase.
@@ -1311,7 +1317,7 @@ elf32_msp430_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
 
          name = bfd_elf_string_from_elf_section
              (input_bfd, symtab_hdr->sh_link, sym->st_name);
-         name = (name == NULL || * name == 0) ? bfd_section_name (input_bfd, sec) : name;
+         name = name == NULL || *name == 0 ? bfd_section_name (sec) : name;
        }
       else
        {
@@ -1382,9 +1388,8 @@ elf32_msp430_relocate_section (bfd * output_bfd ATTRIBUTE_UNUSED,
    file.  This gets the MSP430 architecture right based on the machine
    number.  */
 
-static void
-bfd_elf_msp430_final_write_processing (bfd * abfd,
-                                      bfd_boolean linker ATTRIBUTE_UNUSED)
+static bfd_boolean
+bfd_elf_msp430_final_write_processing (bfd *abfd)
 {
   unsigned long val;
 
@@ -1419,6 +1424,7 @@ bfd_elf_msp430_final_write_processing (bfd * abfd,
   elf_elfheader (abfd)->e_machine = EM_MSP430;
   elf_elfheader (abfd)->e_flags &= ~EF_MSP430_MACH;
   elf_elfheader (abfd)->e_flags |= val;
+  return _bfd_elf_final_write_processing (abfd);
 }
 
 /* Set the right machine number.  */
@@ -1688,7 +1694,7 @@ msp430_elf_relax_delete_bytes (bfd * abfd, asection * sec, bfd_vma addr,
 
       name = bfd_elf_string_from_elf_section
        (abfd, symtab_hdr->sh_link, isym->st_name);
-      name = (name == NULL || * name == 0) ? bfd_section_name (abfd, sec) : name;
+      name = name == NULL || *name == 0 ? bfd_section_name (sec) : name;
 
       if (isym->st_shndx != sec_shndx)
        continue;
@@ -2405,15 +2411,15 @@ data_model (int model)
     }
 }
 
-/* Merge MSPABI object attributes from IBFD into OBFD.
+/* Merge MSPABI and GNU object attributes from IBFD into OBFD.
    Raise an error if there are conflicting attributes.  */
 
 static bfd_boolean
-elf32_msp430_merge_mspabi_attributes (bfd *ibfd, struct bfd_link_info *info)
+elf32_msp430_merge_msp430_attributes (bfd *ibfd, struct bfd_link_info *info)
 {
   bfd *obfd = info->output_bfd;
-  obj_attribute *in_attr;
-  obj_attribute *out_attr;
+  obj_attribute *in_msp_attr, *in_gnu_attr;
+  obj_attribute *out_msp_attr, *out_gnu_attr;
   bfd_boolean result = TRUE;
   static bfd * first_input_bfd = NULL;
 
@@ -2421,50 +2427,59 @@ elf32_msp430_merge_mspabi_attributes (bfd *ibfd, struct bfd_link_info *info)
   if (ibfd->flags & BFD_LINKER_CREATED)
     return TRUE;
 
+  /* LTO can create temporary files for linking which may not have an attribute
+     section.  */
+  if (ibfd->lto_output
+      && bfd_get_section_by_name (ibfd, ".MSP430.attributes") == NULL)
+    return TRUE;
+
   /* If this is the first real object just copy the attributes.  */
   if (!elf_known_obj_attributes_proc (obfd)[0].i)
     {
       _bfd_elf_copy_obj_attributes (ibfd, obfd);
 
-      out_attr = elf_known_obj_attributes_proc (obfd);
+      out_msp_attr = elf_known_obj_attributes_proc (obfd);
 
       /* Use the Tag_null value to indicate that
         the attributes have been initialized.  */
-      out_attr[0].i = 1;
+      out_msp_attr[0].i = 1;
 
       first_input_bfd = ibfd;
       return TRUE;
     }
 
-  in_attr = elf_known_obj_attributes_proc (ibfd);
-  out_attr = elf_known_obj_attributes_proc (obfd);
+  in_msp_attr = elf_known_obj_attributes_proc (ibfd);
+  out_msp_attr = elf_known_obj_attributes_proc (obfd);
+  in_gnu_attr = elf_known_obj_attributes (ibfd) [OBJ_ATTR_GNU];
+  out_gnu_attr = elf_known_obj_attributes (obfd) [OBJ_ATTR_GNU];
 
   /* The ISAs must be the same.  */
-  if (in_attr[OFBA_MSPABI_Tag_ISA].i != out_attr[OFBA_MSPABI_Tag_ISA].i)
+  if (in_msp_attr[OFBA_MSPABI_Tag_ISA].i != out_msp_attr[OFBA_MSPABI_Tag_ISA].i)
     {
       _bfd_error_handler
        /* xgettext:c-format */
        (_("error: %pB uses %s instructions but %pB uses %s"),
-        ibfd, isa_type (in_attr[OFBA_MSPABI_Tag_ISA].i),
-        first_input_bfd, isa_type (out_attr[OFBA_MSPABI_Tag_ISA].i));
+        ibfd, isa_type (in_msp_attr[OFBA_MSPABI_Tag_ISA].i),
+        first_input_bfd, isa_type (out_msp_attr[OFBA_MSPABI_Tag_ISA].i));
       result = FALSE;
     }
 
   /* The code models must be the same.  */
-  if (in_attr[OFBA_MSPABI_Tag_Code_Model].i !=
-      out_attr[OFBA_MSPABI_Tag_Code_Model].i)
+  if (in_msp_attr[OFBA_MSPABI_Tag_Code_Model].i
+      != out_msp_attr[OFBA_MSPABI_Tag_Code_Model].i)
     {
       _bfd_error_handler
        /* xgettext:c-format */
        (_("error: %pB uses the %s code model whereas %pB uses the %s code model"),
-        ibfd, code_model (in_attr[OFBA_MSPABI_Tag_Code_Model].i),
-        first_input_bfd, code_model (out_attr[OFBA_MSPABI_Tag_Code_Model].i));
+        ibfd, code_model (in_msp_attr[OFBA_MSPABI_Tag_Code_Model].i),
+        first_input_bfd,
+        code_model (out_msp_attr[OFBA_MSPABI_Tag_Code_Model].i));
       result = FALSE;
     }
 
   /* The large code model is only supported by the MSP430X.  */
-  if (in_attr[OFBA_MSPABI_Tag_Code_Model].i == 2
-      && out_attr[OFBA_MSPABI_Tag_ISA].i != 2)
+  if (in_msp_attr[OFBA_MSPABI_Tag_Code_Model].i == 2
+      && out_msp_attr[OFBA_MSPABI_Tag_ISA].i != 2)
     {
       _bfd_error_handler
        /* xgettext:c-format */
@@ -2474,41 +2489,69 @@ elf32_msp430_merge_mspabi_attributes (bfd *ibfd, struct bfd_link_info *info)
     }
 
   /* The data models must be the same.  */
-  if (in_attr[OFBA_MSPABI_Tag_Data_Model].i !=
-      out_attr[OFBA_MSPABI_Tag_Data_Model].i)
+  if (in_msp_attr[OFBA_MSPABI_Tag_Data_Model].i
+      != out_msp_attr[OFBA_MSPABI_Tag_Data_Model].i)
     {
       _bfd_error_handler
        /* xgettext:c-format */
        (_("error: %pB uses the %s data model whereas %pB uses the %s data model"),
-        ibfd, data_model (in_attr[OFBA_MSPABI_Tag_Data_Model].i),
-        first_input_bfd, data_model (out_attr[OFBA_MSPABI_Tag_Data_Model].i));
+        ibfd, data_model (in_msp_attr[OFBA_MSPABI_Tag_Data_Model].i),
+        first_input_bfd,
+        data_model (out_msp_attr[OFBA_MSPABI_Tag_Data_Model].i));
       result = FALSE;
     }
 
   /* The small code model requires the use of the small data model.  */
-  if (in_attr[OFBA_MSPABI_Tag_Code_Model].i == 1
-      && out_attr[OFBA_MSPABI_Tag_Data_Model].i != 1)
+  if (in_msp_attr[OFBA_MSPABI_Tag_Code_Model].i == 1
+      && out_msp_attr[OFBA_MSPABI_Tag_Data_Model].i != 1)
     {
       _bfd_error_handler
        /* xgettext:c-format */
        (_("error: %pB uses the small code model but %pB uses the %s data model"),
         ibfd, first_input_bfd,
-        data_model (out_attr[OFBA_MSPABI_Tag_Data_Model].i));
+        data_model (out_msp_attr[OFBA_MSPABI_Tag_Data_Model].i));
       result = FALSE;
     }
 
   /* The large data models are only supported by the MSP430X.  */
-  if (in_attr[OFBA_MSPABI_Tag_Data_Model].i > 1
-      && out_attr[OFBA_MSPABI_Tag_ISA].i != 2)
+  if (in_msp_attr[OFBA_MSPABI_Tag_Data_Model].i > 1
+      && out_msp_attr[OFBA_MSPABI_Tag_ISA].i != 2)
     {
       _bfd_error_handler
        /* xgettext:c-format */
        (_("error: %pB uses the %s data model but %pB only uses MSP430 instructions"),
-        ibfd, data_model (in_attr[OFBA_MSPABI_Tag_Data_Model].i),
+        ibfd, data_model (in_msp_attr[OFBA_MSPABI_Tag_Data_Model].i),
         first_input_bfd);
       result = FALSE;
     }
 
+  /* Just ignore the data region unless the large memory model is in use.
+     We have already checked that ibfd and obfd use the same memory model.  */
+  if ((in_msp_attr[OFBA_MSPABI_Tag_Code_Model].i
+       == OFBA_MSPABI_Val_Code_Model_LARGE)
+      && (in_msp_attr[OFBA_MSPABI_Tag_Data_Model].i
+         == OFBA_MSPABI_Val_Data_Model_LARGE))
+    {
+      /* We cannot allow "lower region only" to be linked with any other
+        values (i.e. ANY or NONE).
+        Before this attribute existed, "ANY" region was the default.  */
+      bfd_boolean ibfd_lower_region_used
+       = (in_gnu_attr[Tag_GNU_MSP430_Data_Region].i
+          == Val_GNU_MSP430_Data_Region_Lower);
+      bfd_boolean obfd_lower_region_used
+       = (out_gnu_attr[Tag_GNU_MSP430_Data_Region].i
+          == Val_GNU_MSP430_Data_Region_Lower);
+      if (ibfd_lower_region_used != obfd_lower_region_used)
+       {
+         _bfd_error_handler
+           (_("error: %pB can use the upper region for data, "
+              "but %pB assumes data is exclusively in lower memory"),
+            ibfd_lower_region_used ? obfd : ibfd,
+            ibfd_lower_region_used ? ibfd : obfd);
+         result = FALSE;
+       }
+    }
+
   return result;
 }
 
@@ -2527,7 +2570,7 @@ elf32_msp430_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
                               max (bfd_get_mach (ibfd), bfd_get_mach (obfd)));
 #undef max
 
-  return elf32_msp430_merge_mspabi_attributes (ibfd, info);
+  return elf32_msp430_merge_msp430_attributes (ibfd, info);
 }
 
 static bfd_boolean
This page took 0.028717 seconds and 4 git commands to generate.