Handle VDSO section headers past end of page
[deliverable/binutils-gdb.git] / bfd / mach-o.c
index c853ba117f542604c3a310f36fecf0553ae4bdd1..e33c01f1e4ac64c632248af695c4d37a278d46a2 100644 (file)
@@ -1,7 +1,5 @@
 /* Mach-O support for BFD.
-   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-   2009, 2010, 2011, 2012
-   Free Software Foundation, Inc.
+   Copyright (C) 1999-2014 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -197,6 +195,9 @@ static const mach_o_section_name_xlat dwarf_section_names_xlat[] =
     {  ".debug_macro",                 "__debug_macro",
        SEC_DEBUGGING,                  BFD_MACH_O_S_REGULAR,
        BFD_MACH_O_S_ATTR_DEBUG,        0},
+    {  ".debug_gdb_scripts",           "__debug_gdb_scri",
+       SEC_DEBUGGING,                  BFD_MACH_O_S_REGULAR,
+       BFD_MACH_O_S_ATTR_DEBUG,        0},
     { NULL, NULL, 0, 0, 0, 0}
   };
 
@@ -904,6 +905,10 @@ bfd_mach_o_convert_architecture (bfd_mach_o_cpu_type mtype,
       *type = bfd_arch_powerpc;
       *subtype = bfd_mach_ppc64;
       break;
+    case BFD_MACH_O_CPU_TYPE_ARM64:
+      *type = bfd_arch_aarch64;
+      *subtype = bfd_mach_aarch64;
+      break;
     default:
       *type = bfd_arch_unknown;
       break;
@@ -1070,7 +1075,7 @@ bfd_mach_o_canonicalize_one_reloc (bfd *abfd,
          /* An external symbol number.  */
          sym = syms + num;
        }
-      else if (num == 0x00ffffff)
+      else if (num == 0x00ffffff || num == 0)
        {
          /* The 'symnum' in a non-scattered PAIR is 0x00ffffff.  But as this
             is generic code, we don't know wether this is really a PAIR.
@@ -1082,7 +1087,6 @@ bfd_mach_o_canonicalize_one_reloc (bfd *abfd,
       else
         {
          /* A section number.  */
-          BFD_ASSERT (num != 0);
           BFD_ASSERT (num <= mdata->nsects);
 
           sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr;
@@ -1473,7 +1477,7 @@ bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
   BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
 
   /* Write the symbols first.  */
-  mdata->filelen = FILE_ALIGN(mdata->filelen, wide ? 3 : 2);
+  mdata->filelen = FILE_ALIGN (mdata->filelen, wide ? 3 : 2);
   sym->symoff = mdata->filelen;
   if (bfd_seek (abfd, sym->symoff, SEEK_SET) != 0)
     return FALSE;
@@ -2013,8 +2017,9 @@ bfd_mach_o_write_contents (bfd *abfd)
        case BFD_MACH_O_LC_SUB_FRAMEWORK:
          break;
        default:
-         (*_bfd_error_handler) (_("unable to write unknown load command 0x%lx"),
-                                (unsigned long) cur->type);
+         (*_bfd_error_handler)
+           (_("unable to write unknown load command 0x%lx"),
+            (unsigned long) cur->type);
          return FALSE;
        }
     }
@@ -2037,7 +2042,8 @@ bfd_mach_o_append_section_to_segment (bfd_mach_o_segment_command *seg,
 /* Create section Mach-O flags from BFD flags.  */
 
 static void
-bfd_mach_o_set_section_flags_from_bfd (bfd *abfd ATTRIBUTE_UNUSED, asection *sec)
+bfd_mach_o_set_section_flags_from_bfd (bfd *abfd ATTRIBUTE_UNUSED,
+                                      asection *sec)
 {
   flagword bfd_flags;
   bfd_mach_o_section *s = bfd_mach_o_get_mach_o_section (sec);
@@ -2168,7 +2174,8 @@ bfd_mach_o_build_seg_command (const char *segment,
       mdata->filelen += s->size;
     }
 
-  /* Now pass through again, for zerofill, only now we just update the vmsize.  */
+  /* Now pass through again, for zerofill, only now we just update the
+     vmsize.  */
   for (i = 0; i < mdata->nsects; ++i)
     {
       bfd_mach_o_section *s = mdata->sections[i];
@@ -2693,7 +2700,7 @@ bfd_mach_o_new_section_hook (bfd *abfd, asection *sec)
          s->flags = xlat->macho_sectype | xlat->macho_secattr;
          s->align = xlat->sectalign > bfdalign ? xlat->sectalign
                                                : bfdalign;
-         bfd_set_section_alignment (abfd, sec, s->align);
+         (void) bfd_set_section_alignment (abfd, sec, s->align);
          bfd_flags = bfd_get_section_flags (abfd, sec);
          if (bfd_flags == SEC_NO_FLAGS)
            bfd_set_section_flags (abfd, sec, xlat->bfd_flags);
@@ -3141,9 +3148,6 @@ bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_command *command)
   struct mach_o_str_command_external raw;
   unsigned int nameoff;
 
-  BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
-             || (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
-
   if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
       || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
     return -1;
@@ -3171,6 +3175,7 @@ bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
   switch (command->type)
     {
     case BFD_MACH_O_LC_LOAD_DYLIB:
+    case BFD_MACH_O_LC_LAZY_LOAD_DYLIB:
     case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
     case BFD_MACH_O_LC_ID_DYLIB:
     case BFD_MACH_O_LC_REEXPORT_DYLIB:
@@ -3836,10 +3841,12 @@ bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
       break;
     case BFD_MACH_O_LC_LOAD_DYLINKER:
     case BFD_MACH_O_LC_ID_DYLINKER:
+    case BFD_MACH_O_LC_DYLD_ENVIRONMENT:
       if (bfd_mach_o_read_dylinker (abfd, command) != 0)
        return -1;
       break;
     case BFD_MACH_O_LC_LOAD_DYLIB:
+    case BFD_MACH_O_LC_LAZY_LOAD_DYLIB:
     case BFD_MACH_O_LC_ID_DYLIB:
     case BFD_MACH_O_LC_LOAD_WEAK_DYLIB:
     case BFD_MACH_O_LC_REEXPORT_DYLIB:
@@ -3979,9 +3986,22 @@ bfd_mach_o_scan_start_address (bfd *abfd)
         cmd = &mdata->commands[i].command.thread;
         break;
       }
+    else if (mdata->commands[i].type == BFD_MACH_O_LC_MAIN
+            && mdata->nsects > 1)
+      {
+       bfd_mach_o_main_command *main_cmd = &mdata->commands[i].command.main;
+       bfd_mach_o_section *text_sect = mdata->sections[0];
+       if (text_sect)
+         {
+           abfd->start_address = main_cmd->entryoff
+             + (text_sect->addr - text_sect->offset);
+           return TRUE;
+         }
+      }
 
+  /* An object file has no start address, so do not fail if not found.  */
   if (cmd == NULL)
-    return FALSE;
+    return TRUE;
 
   /* FIXME: create a subtarget hook ?  */
   for (i = 0; i < cmd->nflavours; i++)
@@ -4121,10 +4141,11 @@ bfd_mach_o_scan (bfd *abfd,
        }
     }
 
-  if (bfd_mach_o_scan_start_address (abfd) < 0)
+  /* Sections should be flatten before scanning start address.  */
+  bfd_mach_o_flatten_sections (abfd);
+  if (!bfd_mach_o_scan_start_address (abfd))
     return FALSE;
 
-  bfd_mach_o_flatten_sections (abfd);
   return TRUE;
 }
 
@@ -4133,7 +4154,7 @@ bfd_mach_o_mkobject_init (bfd *abfd)
 {
   bfd_mach_o_data_struct *mdata = NULL;
 
-  mdata = bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct));
+  mdata = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
   if (mdata == NULL)
     return FALSE;
   abfd->tdata.mach_o_data = mdata;
