/* Mach-O support for BFD.
- Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+ 2009, 2010, 2011
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
#define bfd_mach_o_object_p bfd_mach_o_gen_object_p
#define bfd_mach_o_core_p bfd_mach_o_gen_core_p
-#define bfd_mach_o_mkobject bfd_false
+#define bfd_mach_o_mkobject bfd_mach_o_gen_mkobject
#define FILE_ALIGN(off, algn) \
(((off) + ((file_ptr) 1 << (algn)) - 1) & ((file_ptr) -1 << (algn)))
if (bfd_mach_o_read_symtab_symbols (abfd) != 0)
{
- fprintf (stderr,
- "bfd_mach_o_canonicalize_symtab: unable to load symbols\n");
+ (*_bfd_error_handler) (_("bfd_mach_o_canonicalize_symtab: unable to load symbols"));
return 0;
}
unsigned int i;
unsigned char buf[8];
unsigned int offset;
- unsigned int nflavours;
BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
|| (command->type == BFD_MACH_O_LC_UNIXTHREAD));
offset = 8;
- nflavours = 0;
for (i = 0; i < cmd->nflavours; i++)
{
BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
res->addend = 0;
res->address = addr;
if (symnum & BFD_MACH_O_R_EXTERN)
- sym = syms + num;
+ {
+ sym = syms + num;
+ reloc.r_extern = 1;
+ }
else
{
BFD_ASSERT (num != 0);
BFD_ASSERT (num <= mdata->nsects);
sym = mdata->sections[num - 1]->bfdsection->symbol_ptr_ptr;
+ /* For a symbol defined in section S, the addend (stored in the
+ binary) contains the address of the section. To comply with
+ bfd conventio, substract the section address.
+ Use the address from the header, so that the user can modify
+ the vma of the section. */
+ res->addend = -mdata->sections[num - 1]->addr;
+ reloc.r_extern = 0;
}
res->sym_ptr_ptr = sym;
reloc.r_type = BFD_MACH_O_GET_R_TYPE (symnum);
case BFD_MACH_O_LC_SUB_FRAMEWORK:
break;
default:
- fprintf (stderr,
- "unable to write unknown load command 0x%lx\n",
- (unsigned long) cur->type);
+ (*_bfd_error_handler) (_("unable to write unknown load command 0x%lx"),
+ (unsigned long) cur->type);
return FALSE;
}
}
if (bfd_seek (abfd, symoff, SEEK_SET) != 0
|| bfd_bread ((void *) buf, symwidth, abfd) != symwidth)
{
- fprintf (stderr, "bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu\n",
- symwidth, (unsigned long) symoff);
+ (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"),
+ symwidth, (unsigned long) symoff);
return -1;
}
if (stroff >= sym->strsize)
{
- fprintf (stderr, "bfd_mach_o_read_symtab_symbol: symbol name out of range (%lu >= %lu)\n",
- (unsigned long) stroff, (unsigned long) sym->strsize);
+ (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: symbol name out of range (%lu >= %lu)"),
+ (unsigned long) stroff,
+ (unsigned long) sym->strsize);
return -1;
}
/* Mach-O uses 0 to mean "no section"; not an error. */
if (section != 0)
{
- fprintf (stderr, "bfd_mach_o_read_symtab_symbol: "
- "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined\n",
- s->symbol.name, section, mdata->nsects);
+ (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
+ "symbol \"%s\" specified invalid section %d (max %lu): setting to undefined"),
+ s->symbol.name, section, mdata->nsects);
}
s->symbol.section = bfd_und_section_ptr;
}
break;
case BFD_MACH_O_N_INDR:
- fprintf (stderr, "bfd_mach_o_read_symtab_symbol: "
- "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined\n",
- s->symbol.name);
+ (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
+ "symbol \"%s\" is unsupported 'indirect' reference: setting to undefined"),
+ s->symbol.name);
s->symbol.section = bfd_und_section_ptr;
break;
default:
- fprintf (stderr, "bfd_mach_o_read_symtab_symbol: "
- "symbol \"%s\" specified invalid type field 0x%x: setting to undefined\n",
- s->symbol.name, symtype);
+ (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: "
+ "symbol \"%s\" specified invalid type field 0x%x: setting to undefined"),
+ s->symbol.name, symtype);
s->symbol.section = bfd_und_section_ptr;
break;
}
if (sym->symbols == NULL)
{
- fprintf (stderr, "bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols\n");
+ (*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbols: unable to allocate memory for symbols"));
return -1;
}
if (bfd_seek (abfd, isymoff, SEEK_SET) != 0
|| bfd_bread ((void *) buf, 4, abfd) != 4)
{
- fprintf (stderr, "bfd_mach_o_read_dysymtab_symbol: unable to read %lu bytes at %lu\n",
- (unsigned long) 4, isymoff);
+ (*_bfd_error_handler) (_("bfd_mach_o_read_dysymtab_symbol: unable to read %lu bytes at %lu"),
+ (unsigned long) 4, isymoff);
return -1;
}
sym_index = bfd_h_get_32 (abfd, buf);
bfd_mach_o_read_uuid (bfd *abfd, bfd_mach_o_load_command *command)
{
bfd_mach_o_uuid_command *cmd = &command->command.uuid;
- asection *bfdsec;
- char *sname;
- static const char prefix[] = "LC_UUID";
BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
|| bfd_bread ((void *) cmd->uuid, 16, abfd) != 16)
return -1;
- sname = bfd_alloc (abfd, strlen (prefix) + 1);
- if (sname == NULL)
- return -1;
- strcpy (sname, prefix);
-
- bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, SEC_HAS_CONTENTS);
- if (bfdsec == NULL)
- return -1;
-
- bfdsec->vma = 0;
- bfdsec->lma = 0;
- bfdsec->size = command->len - 8;
- bfdsec->filepos = command->offset + 8;
- bfdsec->alignment_power = 0;
-
- cmd->section = bfdsec;
-
return 0;
}
return -1;
break;
default:
- fprintf (stderr, "unable to read unknown load command 0x%lx\n",
- (unsigned long) command->type);
+ (*_bfd_error_handler) (_("unable to read unknown load command 0x%lx"),
+ (unsigned long) command->type);
break;
}
return 0;
}
+bfd_boolean
+bfd_mach_o_set_arch_mach (bfd *abfd,
+ enum bfd_architecture arch,
+ unsigned long machine)
+{
+ bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
+
+ /* If this isn't the right architecture for this backend, and this
+ isn't the generic backend, fail. */
+ if (arch != bed->arch
+ && arch != bfd_arch_unknown
+ && bed->arch != bfd_arch_unknown)
+ return FALSE;
+
+ return bfd_default_set_arch_mach (abfd, arch, machine);
+}
+
int
bfd_mach_o_scan (bfd *abfd,
bfd_mach_o_header *header,
&cputype, &cpusubtype);
if (cputype == bfd_arch_unknown)
{
- fprintf (stderr, "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx\n",
- header->cputype, header->cpusubtype);
+ (*_bfd_error_handler) (_("bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx"),
+ header->cputype, header->cpusubtype);
return -1;
}
return TRUE;
}
+static bfd_boolean
+bfd_mach_o_gen_mkobject (bfd *abfd)
+{
+ bfd_mach_o_data_struct *mdata;
+
+ if (!bfd_mach_o_mkobject_init (abfd))
+ return FALSE;
+
+ mdata = bfd_mach_o_get_data (abfd);
+ mdata->header.magic = BFD_MACH_O_MH_MAGIC;
+ mdata->header.cputype = 0;
+ mdata->header.cpusubtype = 0;
+ mdata->header.byteorder = abfd->xvec->byteorder;
+ mdata->header.version = 1;
+
+ return TRUE;
+}
+
const bfd_target *
bfd_mach_o_header_p (bfd *abfd,
bfd_mach_o_filetype filetype,
if (! (header.byteorder == BFD_ENDIAN_BIG
|| header.byteorder == BFD_ENDIAN_LITTLE))
{
- fprintf (stderr, "unknown header byte-order value 0x%lx\n",
- (unsigned long) header.byteorder);
+ (*_bfd_error_handler) (_("unknown header byte-order value 0x%lx"),
+ (unsigned long) header.byteorder);
goto wrong;
}
#define TARGET_NAME mach_o_be_vec
#define TARGET_STRING "mach-o-be"
+#define TARGET_ARCHITECTURE bfd_arch_unknown
#define TARGET_BIG_ENDIAN 1
#define TARGET_ARCHIVE 0
#include "mach-o-target.c"
#undef TARGET_NAME
#undef TARGET_STRING
+#undef TARGET_ARCHITECTURE
#undef TARGET_BIG_ENDIAN
#undef TARGET_ARCHIVE
#define TARGET_NAME mach_o_le_vec
#define TARGET_STRING "mach-o-le"
+#define TARGET_ARCHITECTURE bfd_arch_unknown
#define TARGET_BIG_ENDIAN 0
#define TARGET_ARCHIVE 0
#undef TARGET_NAME
#undef TARGET_STRING
+#undef TARGET_ARCHITECTURE
#undef TARGET_BIG_ENDIAN
#undef TARGET_ARCHIVE
+/* Not yet handled: creating an archive. */
+#define bfd_mach_o_mkarchive _bfd_noarchive_mkarchive
+
+/* Not used. */
+#define bfd_mach_o_read_ar_hdr _bfd_noarchive_read_ar_hdr
+#define bfd_mach_o_write_ar_hdr _bfd_noarchive_write_ar_hdr
+#define bfd_mach_o_slurp_armap _bfd_noarchive_slurp_armap
+#define bfd_mach_o_slurp_extended_name_table _bfd_noarchive_slurp_extended_name_table
+#define bfd_mach_o_construct_extended_name_table _bfd_noarchive_construct_extended_name_table
+#define bfd_mach_o_truncate_arname _bfd_noarchive_truncate_arname
+#define bfd_mach_o_write_armap _bfd_noarchive_write_armap
+#define bfd_mach_o_get_elt_at_index _bfd_noarchive_get_elt_at_index
+#define bfd_mach_o_generic_stat_arch_elt _bfd_noarchive_generic_stat_arch_elt
+#define bfd_mach_o_update_armap_timestamp _bfd_noarchive_update_armap_timestamp
+
#define TARGET_NAME mach_o_fat_vec
#define TARGET_STRING "mach-o-fat"
+#define TARGET_ARCHITECTURE bfd_arch_unknown
#define TARGET_BIG_ENDIAN 1
#define TARGET_ARCHIVE 1
#undef TARGET_NAME
#undef TARGET_STRING
+#undef TARGET_ARCHITECTURE
#undef TARGET_BIG_ENDIAN
#undef TARGET_ARCHIVE