Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(763)

Unified Diff: bfd/mach-o.c

Issue 124383005: GDB 7.6.50 (Closed) Base URL: http://git.chromium.org/native_client/nacl-gdb.git@upstream
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « bfd/mach-o.h ('k') | bfd/mach-o-i386.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: bfd/mach-o.c
diff --git a/bfd/mach-o.c b/bfd/mach-o.c
index 1f9fc17608539692303a4c1c4c181d047355b730..ffe7332a674063310989412fdd5e08aabc7cfce8 100644
--- a/bfd/mach-o.c
+++ b/bfd/mach-o.c
@@ -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 1999-2013 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -84,7 +82,7 @@ bfd_mach_o_wide_p (bfd *abfd)
{
return mach_o_wide_p (&bfd_mach_o_get_data (abfd)->header);
}
-
+
/* Tables to translate well known Mach-O segment/section names to bfd
names. Use of canonical names (such as .text or .debug_frame) is required
by gdb. */
@@ -92,7 +90,7 @@ bfd_mach_o_wide_p (bfd *abfd)
/* __TEXT Segment. */
static const mach_o_section_name_xlat text_section_names_xlat[] =
{
- { ".text", "__text",
+ { ".text", "__text",
SEC_CODE | SEC_LOAD, BFD_MACH_O_S_REGULAR,
BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS, 0},
{ ".const", "__const",
@@ -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}
};
@@ -287,7 +288,7 @@ static const char dsym_subdir[] = ".dSYM/Contents/Resources/DWARF";
/* Fetch the translation from a Mach-O section designation (segment, section)
as a bfd short name, if one exists. Otherwise return NULL.
-
+
Allow the segment and section names to be unterminated 16 byte arrays. */
const mach_o_section_name_xlat *
@@ -315,11 +316,11 @@ bfd_mach_o_section_data_for_mach_sect (bfd *abfd, const char *segname,
BFD_MACH_O_SECTNAME_SIZE) == 0)
return sec;
- return NULL;
+ return NULL;
}
/* If the bfd_name for this section is a 'canonical' form for which we
- know the Mach-O data, return the segment name and the data for the
+ know the Mach-O data, return the segment name and the data for the
Mach-O equivalent. Otherwise return NULL. */
const mach_o_section_name_xlat *
@@ -353,12 +354,12 @@ bfd_mach_o_section_data_for_bfd_name (bfd *abfd, const char *bfd_name,
return sec;
}
- return NULL;
+ return NULL;
}
/* Convert Mach-O section name to BFD.
- Try to use standard/canonical names, for which we have tables including
+ Try to use standard/canonical names, for which we have tables including
default flag settings - which are returned. Otherwise forge a new name
in the form "<segmentname>.<sectionname>" this will be prefixed with
LC_SEGMENT. if the segment name does not begin with an underscore.
@@ -380,7 +381,7 @@ bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, const char *segname,
*name = NULL;
*flags = SEC_NO_FLAGS;
- /* First search for a canonical name...
+ /* First search for a canonical name...
xlat will be non-null if there is an entry for segname, secname. */
xlat = bfd_mach_o_section_data_for_mach_sect (abfd, segname, secname);
if (xlat)
@@ -423,7 +424,7 @@ bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, const char *segname,
return the translation table - which contains defaults for flags,
type, attribute and default alignment data.
- Otherwise, expand the bfd_name (assumed to be in the form
+ Otherwise, expand the bfd_name (assumed to be in the form
"[LC_SEGMENT.]<segmentname>.<sectionname>") and return NULL. */
static const mach_o_section_name_xlat *
@@ -558,11 +559,11 @@ bfd_mach_o_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
{
if (osection->used_by_bfd == NULL)
osection->used_by_bfd = isection->used_by_bfd;
- else
+ else
if (isection->used_by_bfd != NULL)
- memcpy (osection->used_by_bfd, isection->used_by_bfd,
+ memcpy (osection->used_by_bfd, isection->used_by_bfd,
sizeof (bfd_mach_o_section));
-
+
if (osection->used_by_bfd != NULL)
((bfd_mach_o_section *)osection->used_by_bfd)->bfdsection = osection;
@@ -590,7 +591,7 @@ bfd_mach_o_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
/* This allows us to set up to 32 bits of flags (unless we invent some
fiendish scheme to subdivide). For now, we'll just set the file flags
without error checking - just overwrite. */
-
+
bfd_boolean
bfd_mach_o_bfd_set_private_flags (bfd *abfd, flagword flags)
{
@@ -706,7 +707,7 @@ bfd_mach_o_get_synthetic_symtab (bfd *abfd,
names = (char *) (s + count);
nul_name = names;
*names++ = 0;
-
+
n = 0;
for (i = 0; i < mdata->nsects; i++)
{
@@ -714,7 +715,7 @@ bfd_mach_o_get_synthetic_symtab (bfd *abfd,
unsigned int first, last;
bfd_vma addr;
bfd_vma entry_size;
-
+
switch (sec->flags & BFD_MACH_O_SECTION_TYPE_MASK)
{
case BFD_MACH_O_S_NON_LAZY_SYMBOL_POINTERS:
@@ -733,7 +734,7 @@ bfd_mach_o_get_synthetic_symtab (bfd *abfd,
s->section = sec->bfdsection;
s->value = addr - sec->addr;
s->udata.p = NULL;
-
+
if (isym < symtab->nsyms
&& symtab->symbols[isym].symbol.name)
{
@@ -989,7 +990,7 @@ bfd_mach_o_swap_in_non_scattered_reloc (bfd *abfd, bfd_mach_o_reloc_info *rel,
rel->r_value = (fields[0] << 16) | (fields[1] << 8) | fields[2];
rel->r_type = (info >> BFD_MACH_O_BE_TYPE_SHIFT) & BFD_MACH_O_TYPE_MASK;
rel->r_pcrel = (info & BFD_MACH_O_BE_PCREL) ? 1 : 0;
- rel->r_length = (info >> BFD_MACH_O_BE_LENGTH_SHIFT)
+ rel->r_length = (info >> BFD_MACH_O_BE_LENGTH_SHIFT)
& BFD_MACH_O_LENGTH_MASK;
rel->r_extern = (info & BFD_MACH_O_BE_EXTERN) ? 1 : 0;
}
@@ -998,7 +999,7 @@ bfd_mach_o_swap_in_non_scattered_reloc (bfd *abfd, bfd_mach_o_reloc_info *rel,
rel->r_value = (fields[2] << 16) | (fields[1] << 8) | fields[0];
rel->r_type = (info >> BFD_MACH_O_LE_TYPE_SHIFT) & BFD_MACH_O_TYPE_MASK;
rel->r_pcrel = (info & BFD_MACH_O_LE_PCREL) ? 1 : 0;
- rel->r_length = (info >> BFD_MACH_O_LE_LENGTH_SHIFT)
+ rel->r_length = (info >> BFD_MACH_O_LE_LENGTH_SHIFT)
& BFD_MACH_O_LENGTH_MASK;
rel->r_extern = (info & BFD_MACH_O_LE_EXTERN) ? 1 : 0;
}
@@ -1018,7 +1019,7 @@ bfd_mach_o_canonicalize_one_reloc (bfd *abfd,
addr = bfd_get_32 (abfd, raw->r_address);
res->sym_ptr_ptr = NULL;
res->addend = 0;
-
+
if (addr & BFD_MACH_O_SR_SCATTERED)
{
unsigned int j;
@@ -1056,22 +1057,35 @@ bfd_mach_o_canonicalize_one_reloc (bfd *abfd,
else
{
unsigned int num;
-
+
/* Non-scattered relocation. */
reloc.r_scattered = 0;
-
+
/* The value and info fields have to be extracted dependent on target
endian-ness. */
bfd_mach_o_swap_in_non_scattered_reloc (abfd, &reloc, raw->r_symbolnum);
num = reloc.r_value;
if (reloc.r_extern)
- sym = syms + num;
- else if (reloc.r_scattered
- || (reloc.r_type != BFD_MACH_O_GENERIC_RELOC_PAIR))
+ {
+ /* An external symbol number. */
+ sym = syms + num;
+ }
+ else if (num == 0x00ffffff)
+ {
+ /* 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.
+ This value is almost certainly not a valid section number, hence
+ this specific case to avoid an assertion failure.
+ Target specific swap_reloc_in routine should adjust that. */
+ sym = bfd_abs_section_ptr->symbol_ptr_ptr;
+ }
+ else
{
+ /* A section number. */
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
@@ -1080,26 +1094,23 @@ bfd_mach_o_canonicalize_one_reloc (bfd *abfd,
the vma of the section. */
res->addend = -mdata->sections[num - 1]->addr;
}
- else /* ... The 'symnum' in a non-scattered PAIR will be 0x00ffffff. */
- {
- /* Pairs for PPC LO/HI/HA are not scattered, but contain the offset
- in the lower 16bits of the address value. So we have to find the
- 'symbol' from the preceding reloc. We do this even thoough the
- section symbol is probably not needed here, because NULL symbol
- values cause an assert in generic BFD code. */
- sym = (res - 1)->sym_ptr_ptr;
- }
+ /* Note: Pairs for PPC LO/HI/HA are not scattered, but contain the offset
+ in the lower 16bits of the address value. So we have to find the
+ 'symbol' from the preceding reloc. We do this even though the
+ section symbol is probably not needed here, because NULL symbol
+ values cause an assert in generic BFD code. This must be done in
+ the PPC swap_reloc_in routine. */
res->sym_ptr_ptr = sym;
-
+
/* The 'address' is just r_address.
??? maybe this should be masked with 0xffffff for safety. */
res->address = addr;
reloc.r_address = addr;
}
-
- /* We have set up a reloc with all the information present, so the swapper can
- modify address, value and addend fields, if necessary, to convey information
- in the generic BFD reloc that is mach-o specific. */
+
+ /* We have set up a reloc with all the information present, so the swapper
+ can modify address, value and addend fields, if necessary, to convey
+ information in the generic BFD reloc that is mach-o specific. */
if (!(*bed->_bfd_mach_o_swap_reloc_in)(res, &reloc))
return -1;
@@ -1403,7 +1414,7 @@ bfd_mach_o_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
bfd_h_put_32 (abfd, seg->flags, raw.flags);
-
+
if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
|| bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
return -1;
@@ -1485,7 +1496,7 @@ bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
{
bfd_size_type str_index;
bfd_mach_o_asymbol *s = (bfd_mach_o_asymbol *)symbols[i];
-
+
if (s->symbol.name == 0 || s->symbol.name[0] == '\0')
/* An index of 0 always means the empty string. */
str_index = 0;
@@ -1652,7 +1663,7 @@ bfd_mach_o_write_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
return FALSE;
}
}
-
+
if (cmd->nindirectsyms > 0)
{
unsigned int i;
@@ -1667,7 +1678,7 @@ bfd_mach_o_write_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
bfd_h_put_32 (abfd, cmd->indirect_syms[i], &raw);
if (bfd_bwrite (raw, sizeof (raw), abfd) != sizeof (raw))
return FALSE;
- }
+ }
}
if (cmd->nextrefsyms != 0)
@@ -1848,7 +1859,7 @@ bfd_mach_o_mangle_symbols (bfd *abfd)
}
else
s->n_type = BFD_MACH_O_N_SECT;
-
+
if (s->symbol.flags & BSF_GLOBAL)
s->n_type |= BFD_MACH_O_N_EXT;
}
@@ -1889,7 +1900,7 @@ bfd_mach_o_mangle_sections (bfd *abfd, bfd_mach_o_data_struct *mdata)
unsigned nsect;
nsect = bfd_count_sections (abfd);
-
+
/* Don't do it if it's already set - assume the application knows what it's
doing. */
if (mdata->nsects == nsect
@@ -1897,7 +1908,7 @@ bfd_mach_o_mangle_sections (bfd *abfd, bfd_mach_o_data_struct *mdata)
return TRUE;
mdata->nsects = nsect;
- mdata->sections = bfd_alloc (abfd,
+ mdata->sections = bfd_alloc (abfd,
mdata->nsects * sizeof (bfd_mach_o_section *));
if (mdata->sections == NULL)
return FALSE;
@@ -1908,7 +1919,7 @@ bfd_mach_o_mangle_sections (bfd *abfd, bfd_mach_o_data_struct *mdata)
" maximum is 255,\n"), nsect);
/* Create Mach-O sections.
- Section type, attribute and align should have been set when the
+ Section type, attribute and align should have been set when the
section was created - either read in or specified. */
target_index = 0;
for (sec = abfd->sections; sec; sec = sec->next)
@@ -1921,7 +1932,7 @@ bfd_mach_o_mangle_sections (bfd *abfd, bfd_mach_o_data_struct *mdata)
msect->addr = bfd_get_section_vma (abfd, sec);
msect->size = bfd_get_section_size (sec);
- /* Use the largest alignment set, in case it was bumped after the
+ /* Use the largest alignment set, in case it was bumped after the
section was created. */
msect->align = msect->align > bfd_align ? msect->align : bfd_align;
@@ -2049,15 +2060,15 @@ bfd_mach_o_set_section_flags_from_bfd (bfd *abfd ATTRIBUTE_UNUSED, asection *sec
/* Count the number of sections in the list for the segment named.
The special case of NULL or "" for the segment name is valid for
- an MH_OBJECT file and means 'all sections available'.
-
- Requires that the sections table in mdata be filled in.
+ an MH_OBJECT file and means 'all sections available'.
+
+ Requires that the sections table in mdata be filled in.
Returns the number of sections (0 is valid).
Any number > 255 signals an invalid section count, although we will,
perhaps, allow the file to be written (in line with Darwin tools up
- to XCode 4).
-
+ to XCode 4).
+
A section count of (unsigned long) -1 signals a definite error. */
static unsigned long
@@ -2112,11 +2123,11 @@ bfd_mach_o_build_seg_command (const char *segment,
seg->sect_head = NULL;
seg->sect_tail = NULL;
- /* Append sections to the segment.
+ /* Append sections to the segment.
This is a little tedious, we have to honor the need to account zerofill
sections after all the rest. This forces us to do the calculation of
- total vmsize in three passes so that any alignment increments are
+ total vmsize in three passes so that any alignment increments are
properly accounted. */
for (i = 0; i < mdata->nsects; ++i)
@@ -2126,7 +2137,7 @@ bfd_mach_o_build_seg_command (const char *segment,
/* If we're not making an MH_OBJECT, check whether this section is from
our segment, and skip if not. Otherwise, just add all sections. */
- if (! is_mho
+ if (! is_mho
&& strncmp (segment, s->segname, BFD_MACH_O_SEGNAME_SIZE) != 0)
continue;
@@ -2134,11 +2145,11 @@ bfd_mach_o_build_seg_command (const char *segment,
placed in the file in source sequence. */
bfd_mach_o_append_section_to_segment (seg, sec);
s->offset = 0;
-
- /* Zerofill sections have zero file size & offset,
+
+ /* Zerofill sections have zero file size & offset,
and are not written. */
if ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK) == BFD_MACH_O_S_ZEROFILL
- || (s->flags & BFD_MACH_O_SECTION_TYPE_MASK)
+ || (s->flags & BFD_MACH_O_SECTION_TYPE_MASK)
== BFD_MACH_O_S_GB_ZEROFILL)
continue;
@@ -2166,7 +2177,7 @@ bfd_mach_o_build_seg_command (const char *segment,
if ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK) != BFD_MACH_O_S_ZEROFILL)
continue;
- if (! is_mho
+ if (! is_mho
&& strncmp (segment, s->segname, BFD_MACH_O_SEGNAME_SIZE) != 0)
continue;
@@ -2181,11 +2192,11 @@ bfd_mach_o_build_seg_command (const char *segment,
for (i = 0; i < mdata->nsects; ++i)
{
bfd_mach_o_section *s = mdata->sections[i];
-
+
if ((s->flags & BFD_MACH_O_SECTION_TYPE_MASK) != BFD_MACH_O_S_GB_ZEROFILL)
continue;
- if (! is_mho
+ if (! is_mho
&& strncmp (segment, s->segname, BFD_MACH_O_SEGNAME_SIZE) != 0)
continue;
@@ -2203,7 +2214,7 @@ bfd_mach_o_build_seg_command (const char *segment,
{
bfd_mach_o_section *ms = mdata->sections[i];
asection *sec = ms->bfdsection;
-
+
if ((ms->nreloc = sec->reloc_count) == 0)
{
ms->reloff = 0;
@@ -2287,8 +2298,8 @@ bfd_mach_o_build_dysymtab_command (bfd *abfd,
}
dsym->nextdefsym = i - dsym->nlocalsym;
dsym->iundefsym = dsym->nextdefsym + dsym->iextdefsym;
- dsym->nundefsym = bfd_get_symcount (abfd)
- - dsym->nlocalsym
+ dsym->nundefsym = bfd_get_symcount (abfd)
+ - dsym->nlocalsym
- dsym->nextdefsym;
}
else
@@ -2309,11 +2320,11 @@ bfd_mach_o_build_dysymtab_command (bfd *abfd,
mdata->filelen = FILE_ALIGN (mdata->filelen, 2);
dsym->indirectsymoff = mdata->filelen;
mdata->filelen += dsym->nindirectsyms * 4;
-
+
dsym->indirect_syms = bfd_zalloc (abfd, dsym->nindirectsyms * 4);
if (dsym->indirect_syms == NULL)
return FALSE;
-
+
n = 0;
for (i = 0; i < mdata->nsects; ++i)
{
@@ -2327,7 +2338,7 @@ bfd_mach_o_build_dysymtab_command (bfd *abfd,
{
unsigned j, num;
bfd_mach_o_asymbol **isyms = sec->indirect_syms;
-
+
num = bfd_mach_o_section_get_nbr_indirect (abfd, sec);
if (isyms == NULL || num == 0)
break;
@@ -2403,7 +2414,7 @@ bfd_mach_o_build_commands (bfd *abfd)
a command (segment) to contain all the sections,
command for the symbol table,
- a command for the dysymtab.
+ a command for the dysymtab.
??? maybe we should assert that this is an MH_OBJECT? */
@@ -2449,7 +2460,7 @@ bfd_mach_o_build_commands (bfd *abfd)
return FALSE;
if (segcmd_idx >= 0)
- {
+ {
bfd_mach_o_load_command *cmd = &mdata->commands[segcmd_idx];
bfd_mach_o_segment_command *seg = &cmd->command.segment;
@@ -2482,7 +2493,7 @@ bfd_mach_o_build_commands (bfd *abfd)
{
/* Init symtab command. */
bfd_mach_o_load_command *cmd = &mdata->commands[symtab_idx];
-
+
cmd->type = BFD_MACH_O_LC_SYMTAB;
cmd->offset = base_offset;
if (segcmd_idx >= 0)
@@ -2503,10 +2514,10 @@ bfd_mach_o_build_commands (bfd *abfd)
cmd->type = BFD_MACH_O_LC_DYSYMTAB;
if (symtab_idx >= 0)
- cmd->offset = mdata->commands[symtab_idx].offset
+ cmd->offset = mdata->commands[symtab_idx].offset
+ mdata->commands[symtab_idx].len;
else if (segcmd_idx >= 0)
- cmd->offset = mdata->commands[segcmd_idx].offset
+ cmd->offset = mdata->commands[segcmd_idx].offset
+ mdata->commands[segcmd_idx].len;
else
cmd->offset = base_offset;
@@ -2522,13 +2533,13 @@ bfd_mach_o_build_commands (bfd *abfd)
/* So, now we have sized the commands and the filelen set to that.
Now we can build the segment command and set the section file offsets. */
if (segcmd_idx >= 0
- && ! bfd_mach_o_build_seg_command
+ && ! bfd_mach_o_build_seg_command
(NULL, mdata, &mdata->commands[segcmd_idx].command.segment))
return FALSE;
/* If we're doing a dysymtab, cmd points to its load command. */
if (dysymtab_idx >= 0
- && ! bfd_mach_o_build_dysymtab_command (abfd, mdata,
+ && ! bfd_mach_o_build_dysymtab_command (abfd, mdata,
&mdata->commands[dysymtab_idx]))
return FALSE;
@@ -2681,9 +2692,9 @@ bfd_mach_o_new_section_hook (bfd *abfd, asection *sec)
if (xlat != NULL)
{
s->flags = xlat->macho_sectype | xlat->macho_secattr;
- s->align = xlat->sectalign > bfdalign ? xlat->sectalign
+ 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);
@@ -3656,6 +3667,48 @@ bfd_mach_o_read_encryption_info (bfd *abfd, bfd_mach_o_load_command *command)
return TRUE;
}
+static bfd_boolean
+bfd_mach_o_read_main (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_main_command *cmd = &command->command.main;
+ struct mach_o_entry_point_command_external raw;
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ cmd->entryoff = bfd_get_64 (abfd, raw.entryoff);
+ cmd->stacksize = bfd_get_64 (abfd, raw.stacksize);
+ return TRUE;
+}
+
+static bfd_boolean
+bfd_mach_o_read_source_version (bfd *abfd, bfd_mach_o_load_command *command)
+{
+ bfd_mach_o_source_version_command *cmd = &command->command.source_version;
+ struct mach_o_source_version_command_external raw;
+ bfd_uint64_t ver;
+
+ if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
+ || bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
+ return FALSE;
+
+ ver = bfd_get_64 (abfd, raw.version);
+ /* Note: we use a serie of shift to avoid shift > 32 (for which gcc
+ generates warnings) in case of the host doesn't support 64 bit
+ integers. */
+ cmd->e = ver & 0x3ff;
+ ver >>= 10;
+ cmd->d = ver & 0x3ff;
+ ver >>= 10;
+ cmd->c = ver & 0x3ff;
+ ver >>= 10;
+ cmd->b = ver & 0x3ff;
+ ver >>= 10;
+ cmd->a = ver & 0xffffff;
+ return TRUE;
+}
+
static int
bfd_mach_o_read_segment (bfd *abfd,
bfd_mach_o_load_command *command,
@@ -3832,6 +3885,8 @@ bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
case BFD_MACH_O_LC_CODE_SIGNATURE:
case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
case BFD_MACH_O_LC_FUNCTION_STARTS:
+ case BFD_MACH_O_LC_DATA_IN_CODE:
+ case BFD_MACH_O_LC_DYLIB_CODE_SIGN_DRS:
if (bfd_mach_o_read_linkedit (abfd, command) != 0)
return -1;
break;
@@ -3848,6 +3903,14 @@ bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
if (!bfd_mach_o_read_version_min (abfd, command))
return -1;
break;
+ case BFD_MACH_O_LC_MAIN:
+ if (!bfd_mach_o_read_main (abfd, command))
+ return -1;
+ break;
+ case BFD_MACH_O_LC_SOURCE_VERSION:
+ if (!bfd_mach_o_read_source_version (abfd, command))
+ return -1;
+ break;
default:
(*_bfd_error_handler)(_("%B: unknown load command 0x%lx"),
abfd, (unsigned long) command->type);
@@ -3917,9 +3980,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++)
@@ -4059,10 +4135,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;
}
@@ -4071,7 +4148,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;
@@ -4115,10 +4192,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;
@@ -4164,24 +4240,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;
}
@@ -4294,7 +4365,7 @@ bfd_mach_o_fat_member_init (bfd *abfd,
abfd->filename = name;
}
- areltdata = bfd_zalloc (abfd, sizeof (struct areltdata));
+ areltdata = bfd_zmalloc (sizeof (struct areltdata));
areltdata->parsed_size = entry->size;
abfd->arelt_data = areltdata;
abfd->iostream = NULL;
@@ -4836,7 +4907,7 @@ bfd_mach_o_find_nearest_line (bfd *abfd,
if (_bfd_dwarf2_find_nearest_line (abfd, dwarf_debug_sections,
section, symbols, offset,
filename_ptr, functionname_ptr,
- line_ptr, 0,
+ line_ptr, NULL, 0,
&mdata->dwarf2_find_line_info))
return TRUE;
return FALSE;
@@ -4864,6 +4935,9 @@ bfd_mach_o_close_and_cleanup (bfd *abfd)
}
}
+ if (bfd_get_format (abfd) == bfd_archive
+ && abfd->xvec == &mach_o_fat_vec)
+ return TRUE;
return _bfd_generic_close_and_cleanup (abfd);
}
@@ -4882,7 +4956,7 @@ bfd_boolean bfd_mach_o_free_cached_info (bfd *abfd)
return TRUE;
}
-#define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
+#define bfd_mach_o_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
#define bfd_mach_o_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
#define bfd_mach_o_swap_reloc_in NULL
« no previous file with comments | « bfd/mach-o.h ('k') | bfd/mach-o-i386.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698