/* 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.
{ ".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}
};
*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;
/* 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.
else
{
/* A section number. */
- BFD_ASSERT (num != 0);
BFD_ASSERT (num <= mdata->nsects);
sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr;
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;
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;
}
}
/* 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);
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];
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);
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;
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:
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:
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++)
}
}
- 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;
}
{
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;
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;
}
}
- 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;
}
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;
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;