@@ -4177,10 +4198,9 @@ bfd_mach_o_header_p (bfd *abfd,
                      bfd_mach_o_filetype filetype,
                      bfd_mach_o_cpu_type cputype)
 {
-  struct bfd_preserve preserve;
   bfd_mach_o_header header;
+  bfd_mach_o_data_struct *mdata;
 
-  preserve.marker = NULL;
   if (!bfd_mach_o_read_header (abfd, &header))
     goto wrong;
 
@@ -4226,24 +4246,19 @@ bfd_mach_o_header_p (bfd *abfd,
         }
     }
 
-  preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
-  if (preserve.marker == NULL
-      || !bfd_preserve_save (abfd, &preserve))
+  mdata = (bfd_mach_o_data_struct *) bfd_zalloc (abfd, sizeof (*mdata));
+  if (mdata == NULL)
     goto fail;
 
-  if (!bfd_mach_o_scan (abfd, &header,
-                        (bfd_mach_o_data_struct *) preserve.marker))
+  if (!bfd_mach_o_scan (abfd, &header, mdata))
     goto wrong;
 
-  bfd_preserve_finish (abfd, &preserve);
   return abfd->xvec;
 
  wrong:
   bfd_set_error (bfd_error_wrong_format);
 
  fail:
-  if (preserve.marker != NULL)
-    bfd_preserve_restore (abfd, &preserve);
   return NULL;
 }
 
@@ -4259,6 +4274,35 @@ bfd_mach_o_gen_core_p (bfd *abfd)
   return bfd_mach_o_header_p (abfd, BFD_MACH_O_MH_CORE, 0);
 }
 
+/* Return the base address of ABFD, ie the address at which the image is
+   mapped.  The possible initial pagezero is ignored.  */
+
+bfd_vma
+bfd_mach_o_get_base_address (bfd *abfd)
+{
+  bfd_mach_o_data_struct *mdata;
+  unsigned int i;
+
+  /* Check for Mach-O.  */
+  if (!bfd_mach_o_valid (abfd))
+    return 0;
+  mdata = bfd_mach_o_get_data (abfd);
+
+  for (i = 0; i < mdata->header.ncmds; i++)
+    {
+      bfd_mach_o_load_command *cmd = &mdata->commands[i];
+      if ((cmd->type == BFD_MACH_O_LC_SEGMENT
+          || cmd->type == BFD_MACH_O_LC_SEGMENT_64))
+       {
+         struct bfd_mach_o_segment_command *segcmd = &cmd->command.segment;
+
+         if (segcmd->initprot != 0)
+           return segcmd->vmaddr;
+       }
+    }
+  return 0;
+}
+
 typedef struct mach_o_fat_archentry
 {
   unsigned long cputype;
@@ -4344,13 +4388,13 @@ bfd_mach_o_fat_member_init (bfd *abfd,
   if (ap)
     {
       /* Use the architecture name if known.  */
-      abfd->filename = ap->printable_name;
+      abfd->filename = xstrdup (ap->printable_name);
     }
   else
     {
       /* Forge a uniq id.  */
       const size_t namelen = 2 + 8 + 1 + 2 + 8 + 1;
-      char *name = bfd_alloc (abfd, namelen);
+      char *name = xmalloc (namelen);
       snprintf (name, namelen, "0x%lx-0x%lx",
                 entry->cputype, entry->cpusubtype);
       abfd->filename = name;
This page took 0.033511 seconds and 4 git commands to generate.