Line 24... |
Line 24... |
#include "mach-o.h"
|
#include "mach-o.h"
|
#include "bfd.h"
|
#include "bfd.h"
|
#include "libbfd.h"
|
#include "libbfd.h"
|
#include "libiberty.h"
|
#include "libiberty.h"
|
#include "aout/stab_gnu.h"
|
#include "aout/stab_gnu.h"
|
|
#include "mach-o/reloc.h"
|
|
#include "mach-o/external.h"
|
#include <ctype.h>
|
#include <ctype.h>
|
|
|
#define bfd_mach_o_object_p bfd_mach_o_gen_object_p
|
#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_core_p bfd_mach_o_gen_core_p
|
#define bfd_mach_o_mkobject bfd_mach_o_gen_mkobject
|
#define bfd_mach_o_mkobject bfd_mach_o_gen_mkobject
|
Line 130... |
Line 132... |
{ NULL, NULL, 0}
|
{ NULL, NULL, 0}
|
};
|
};
|
|
|
struct mach_o_segment_name_xlat
|
struct mach_o_segment_name_xlat
|
{
|
{
|
|
/* Segment name. */
|
const char *segname;
|
const char *segname;
|
|
|
|
/* List of known sections for the segment. */
|
const struct mach_o_section_name_xlat *sections;
|
const struct mach_o_section_name_xlat *sections;
|
};
|
};
|
|
|
|
/* List of known segment names. */
|
|
|
static const struct mach_o_segment_name_xlat segsec_names_xlat[] =
|
static const struct mach_o_segment_name_xlat segsec_names_xlat[] =
|
{
|
{
|
{ "__DWARF", dwarf_section_names_xlat },
|
|
{ "__TEXT", text_section_names_xlat },
|
{ "__TEXT", text_section_names_xlat },
|
{ "__DATA", data_section_names_xlat },
|
{ "__DATA", data_section_names_xlat },
|
|
{ "__DWARF", dwarf_section_names_xlat },
|
{ NULL, NULL }
|
{ NULL, NULL }
|
};
|
};
|
|
|
|
|
/* Mach-O to bfd names. */
|
/* Mach-O to bfd names. */
|
|
|
static void
|
void
|
bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, bfd_mach_o_section *section,
|
bfd_mach_o_normalize_section_name (const char *segname, const char *sectname,
|
char **name, flagword *flags)
|
const char **name, flagword *flags)
|
{
|
{
|
const struct mach_o_segment_name_xlat *seg;
|
const struct mach_o_segment_name_xlat *seg;
|
char *res;
|
|
unsigned int len;
|
|
const char *pfx = "";
|
|
|
|
*name = NULL;
|
*name = NULL;
|
*flags = SEC_NO_FLAGS;
|
*flags = SEC_NO_FLAGS;
|
|
|
for (seg = segsec_names_xlat; seg->segname; seg++)
|
for (seg = segsec_names_xlat; seg->segname; seg++)
|
{
|
{
|
if (strcmp (seg->segname, section->segname) == 0)
|
if (strncmp (seg->segname, segname, BFD_MACH_O_SEGNAME_SIZE) == 0)
|
{
|
{
|
const struct mach_o_section_name_xlat *sec;
|
const struct mach_o_section_name_xlat *sec;
|
|
|
for (sec = seg->sections; sec->mach_o_name; sec++)
|
for (sec = seg->sections; sec->mach_o_name; sec++)
|
{
|
{
|
if (strcmp (sec->mach_o_name, section->sectname) == 0)
|
if (strncmp (sec->mach_o_name, sectname,
|
|
BFD_MACH_O_SECTNAME_SIZE) == 0)
|
{
|
{
|
len = strlen (sec->bfd_name);
|
*name = sec->bfd_name;
|
res = bfd_alloc (abfd, len + 1);
|
|
|
|
if (res == NULL)
|
|
return;
|
|
strcpy (res, sec->bfd_name);
|
|
*name = res;
|
|
*flags = sec->flags;
|
*flags = sec->flags;
|
return;
|
return;
|
}
|
}
|
}
|
}
|
|
return;
|
|
}
|
}
|
}
|
}
|
}
|
|
|
len = strlen (section->segname) + 1
|
static void
|
+ strlen (section->sectname) + 1;
|
bfd_mach_o_convert_section_name_to_bfd
|
|
(bfd *abfd, const char *segname, const char *sectname,
|
|
const char **name, flagword *flags)
|
|
{
|
|
char *res;
|
|
unsigned int len;
|
|
const char *pfx = "";
|
|
|
|
/* First search for a canonical name. */
|
|
bfd_mach_o_normalize_section_name (segname, sectname, name, flags);
|
|
|
|
/* Return now if found. */
|
|
if (*name)
|
|
return;
|
|
|
|
len = strlen (segname) + 1 + strlen (sectname) + 1;
|
|
|
/* Put "LC_SEGMENT." prefix if the segment name is weird (ie doesn't start
|
/* Put "LC_SEGMENT." prefix if the segment name is weird (ie doesn't start
|
with an underscore. */
|
with an underscore. */
|
if (section->segname[0] != '_')
|
if (segname[0] != '_')
|
{
|
{
|
static const char seg_pfx[] = "LC_SEGMENT.";
|
static const char seg_pfx[] = "LC_SEGMENT.";
|
|
|
pfx = seg_pfx;
|
pfx = seg_pfx;
|
len += sizeof (seg_pfx) - 1;
|
len += sizeof (seg_pfx) - 1;
|
}
|
}
|
|
|
res = bfd_alloc (abfd, len);
|
res = bfd_alloc (abfd, len);
|
if (res == NULL)
|
if (res == NULL)
|
return;
|
return;
|
snprintf (res, len, "%s%s.%s", pfx, section->segname, section->sectname);
|
snprintf (res, len, "%s%s.%s", pfx, segname, sectname);
|
*name = res;
|
*name = res;
|
|
*flags = SEC_NO_FLAGS;
|
}
|
}
|
|
|
/* Convert a bfd section name to a Mach-O segment + section name. */
|
/* Convert a bfd section name to a Mach-O segment + section name. */
|
|
|
static void
|
static void
|
Line 374... |
Line 390... |
unsigned long j;
|
unsigned long j;
|
|
|
if (nsyms < 0)
|
if (nsyms < 0)
|
return nsyms;
|
return nsyms;
|
|
|
|
if (nsyms == 0)
|
|
{
|
|
/* Do not try to read symbols if there are none. */
|
|
alocation[0] = NULL;
|
|
return 0;
|
|
}
|
|
|
if (bfd_mach_o_read_symtab_symbols (abfd) != 0)
|
if (bfd_mach_o_read_symtab_symbols (abfd) != 0)
|
{
|
{
|
(*_bfd_error_handler) (_("bfd_mach_o_canonicalize_symtab: unable to load symbols"));
|
(*_bfd_error_handler) (_("bfd_mach_o_canonicalize_symtab: unable to load symbols"));
|
return 0;
|
return 0;
|
}
|
}
|
Line 596... |
Line 619... |
}
|
}
|
|
|
static bfd_boolean
|
static bfd_boolean
|
bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header)
|
bfd_mach_o_write_header (bfd *abfd, bfd_mach_o_header *header)
|
{
|
{
|
unsigned char buf[32];
|
struct mach_o_header_external raw;
|
unsigned int size;
|
unsigned int size;
|
|
|
size = mach_o_wide_p (header) ?
|
size = mach_o_wide_p (header) ?
|
BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
|
BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
|
|
|
bfd_h_put_32 (abfd, header->magic, buf + 0);
|
bfd_h_put_32 (abfd, header->magic, raw.magic);
|
bfd_h_put_32 (abfd, header->cputype, buf + 4);
|
bfd_h_put_32 (abfd, header->cputype, raw.cputype);
|
bfd_h_put_32 (abfd, header->cpusubtype, buf + 8);
|
bfd_h_put_32 (abfd, header->cpusubtype, raw.cpusubtype);
|
bfd_h_put_32 (abfd, header->filetype, buf + 12);
|
bfd_h_put_32 (abfd, header->filetype, raw.filetype);
|
bfd_h_put_32 (abfd, header->ncmds, buf + 16);
|
bfd_h_put_32 (abfd, header->ncmds, raw.ncmds);
|
bfd_h_put_32 (abfd, header->sizeofcmds, buf + 20);
|
bfd_h_put_32 (abfd, header->sizeofcmds, raw.sizeofcmds);
|
bfd_h_put_32 (abfd, header->flags, buf + 24);
|
bfd_h_put_32 (abfd, header->flags, raw.flags);
|
|
|
if (mach_o_wide_p (header))
|
if (mach_o_wide_p (header))
|
bfd_h_put_32 (abfd, header->reserved, buf + 28);
|
bfd_h_put_32 (abfd, header->reserved, raw.reserved);
|
|
|
if (bfd_seek (abfd, 0, SEEK_SET) != 0
|
if (bfd_seek (abfd, 0, SEEK_SET) != 0
|
|| bfd_bwrite ((void *) buf, size, abfd) != size)
|
|| bfd_bwrite (&raw, size, abfd) != size)
|
return FALSE;
|
return FALSE;
|
|
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
static int
|
static int
|
bfd_mach_o_write_thread (bfd *abfd, bfd_mach_o_load_command *command)
|
bfd_mach_o_write_thread (bfd *abfd, bfd_mach_o_load_command *command)
|
{
|
{
|
bfd_mach_o_thread_command *cmd = &command->command.thread;
|
bfd_mach_o_thread_command *cmd = &command->command.thread;
|
unsigned int i;
|
unsigned int i;
|
unsigned char buf[8];
|
struct mach_o_thread_command_external raw;
|
unsigned int offset;
|
unsigned int offset;
|
|
|
BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
|
BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
|
|| (command->type == BFD_MACH_O_LC_UNIXTHREAD));
|
|| (command->type == BFD_MACH_O_LC_UNIXTHREAD));
|
|
|
offset = 8;
|
offset = 8;
|
for (i = 0; i < cmd->nflavours; i++)
|
for (i = 0; i < cmd->nflavours; i++)
|
{
|
{
|
BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
|
BFD_ASSERT ((cmd->flavours[i].size % 4) == 0);
|
BFD_ASSERT (cmd->flavours[i].offset == (command->offset + offset + 8));
|
BFD_ASSERT (cmd->flavours[i].offset ==
|
|
(command->offset + offset + BFD_MACH_O_LC_SIZE));
|
|
|
bfd_h_put_32 (abfd, cmd->flavours[i].flavour, buf);
|
bfd_h_put_32 (abfd, cmd->flavours[i].flavour, raw.flavour);
|
bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), buf + 4);
|
bfd_h_put_32 (abfd, (cmd->flavours[i].size / 4), raw.count);
|
|
|
if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
|
if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
|
|| bfd_bwrite ((void *) buf, 8, abfd) != 8)
|
|| bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
|
return -1;
|
return -1;
|
|
|
offset += cmd->flavours[i].size + 8;
|
offset += cmd->flavours[i].size + sizeof (raw);
|
}
|
}
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
Line 658... |
Line 682... |
{
|
{
|
return (asect->reloc_count + 1) * sizeof (arelent *);
|
return (asect->reloc_count + 1) * sizeof (arelent *);
|
}
|
}
|
|
|
static int
|
static int
|
bfd_mach_o_canonicalize_one_reloc (bfd *abfd, char *buf,
|
bfd_mach_o_canonicalize_one_reloc (bfd *abfd,
|
|
struct mach_o_reloc_info_external *raw,
|
arelent *res, asymbol **syms)
|
arelent *res, asymbol **syms)
|
{
|
{
|
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
|
bfd_mach_o_backend_data *bed = bfd_mach_o_get_backend_data (abfd);
|
bfd_mach_o_reloc_info reloc;
|
bfd_mach_o_reloc_info reloc;
|
bfd_vma addr;
|
bfd_vma addr;
|
bfd_vma symnum;
|
bfd_vma symnum;
|
asymbol **sym;
|
asymbol **sym;
|
|
|
addr = bfd_get_32 (abfd, buf + 0);
|
addr = bfd_get_32 (abfd, raw->r_address);
|
symnum = bfd_get_32 (abfd, buf + 4);
|
symnum = bfd_get_32 (abfd, raw->r_symbolnum);
|
|
|
if (addr & BFD_MACH_O_SR_SCATTERED)
|
if (addr & BFD_MACH_O_SR_SCATTERED)
|
{
|
{
|
unsigned int j;
|
unsigned int j;
|
|
|
Line 736... |
Line 761... |
bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos,
|
bfd_mach_o_canonicalize_relocs (bfd *abfd, unsigned long filepos,
|
unsigned long count,
|
unsigned long count,
|
arelent *res, asymbol **syms)
|
arelent *res, asymbol **syms)
|
{
|
{
|
unsigned long i;
|
unsigned long i;
|
char *native_relocs;
|
struct mach_o_reloc_info_external *native_relocs;
|
bfd_size_type native_size;
|
bfd_size_type native_size;
|
|
|
/* Allocate and read relocs. */
|
/* Allocate and read relocs. */
|
native_size = count * BFD_MACH_O_RELENT_SIZE;
|
native_size = count * BFD_MACH_O_RELENT_SIZE;
|
native_relocs = bfd_malloc (native_size);
|
native_relocs =
|
|
(struct mach_o_reloc_info_external *) bfd_malloc (native_size);
|
if (native_relocs == NULL)
|
if (native_relocs == NULL)
|
return -1;
|
return -1;
|
|
|
if (bfd_seek (abfd, filepos, SEEK_SET) != 0
|
if (bfd_seek (abfd, filepos, SEEK_SET) != 0
|
|| bfd_bread (native_relocs, native_size, abfd) != native_size)
|
|| bfd_bread (native_relocs, native_size, abfd) != native_size)
|
goto err;
|
goto err;
|
|
|
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
{
|
{
|
char *buf = native_relocs + BFD_MACH_O_RELENT_SIZE * i;
|
if (bfd_mach_o_canonicalize_one_reloc (abfd, &native_relocs[i],
|
|
&res[i], syms) < 0)
|
if (bfd_mach_o_canonicalize_one_reloc (abfd, buf, &res[i], syms) < 0)
|
|
goto err;
|
goto err;
|
}
|
}
|
free (native_relocs);
|
free (native_relocs);
|
return i;
|
return i;
|
err:
|
err:
|
Line 883... |
Line 908... |
/* Convert and write. */
|
/* Convert and write. */
|
entries = section->bfdsection->orelocation;
|
entries = section->bfdsection->orelocation;
|
for (i = 0; i < section->nreloc; i++)
|
for (i = 0; i < section->nreloc; i++)
|
{
|
{
|
arelent *rel = entries[i];
|
arelent *rel = entries[i];
|
char buf[8];
|
struct mach_o_reloc_info_external raw;
|
bfd_mach_o_reloc_info info, *pinfo = &info;
|
bfd_mach_o_reloc_info info, *pinfo = &info;
|
|
|
/* Convert relocation to an intermediate representation. */
|
/* Convert relocation to an intermediate representation. */
|
if (!(*bed->_bfd_mach_o_swap_reloc_out) (rel, pinfo))
|
if (!(*bed->_bfd_mach_o_swap_reloc_out) (rel, pinfo))
|
return FALSE;
|
return FALSE;
|
Line 900... |
Line 925... |
v = BFD_MACH_O_SR_SCATTERED
|
v = BFD_MACH_O_SR_SCATTERED
|
| (pinfo->r_pcrel ? BFD_MACH_O_SR_PCREL : 0)
|
| (pinfo->r_pcrel ? BFD_MACH_O_SR_PCREL : 0)
|
| BFD_MACH_O_SET_SR_LENGTH(pinfo->r_length)
|
| BFD_MACH_O_SET_SR_LENGTH(pinfo->r_length)
|
| BFD_MACH_O_SET_SR_TYPE(pinfo->r_type)
|
| BFD_MACH_O_SET_SR_TYPE(pinfo->r_type)
|
| BFD_MACH_O_SET_SR_ADDRESS(pinfo->r_address);
|
| BFD_MACH_O_SET_SR_ADDRESS(pinfo->r_address);
|
bfd_put_32 (abfd, v, buf);
|
/* Note: scattered relocs have field in reverse order... */
|
bfd_put_32 (abfd, pinfo->r_value, buf + 4);
|
bfd_put_32 (abfd, v, raw.r_address);
|
|
bfd_put_32 (abfd, pinfo->r_value, raw.r_symbolnum);
|
}
|
}
|
else
|
else
|
{
|
{
|
unsigned long v;
|
unsigned long v;
|
|
|
bfd_put_32 (abfd, pinfo->r_address, buf);
|
bfd_put_32 (abfd, pinfo->r_address, raw.r_address);
|
v = BFD_MACH_O_SET_R_SYMBOLNUM (pinfo->r_value)
|
v = BFD_MACH_O_SET_R_SYMBOLNUM (pinfo->r_value)
|
| (pinfo->r_pcrel ? BFD_MACH_O_R_PCREL : 0)
|
| (pinfo->r_pcrel ? BFD_MACH_O_R_PCREL : 0)
|
| BFD_MACH_O_SET_R_LENGTH (pinfo->r_length)
|
| BFD_MACH_O_SET_R_LENGTH (pinfo->r_length)
|
| (pinfo->r_extern ? BFD_MACH_O_R_EXTERN : 0)
|
| (pinfo->r_extern ? BFD_MACH_O_R_EXTERN : 0)
|
| BFD_MACH_O_SET_R_TYPE (pinfo->r_type);
|
| BFD_MACH_O_SET_R_TYPE (pinfo->r_type);
|
bfd_put_32 (abfd, v, buf + 4);
|
bfd_put_32 (abfd, v, raw.r_symbolnum);
|
}
|
}
|
|
|
if (bfd_bwrite ((void *) buf, BFD_MACH_O_RELENT_SIZE, abfd)
|
if (bfd_bwrite (&raw, BFD_MACH_O_RELENT_SIZE, abfd)
|
!= BFD_MACH_O_RELENT_SIZE)
|
!= BFD_MACH_O_RELENT_SIZE)
|
return FALSE;
|
return FALSE;
|
}
|
}
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
static int
|
static int
|
bfd_mach_o_write_section_32 (bfd *abfd, bfd_mach_o_section *section)
|
bfd_mach_o_write_section_32 (bfd *abfd, bfd_mach_o_section *section)
|
{
|
{
|
unsigned char buf[BFD_MACH_O_SECTION_SIZE];
|
struct mach_o_section_32_external raw;
|
|
|
memcpy (buf, section->sectname, 16);
|
memcpy (raw.sectname, section->sectname, 16);
|
memcpy (buf + 16, section->segname, 16);
|
memcpy (raw.segname, section->segname, 16);
|
bfd_h_put_32 (abfd, section->addr, buf + 32);
|
bfd_h_put_32 (abfd, section->addr, raw.addr);
|
bfd_h_put_32 (abfd, section->size, buf + 36);
|
bfd_h_put_32 (abfd, section->size, raw.size);
|
bfd_h_put_32 (abfd, section->offset, buf + 40);
|
bfd_h_put_32 (abfd, section->offset, raw.offset);
|
bfd_h_put_32 (abfd, section->align, buf + 44);
|
bfd_h_put_32 (abfd, section->align, raw.align);
|
bfd_h_put_32 (abfd, section->reloff, buf + 48);
|
bfd_h_put_32 (abfd, section->reloff, raw.reloff);
|
bfd_h_put_32 (abfd, section->nreloc, buf + 52);
|
bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
|
bfd_h_put_32 (abfd, section->flags, buf + 56);
|
bfd_h_put_32 (abfd, section->flags, raw.flags);
|
bfd_h_put_32 (abfd, section->reserved1, buf + 60);
|
bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
|
bfd_h_put_32 (abfd, section->reserved2, buf + 64);
|
bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
|
|
|
if (bfd_bwrite ((void *) buf, BFD_MACH_O_SECTION_SIZE, abfd)
|
if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
|
!= BFD_MACH_O_SECTION_SIZE)
|
!= BFD_MACH_O_SECTION_SIZE)
|
return -1;
|
return -1;
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
static int
|
static int
|
bfd_mach_o_write_section_64 (bfd *abfd, bfd_mach_o_section *section)
|
bfd_mach_o_write_section_64 (bfd *abfd, bfd_mach_o_section *section)
|
{
|
{
|
unsigned char buf[BFD_MACH_O_SECTION_64_SIZE];
|
struct mach_o_section_64_external raw;
|
|
|
memcpy (buf, section->sectname, 16);
|
memcpy (raw.sectname, section->sectname, 16);
|
memcpy (buf + 16, section->segname, 16);
|
memcpy (raw.segname, section->segname, 16);
|
bfd_h_put_64 (abfd, section->addr, buf + 32);
|
bfd_h_put_64 (abfd, section->addr, raw.addr);
|
bfd_h_put_64 (abfd, section->size, buf + 40);
|
bfd_h_put_64 (abfd, section->size, raw.size);
|
bfd_h_put_32 (abfd, section->offset, buf + 48);
|
bfd_h_put_32 (abfd, section->offset, raw.offset);
|
bfd_h_put_32 (abfd, section->align, buf + 52);
|
bfd_h_put_32 (abfd, section->align, raw.align);
|
bfd_h_put_32 (abfd, section->reloff, buf + 56);
|
bfd_h_put_32 (abfd, section->reloff, raw.reloff);
|
bfd_h_put_32 (abfd, section->nreloc, buf + 60);
|
bfd_h_put_32 (abfd, section->nreloc, raw.nreloc);
|
bfd_h_put_32 (abfd, section->flags, buf + 64);
|
bfd_h_put_32 (abfd, section->flags, raw.flags);
|
bfd_h_put_32 (abfd, section->reserved1, buf + 68);
|
bfd_h_put_32 (abfd, section->reserved1, raw.reserved1);
|
bfd_h_put_32 (abfd, section->reserved2, buf + 72);
|
bfd_h_put_32 (abfd, section->reserved2, raw.reserved2);
|
bfd_h_put_32 (abfd, section->reserved3, buf + 76);
|
bfd_h_put_32 (abfd, section->reserved3, raw.reserved3);
|
|
|
if (bfd_bwrite ((void *) buf, BFD_MACH_O_SECTION_64_SIZE, abfd)
|
if (bfd_bwrite (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
|
!= BFD_MACH_O_SECTION_64_SIZE)
|
!= BFD_MACH_O_SECTION_64_SIZE)
|
return -1;
|
return -1;
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
static int
|
static int
|
bfd_mach_o_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
|
bfd_mach_o_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
|
{
|
{
|
unsigned char buf[BFD_MACH_O_LC_SEGMENT_SIZE];
|
struct mach_o_segment_command_32_external raw;
|
bfd_mach_o_segment_command *seg = &command->command.segment;
|
bfd_mach_o_segment_command *seg = &command->command.segment;
|
unsigned long i;
|
bfd_mach_o_section *sec;
|
|
|
BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
|
BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
|
|
|
for (i = 0; i < seg->nsects; i++)
|
for (sec = seg->sect_head; sec != NULL; sec = sec->next)
|
if (!bfd_mach_o_write_relocs (abfd, &seg->sections[i]))
|
if (!bfd_mach_o_write_relocs (abfd, sec))
|
return -1;
|
return -1;
|
|
|
memcpy (buf, seg->segname, 16);
|
memcpy (raw.segname, seg->segname, 16);
|
bfd_h_put_32 (abfd, seg->vmaddr, buf + 16);
|
bfd_h_put_32 (abfd, seg->vmaddr, raw.vmaddr);
|
bfd_h_put_32 (abfd, seg->vmsize, buf + 20);
|
bfd_h_put_32 (abfd, seg->vmsize, raw.vmsize);
|
bfd_h_put_32 (abfd, seg->fileoff, buf + 24);
|
bfd_h_put_32 (abfd, seg->fileoff, raw.fileoff);
|
bfd_h_put_32 (abfd, seg->filesize, buf + 28);
|
bfd_h_put_32 (abfd, seg->filesize, raw.filesize);
|
bfd_h_put_32 (abfd, seg->maxprot, buf + 32);
|
bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
|
bfd_h_put_32 (abfd, seg->initprot, buf + 36);
|
bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
|
bfd_h_put_32 (abfd, seg->nsects, buf + 40);
|
bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
|
bfd_h_put_32 (abfd, seg->flags, buf + 44);
|
bfd_h_put_32 (abfd, seg->flags, raw.flags);
|
|
|
if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
|
if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
|
|| (bfd_bwrite ((void *) buf, BFD_MACH_O_LC_SEGMENT_SIZE - 8, abfd)
|
|| bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
|
!= BFD_MACH_O_LC_SEGMENT_SIZE - 8))
|
|
return -1;
|
return -1;
|
|
|
for (i = 0; i < seg->nsects; i++)
|
for (sec = seg->sect_head; sec != NULL; sec = sec->next)
|
if (bfd_mach_o_write_section_32 (abfd, &seg->sections[i]))
|
if (bfd_mach_o_write_section_32 (abfd, sec))
|
return -1;
|
return -1;
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
static int
|
static int
|
bfd_mach_o_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
|
bfd_mach_o_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
|
{
|
{
|
unsigned char buf[BFD_MACH_O_LC_SEGMENT_64_SIZE];
|
struct mach_o_segment_command_64_external raw;
|
bfd_mach_o_segment_command *seg = &command->command.segment;
|
bfd_mach_o_segment_command *seg = &command->command.segment;
|
unsigned long i;
|
bfd_mach_o_section *sec;
|
|
|
BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
|
BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
|
|
|
for (i = 0; i < seg->nsects; i++)
|
for (sec = seg->sect_head; sec != NULL; sec = sec->next)
|
if (!bfd_mach_o_write_relocs (abfd, &seg->sections[i]))
|
if (!bfd_mach_o_write_relocs (abfd, sec))
|
return -1;
|
return -1;
|
|
|
memcpy (buf, seg->segname, 16);
|
memcpy (raw.segname, seg->segname, 16);
|
bfd_h_put_64 (abfd, seg->vmaddr, buf + 16);
|
bfd_h_put_64 (abfd, seg->vmaddr, raw.vmaddr);
|
bfd_h_put_64 (abfd, seg->vmsize, buf + 24);
|
bfd_h_put_64 (abfd, seg->vmsize, raw.vmsize);
|
bfd_h_put_64 (abfd, seg->fileoff, buf + 32);
|
bfd_h_put_64 (abfd, seg->fileoff, raw.fileoff);
|
bfd_h_put_64 (abfd, seg->filesize, buf + 40);
|
bfd_h_put_64 (abfd, seg->filesize, raw.filesize);
|
bfd_h_put_32 (abfd, seg->maxprot, buf + 48);
|
bfd_h_put_32 (abfd, seg->maxprot, raw.maxprot);
|
bfd_h_put_32 (abfd, seg->initprot, buf + 52);
|
bfd_h_put_32 (abfd, seg->initprot, raw.initprot);
|
bfd_h_put_32 (abfd, seg->nsects, buf + 56);
|
bfd_h_put_32 (abfd, seg->nsects, raw.nsects);
|
bfd_h_put_32 (abfd, seg->flags, buf + 60);
|
bfd_h_put_32 (abfd, seg->flags, raw.flags);
|
|
|
if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
|
if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
|
|| (bfd_bwrite ((void *) buf, BFD_MACH_O_LC_SEGMENT_64_SIZE - 8, abfd)
|
|| bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
|
!= BFD_MACH_O_LC_SEGMENT_64_SIZE - 8))
|
|
return -1;
|
return -1;
|
|
|
for (i = 0; i < seg->nsects; i++)
|
for (sec = seg->sect_head; sec != NULL; sec = sec->next)
|
if (bfd_mach_o_write_section_64 (abfd, &seg->sections[i]))
|
if (bfd_mach_o_write_section_64 (abfd, sec))
|
return -1;
|
return -1;
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
static bfd_boolean
|
static bfd_boolean
|
bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
|
bfd_mach_o_write_symtab (bfd *abfd, bfd_mach_o_load_command *command)
|
{
|
{
|
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
bfd_mach_o_symtab_command *sym = &command->command.symtab;
|
bfd_mach_o_symtab_command *sym = &command->command.symtab;
|
unsigned char buf[16];
|
|
unsigned long i;
|
unsigned long i;
|
unsigned int wide = bfd_mach_o_wide_p (abfd);
|
unsigned int wide = bfd_mach_o_wide_p (abfd);
|
unsigned int symlen = wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
|
unsigned int symlen = wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
|
struct bfd_strtab_hash *strtab;
|
struct bfd_strtab_hash *strtab;
|
asymbol **symbols = bfd_get_outsymbols (abfd);
|
asymbol **symbols = bfd_get_outsymbols (abfd);
|
Line 1084... |
Line 1107... |
{
|
{
|
str_index = _bfd_stringtab_add (strtab, s->symbol.name, TRUE, FALSE);
|
str_index = _bfd_stringtab_add (strtab, s->symbol.name, TRUE, FALSE);
|
if (str_index == (bfd_size_type) -1)
|
if (str_index == (bfd_size_type) -1)
|
goto err;
|
goto err;
|
}
|
}
|
bfd_h_put_32 (abfd, str_index, buf);
|
|
bfd_h_put_8 (abfd, s->n_type, buf + 4);
|
|
bfd_h_put_8 (abfd, s->n_sect, buf + 5);
|
|
bfd_h_put_16 (abfd, s->n_desc, buf + 6);
|
|
if (wide)
|
if (wide)
|
bfd_h_put_64 (abfd, s->symbol.section->vma + s->symbol.value, buf + 8);
|
{
|
|
struct mach_o_nlist_64_external raw;
|
|
|
|
bfd_h_put_32 (abfd, str_index, raw.n_strx);
|
|
bfd_h_put_8 (abfd, s->n_type, raw.n_type);
|
|
bfd_h_put_8 (abfd, s->n_sect, raw.n_sect);
|
|
bfd_h_put_16 (abfd, s->n_desc, raw.n_desc);
|
|
bfd_h_put_64 (abfd, s->symbol.section->vma + s->symbol.value,
|
|
raw.n_value);
|
|
|
|
if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
|
|
goto err;
|
|
}
|
else
|
else
|
bfd_h_put_32 (abfd, s->symbol.section->vma + s->symbol.value, buf + 8);
|
{
|
|
struct mach_o_nlist_external raw;
|
|
|
|
bfd_h_put_32 (abfd, str_index, raw.n_strx);
|
|
bfd_h_put_8 (abfd, s->n_type, raw.n_type);
|
|
bfd_h_put_8 (abfd, s->n_sect, raw.n_sect);
|
|
bfd_h_put_16 (abfd, s->n_desc, raw.n_desc);
|
|
bfd_h_put_32 (abfd, s->symbol.section->vma + s->symbol.value,
|
|
raw.n_value);
|
|
|
if (bfd_bwrite ((void *) buf, symlen, abfd) != symlen)
|
if (bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
|
goto err;
|
goto err;
|
}
|
}
|
|
}
|
sym->strsize = _bfd_stringtab_size (strtab);
|
sym->strsize = _bfd_stringtab_size (strtab);
|
sym->stroff = mdata->filelen;
|
sym->stroff = mdata->filelen;
|
mdata->filelen += sym->strsize;
|
mdata->filelen += sym->strsize;
|
|
|
if (_bfd_stringtab_emit (abfd, strtab) != TRUE)
|
if (_bfd_stringtab_emit (abfd, strtab) != TRUE)
|
goto err;
|
goto err;
|
_bfd_stringtab_free (strtab);
|
_bfd_stringtab_free (strtab);
|
|
|
/* The command. */
|
/* The command. */
|
bfd_h_put_32 (abfd, sym->symoff, buf);
|
{
|
bfd_h_put_32 (abfd, sym->nsyms, buf + 4);
|
struct mach_o_symtab_command_external raw;
|
bfd_h_put_32 (abfd, sym->stroff, buf + 8);
|
|
bfd_h_put_32 (abfd, sym->strsize, buf + 12);
|
bfd_h_put_32 (abfd, sym->symoff, raw.symoff);
|
|
bfd_h_put_32 (abfd, sym->nsyms, raw.nsyms);
|
|
bfd_h_put_32 (abfd, sym->stroff, raw.stroff);
|
|
bfd_h_put_32 (abfd, sym->strsize, raw.strsize);
|
|
|
if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
|
if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
|
|| bfd_bwrite ((void *) buf, 16, abfd) != 16)
|
|| bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
|
return FALSE;
|
return FALSE;
|
|
}
|
|
|
return TRUE;
|
return TRUE;
|
|
|
err:
|
err:
|
_bfd_stringtab_free (strtab);
|
_bfd_stringtab_free (strtab);
|
Line 1197... |
Line 1242... |
if (!bfd_mach_o_mangle_symbols (abfd))
|
if (!bfd_mach_o_mangle_symbols (abfd))
|
return FALSE;
|
return FALSE;
|
|
|
for (i = 0; i < mdata->header.ncmds; i++)
|
for (i = 0; i < mdata->header.ncmds; i++)
|
{
|
{
|
unsigned char buf[8];
|
struct mach_o_load_command_external raw;
|
bfd_mach_o_load_command *cur = &mdata->commands[i];
|
bfd_mach_o_load_command *cur = &mdata->commands[i];
|
unsigned long typeflag;
|
unsigned long typeflag;
|
|
|
typeflag = cur->type | (cur->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0);
|
typeflag = cur->type | (cur->type_required ? BFD_MACH_O_LC_REQ_DYLD : 0);
|
|
|
bfd_h_put_32 (abfd, typeflag, buf);
|
bfd_h_put_32 (abfd, typeflag, raw.cmd);
|
bfd_h_put_32 (abfd, cur->len, buf + 4);
|
bfd_h_put_32 (abfd, cur->len, raw.cmdsize);
|
|
|
if (bfd_seek (abfd, cur->offset, SEEK_SET) != 0
|
if (bfd_seek (abfd, cur->offset, SEEK_SET) != 0
|
|| bfd_bwrite ((void *) buf, 8, abfd) != 8)
|
|| bfd_bwrite (&raw, BFD_MACH_O_LC_SIZE, abfd) != 8)
|
return FALSE;
|
return FALSE;
|
|
|
switch (cur->type)
|
switch (cur->type)
|
{
|
{
|
case BFD_MACH_O_LC_SEGMENT:
|
case BFD_MACH_O_LC_SEGMENT:
|
Line 1257... |
Line 1302... |
}
|
}
|
|
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
|
static void
|
|
bfd_mach_o_append_section_to_segment (bfd_mach_o_segment_command *seg,
|
|
asection *sec)
|
|
{
|
|
bfd_mach_o_section *s = (bfd_mach_o_section *)sec->used_by_bfd;
|
|
if (seg->sect_head == NULL)
|
|
seg->sect_head = s;
|
|
else
|
|
seg->sect_tail->next = s;
|
|
seg->sect_tail = s;
|
|
}
|
|
|
|
/* Create section Mach-O flags from BFD flags. */
|
|
|
|
static void
|
|
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);
|
|
|
|
/* Create default flags. */
|
|
bfd_flags = bfd_get_section_flags (abfd, sec);
|
|
if ((bfd_flags & SEC_CODE) == SEC_CODE)
|
|
s->flags = BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS
|
|
| BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS
|
|
| BFD_MACH_O_S_REGULAR;
|
|
else if ((bfd_flags & (SEC_ALLOC | SEC_LOAD)) == SEC_ALLOC)
|
|
s->flags = BFD_MACH_O_S_ZEROFILL;
|
|
else if (bfd_flags & SEC_DEBUGGING)
|
|
s->flags = BFD_MACH_O_S_REGULAR | BFD_MACH_O_S_ATTR_DEBUG;
|
|
else
|
|
s->flags = BFD_MACH_O_S_REGULAR;
|
|
}
|
|
|
/* Build Mach-O load commands from the sections. */
|
/* Build Mach-O load commands from the sections. */
|
|
|
bfd_boolean
|
bfd_boolean
|
bfd_mach_o_build_commands (bfd *abfd)
|
bfd_mach_o_build_commands (bfd *abfd)
|
{
|
{
|
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
unsigned int wide = mach_o_wide_p (&mdata->header);
|
unsigned int wide = mach_o_wide_p (&mdata->header);
|
bfd_mach_o_segment_command *seg;
|
bfd_mach_o_segment_command *seg;
|
bfd_mach_o_section *sections;
|
|
asection *sec;
|
asection *sec;
|
bfd_mach_o_load_command *cmd;
|
bfd_mach_o_load_command *cmd;
|
bfd_mach_o_load_command *symtab_cmd;
|
bfd_mach_o_load_command *symtab_cmd;
|
int target_index;
|
int target_index;
|
|
|
/* Return now if commands are already built. */
|
/* Return now if commands are already built. */
|
if (mdata->header.ncmds)
|
if (mdata->header.ncmds)
|
return FALSE;
|
return FALSE;
|
|
|
/* Very simple version: 1 command (segment) containing all sections. */
|
/* Very simple version: a command (segment) to contain all the sections and
|
|
a command for the symbol table. */
|
mdata->header.ncmds = 2;
|
mdata->header.ncmds = 2;
|
mdata->commands = bfd_alloc (abfd, mdata->header.ncmds
|
mdata->commands = bfd_alloc (abfd, mdata->header.ncmds
|
* sizeof (bfd_mach_o_load_command));
|
* sizeof (bfd_mach_o_load_command));
|
if (mdata->commands == NULL)
|
if (mdata->commands == NULL)
|
return FALSE;
|
return FALSE;
|
cmd = &mdata->commands[0];
|
cmd = &mdata->commands[0];
|
seg = &cmd->command.segment;
|
seg = &cmd->command.segment;
|
|
|
seg->nsects = bfd_count_sections (abfd);
|
seg->nsects = bfd_count_sections (abfd);
|
sections = bfd_alloc (abfd, seg->nsects * sizeof (bfd_mach_o_section));
|
|
if (sections == NULL)
|
|
return FALSE;
|
|
seg->sections = sections;
|
|
|
|
/* Set segment command. */
|
/* Set segment command. */
|
if (wide)
|
if (wide)
|
{
|
{
|
cmd->type = BFD_MACH_O_LC_SEGMENT_64;
|
cmd->type = BFD_MACH_O_LC_SEGMENT_64;
|
Line 1334... |
Line 1409... |
|
|
/* Create Mach-O sections. */
|
/* Create Mach-O sections. */
|
target_index = 0;
|
target_index = 0;
|
for (sec = abfd->sections; sec; sec = sec->next)
|
for (sec = abfd->sections; sec; sec = sec->next)
|
{
|
{
|
sections->bfdsection = sec;
|
bfd_mach_o_section *msect = bfd_mach_o_get_mach_o_section (sec);
|
bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, sections);
|
|
sections->addr = bfd_get_section_vma (abfd, sec);
|
bfd_mach_o_append_section_to_segment (seg, sec);
|
sections->size = bfd_get_section_size (sec);
|
|
sections->align = bfd_get_section_alignment (abfd, sec);
|
if (msect->flags == 0)
|
|
{
|
if (sections->size != 0)
|
/* We suppose it hasn't been set. Convert from BFD flags. */
|
{
|
bfd_mach_o_set_section_flags_from_bfd (abfd, sec);
|
mdata->filelen = FILE_ALIGN (mdata->filelen, sections->align);
|
}
|
sections->offset = mdata->filelen;
|
msect->addr = bfd_get_section_vma (abfd, sec);
|
}
|
msect->size = bfd_get_section_size (sec);
|
else
|
msect->align = bfd_get_section_alignment (abfd, sec);
|
sections->offset = 0;
|
|
sections->reloff = 0;
|
|
sections->nreloc = 0;
|
|
sections->reserved1 = 0;
|
|
sections->reserved2 = 0;
|
|
sections->reserved3 = 0;
|
|
|
|
sec->filepos = sections->offset;
|
if (msect->size != 0)
|
|
{
|
|
mdata->filelen = FILE_ALIGN (mdata->filelen, msect->align);
|
|
msect->offset = mdata->filelen;
|
|
}
|
|
else
|
|
msect->offset = 0;
|
|
|
|
sec->filepos = msect->offset;
|
sec->target_index = ++target_index;
|
sec->target_index = ++target_index;
|
|
|
mdata->filelen += sections->size;
|
mdata->filelen += msect->size;
|
sections++;
|
|
}
|
}
|
seg->filesize = mdata->filelen - seg->fileoff;
|
seg->filesize = mdata->filelen - seg->fileoff;
|
seg->vmsize = seg->filesize;
|
seg->vmsize = seg->filesize;
|
|
|
return TRUE;
|
return TRUE;
|
Line 1418... |
Line 1494... |
}
|
}
|
|
|
static bfd_boolean
|
static bfd_boolean
|
bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
|
bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
|
{
|
{
|
unsigned char buf[32];
|
struct mach_o_header_external raw;
|
unsigned int size;
|
unsigned int size;
|
bfd_vma (*get32) (const void *) = NULL;
|
bfd_vma (*get32) (const void *) = NULL;
|
|
|
/* Just read the magic number. */
|
/* Just read the magic number. */
|
if (bfd_seek (abfd, 0, SEEK_SET) != 0
|
if (bfd_seek (abfd, 0, SEEK_SET) != 0
|
|| bfd_bread ((void *) buf, 4, abfd) != 4)
|
|| bfd_bread (raw.magic, sizeof (raw.magic), abfd) != 4)
|
return FALSE;
|
return FALSE;
|
|
|
if (bfd_getb32 (buf) == BFD_MACH_O_MH_MAGIC)
|
if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
|
{
|
{
|
header->byteorder = BFD_ENDIAN_BIG;
|
header->byteorder = BFD_ENDIAN_BIG;
|
header->magic = BFD_MACH_O_MH_MAGIC;
|
header->magic = BFD_MACH_O_MH_MAGIC;
|
header->version = 1;
|
header->version = 1;
|
get32 = bfd_getb32;
|
get32 = bfd_getb32;
|
}
|
}
|
else if (bfd_getl32 (buf) == BFD_MACH_O_MH_MAGIC)
|
else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC)
|
{
|
{
|
header->byteorder = BFD_ENDIAN_LITTLE;
|
header->byteorder = BFD_ENDIAN_LITTLE;
|
header->magic = BFD_MACH_O_MH_MAGIC;
|
header->magic = BFD_MACH_O_MH_MAGIC;
|
header->version = 1;
|
header->version = 1;
|
get32 = bfd_getl32;
|
get32 = bfd_getl32;
|
}
|
}
|
else if (bfd_getb32 (buf) == BFD_MACH_O_MH_MAGIC_64)
|
else if (bfd_getb32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
|
{
|
{
|
header->byteorder = BFD_ENDIAN_BIG;
|
header->byteorder = BFD_ENDIAN_BIG;
|
header->magic = BFD_MACH_O_MH_MAGIC_64;
|
header->magic = BFD_MACH_O_MH_MAGIC_64;
|
header->version = 2;
|
header->version = 2;
|
get32 = bfd_getb32;
|
get32 = bfd_getb32;
|
}
|
}
|
else if (bfd_getl32 (buf) == BFD_MACH_O_MH_MAGIC_64)
|
else if (bfd_getl32 (raw.magic) == BFD_MACH_O_MH_MAGIC_64)
|
{
|
{
|
header->byteorder = BFD_ENDIAN_LITTLE;
|
header->byteorder = BFD_ENDIAN_LITTLE;
|
header->magic = BFD_MACH_O_MH_MAGIC_64;
|
header->magic = BFD_MACH_O_MH_MAGIC_64;
|
header->version = 2;
|
header->version = 2;
|
get32 = bfd_getl32;
|
get32 = bfd_getl32;
|
Line 1466... |
Line 1542... |
/* Once the size of the header is known, read the full header. */
|
/* Once the size of the header is known, read the full header. */
|
size = mach_o_wide_p (header) ?
|
size = mach_o_wide_p (header) ?
|
BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
|
BFD_MACH_O_HEADER_64_SIZE : BFD_MACH_O_HEADER_SIZE;
|
|
|
if (bfd_seek (abfd, 0, SEEK_SET) != 0
|
if (bfd_seek (abfd, 0, SEEK_SET) != 0
|
|| bfd_bread ((void *) buf, size, abfd) != size)
|
|| bfd_bread (&raw, size, abfd) != size)
|
return FALSE;
|
return FALSE;
|
|
|
header->cputype = (*get32) (buf + 4);
|
header->cputype = (*get32) (raw.cputype);
|
header->cpusubtype = (*get32) (buf + 8);
|
header->cpusubtype = (*get32) (raw.cpusubtype);
|
header->filetype = (*get32) (buf + 12);
|
header->filetype = (*get32) (raw.filetype);
|
header->ncmds = (*get32) (buf + 16);
|
header->ncmds = (*get32) (raw.ncmds);
|
header->sizeofcmds = (*get32) (buf + 20);
|
header->sizeofcmds = (*get32) (raw.sizeofcmds);
|
header->flags = (*get32) (buf + 24);
|
header->flags = (*get32) (raw.flags);
|
|
|
if (mach_o_wide_p (header))
|
if (mach_o_wide_p (header))
|
header->reserved = (*get32) (buf + 28);
|
header->reserved = (*get32) (raw.reserved);
|
|
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
static asection *
|
bfd_boolean
|
bfd_mach_o_make_bfd_section (bfd *abfd, bfd_mach_o_section *section,
|
bfd_mach_o_new_section_hook (bfd *abfd, asection *sec)
|
|
{
|
|
bfd_mach_o_section *s;
|
|
|
|
s = bfd_mach_o_get_mach_o_section (sec);
|
|
if (s == NULL)
|
|
{
|
|
flagword bfd_flags;
|
|
|
|
s = (bfd_mach_o_section *) bfd_zalloc (abfd, sizeof (*s));
|
|
if (s == NULL)
|
|
return FALSE;
|
|
sec->used_by_bfd = s;
|
|
s->bfdsection = sec;
|
|
|
|
/* Create default name. */
|
|
bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, s);
|
|
|
|
/* Create default flags. */
|
|
bfd_flags = bfd_get_section_flags (abfd, sec);
|
|
if ((bfd_flags & SEC_CODE) == SEC_CODE)
|
|
s->flags = BFD_MACH_O_S_ATTR_PURE_INSTRUCTIONS
|
|
| BFD_MACH_O_S_ATTR_SOME_INSTRUCTIONS
|
|
| BFD_MACH_O_S_REGULAR;
|
|
else if ((bfd_flags & (SEC_ALLOC | SEC_LOAD)) == SEC_ALLOC)
|
|
s->flags = BFD_MACH_O_S_ZEROFILL;
|
|
else if (bfd_flags & SEC_DEBUGGING)
|
|
s->flags = BFD_MACH_O_S_REGULAR | BFD_MACH_O_S_ATTR_DEBUG;
|
|
else
|
|
s->flags = BFD_MACH_O_S_REGULAR;
|
|
}
|
|
|
|
return _bfd_generic_new_section_hook (abfd, sec);
|
|
}
|
|
|
|
static void
|
|
bfd_mach_o_init_section_from_mach_o (bfd *abfd, asection *sec,
|
unsigned long prot)
|
unsigned long prot)
|
{
|
{
|
asection *bfdsec;
|
|
char *sname;
|
|
flagword flags;
|
flagword flags;
|
|
bfd_mach_o_section *section;
|
|
|
bfd_mach_o_convert_section_name_to_bfd (abfd, section, &sname, &flags);
|
flags = bfd_get_section_flags (abfd, sec);
|
if (sname == NULL)
|
section = bfd_mach_o_get_mach_o_section (sec);
|
return NULL;
|
|
|
|
if (flags == SEC_NO_FLAGS)
|
if (flags == SEC_NO_FLAGS)
|
{
|
{
|
/* Try to guess flags. */
|
/* Try to guess flags. */
|
if (section->flags & BFD_MACH_O_S_ATTR_DEBUG)
|
if (section->flags & BFD_MACH_O_S_ATTR_DEBUG)
|
Line 1526... |
Line 1636... |
if (section->offset != 0)
|
if (section->offset != 0)
|
flags |= SEC_HAS_CONTENTS;
|
flags |= SEC_HAS_CONTENTS;
|
if (section->nreloc != 0)
|
if (section->nreloc != 0)
|
flags |= SEC_RELOC;
|
flags |= SEC_RELOC;
|
|
|
bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, flags);
|
bfd_set_section_flags (abfd, sec, flags);
|
if (bfdsec == NULL)
|
|
return NULL;
|
|
|
|
bfdsec->vma = section->addr;
|
sec->vma = section->addr;
|
bfdsec->lma = section->addr;
|
sec->lma = section->addr;
|
bfdsec->size = section->size;
|
sec->size = section->size;
|
bfdsec->filepos = section->offset;
|
sec->filepos = section->offset;
|
bfdsec->alignment_power = section->align;
|
sec->alignment_power = section->align;
|
bfdsec->segment_mark = 0;
|
sec->segment_mark = 0;
|
bfdsec->reloc_count = section->nreloc;
|
sec->reloc_count = section->nreloc;
|
bfdsec->rel_filepos = section->reloff;
|
sec->rel_filepos = section->reloff;
|
|
}
|
|
|
return bfdsec;
|
static asection *
|
|
bfd_mach_o_make_bfd_section (bfd *abfd,
|
|
const unsigned char *segname,
|
|
const unsigned char *sectname)
|
|
{
|
|
const char *sname;
|
|
flagword flags;
|
|
|
|
bfd_mach_o_convert_section_name_to_bfd
|
|
(abfd, (const char *)segname, (const char *)sectname, &sname, &flags);
|
|
if (sname == NULL)
|
|
return NULL;
|
|
|
|
return bfd_make_section_anyway_with_flags (abfd, sname, flags);
|
}
|
}
|
|
|
static int
|
static asection *
|
bfd_mach_o_read_section_32 (bfd *abfd,
|
bfd_mach_o_read_section_32 (bfd *abfd,
|
bfd_mach_o_section *section,
|
|
unsigned int offset,
|
unsigned int offset,
|
unsigned long prot)
|
unsigned long prot)
|
{
|
{
|
unsigned char buf[BFD_MACH_O_SECTION_SIZE];
|
struct mach_o_section_32_external raw;
|
|
asection *sec;
|
|
bfd_mach_o_section *section;
|
|
|
if (bfd_seek (abfd, offset, SEEK_SET) != 0
|
if (bfd_seek (abfd, offset, SEEK_SET) != 0
|
|| (bfd_bread ((void *) buf, BFD_MACH_O_SECTION_SIZE, abfd)
|
|| (bfd_bread (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
|
!= BFD_MACH_O_SECTION_SIZE))
|
!= BFD_MACH_O_SECTION_SIZE))
|
return -1;
|
return NULL;
|
|
|
|
sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
|
|
if (sec == NULL)
|
|
return NULL;
|
|
|
memcpy (section->sectname, buf, 16);
|
section = bfd_mach_o_get_mach_o_section (sec);
|
section->sectname[16] = '\0';
|
memcpy (section->segname, raw.segname, sizeof (raw.segname));
|
memcpy (section->segname, buf + 16, 16);
|
section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
|
section->segname[16] = '\0';
|
memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
|
section->addr = bfd_h_get_32 (abfd, buf + 32);
|
section->segname[BFD_MACH_O_SECTNAME_SIZE] = 0;
|
section->size = bfd_h_get_32 (abfd, buf + 36);
|
section->addr = bfd_h_get_32 (abfd, raw.addr);
|
section->offset = bfd_h_get_32 (abfd, buf + 40);
|
section->size = bfd_h_get_32 (abfd, raw.size);
|
section->align = bfd_h_get_32 (abfd, buf + 44);
|
section->offset = bfd_h_get_32 (abfd, raw.offset);
|
section->reloff = bfd_h_get_32 (abfd, buf + 48);
|
section->align = bfd_h_get_32 (abfd, raw.align);
|
section->nreloc = bfd_h_get_32 (abfd, buf + 52);
|
section->reloff = bfd_h_get_32 (abfd, raw.reloff);
|
section->flags = bfd_h_get_32 (abfd, buf + 56);
|
section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
|
section->reserved1 = bfd_h_get_32 (abfd, buf + 60);
|
section->flags = bfd_h_get_32 (abfd, raw.flags);
|
section->reserved2 = bfd_h_get_32 (abfd, buf + 64);
|
section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
|
|
section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
|
section->reserved3 = 0;
|
section->reserved3 = 0;
|
section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
|
|
|
|
if (section->bfdsection == NULL)
|
bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
|
return -1;
|
|
|
|
return 0;
|
return sec;
|
}
|
}
|
|
|
static int
|
static asection *
|
bfd_mach_o_read_section_64 (bfd *abfd,
|
bfd_mach_o_read_section_64 (bfd *abfd,
|
bfd_mach_o_section *section,
|
|
unsigned int offset,
|
unsigned int offset,
|
unsigned long prot)
|
unsigned long prot)
|
{
|
{
|
unsigned char buf[BFD_MACH_O_SECTION_64_SIZE];
|
struct mach_o_section_64_external raw;
|
|
asection *sec;
|
|
bfd_mach_o_section *section;
|
|
|
if (bfd_seek (abfd, offset, SEEK_SET) != 0
|
if (bfd_seek (abfd, offset, SEEK_SET) != 0
|
|| (bfd_bread ((void *) buf, BFD_MACH_O_SECTION_64_SIZE, abfd)
|
|| (bfd_bread (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
|
!= BFD_MACH_O_SECTION_64_SIZE))
|
!= BFD_MACH_O_SECTION_64_SIZE))
|
return -1;
|
return NULL;
|
|
|
memcpy (section->sectname, buf, 16);
|
sec = bfd_mach_o_make_bfd_section (abfd, raw.segname, raw.sectname);
|
section->sectname[16] = '\0';
|
if (sec == NULL)
|
memcpy (section->segname, buf + 16, 16);
|
return NULL;
|
section->segname[16] = '\0';
|
|
section->addr = bfd_h_get_64 (abfd, buf + 32);
|
|
section->size = bfd_h_get_64 (abfd, buf + 40);
|
|
section->offset = bfd_h_get_32 (abfd, buf + 48);
|
|
section->align = bfd_h_get_32 (abfd, buf + 52);
|
|
section->reloff = bfd_h_get_32 (abfd, buf + 56);
|
|
section->nreloc = bfd_h_get_32 (abfd, buf + 60);
|
|
section->flags = bfd_h_get_32 (abfd, buf + 64);
|
|
section->reserved1 = bfd_h_get_32 (abfd, buf + 68);
|
|
section->reserved2 = bfd_h_get_32 (abfd, buf + 72);
|
|
section->reserved3 = bfd_h_get_32 (abfd, buf + 76);
|
|
section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
|
|
|
|
if (section->bfdsection == NULL)
|
section = bfd_mach_o_get_mach_o_section (sec);
|
return -1;
|
memcpy (section->segname, raw.segname, sizeof (raw.segname));
|
|
section->segname[BFD_MACH_O_SEGNAME_SIZE] = 0;
|
|
memcpy (section->sectname, raw.sectname, sizeof (raw.sectname));
|
|
section->segname[BFD_MACH_O_SECTNAME_SIZE] = 0;
|
|
section->addr = bfd_h_get_64 (abfd, raw.addr);
|
|
section->size = bfd_h_get_64 (abfd, raw.size);
|
|
section->offset = bfd_h_get_32 (abfd, raw.offset);
|
|
section->align = bfd_h_get_32 (abfd, raw.align);
|
|
section->reloff = bfd_h_get_32 (abfd, raw.reloff);
|
|
section->nreloc = bfd_h_get_32 (abfd, raw.nreloc);
|
|
section->flags = bfd_h_get_32 (abfd, raw.flags);
|
|
section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
|
|
section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
|
|
section->reserved3 = bfd_h_get_32 (abfd, raw.reserved3);
|
|
|
return 0;
|
bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
|
|
|
|
return sec;
|
}
|
}
|
|
|
static int
|
static asection *
|
bfd_mach_o_read_section (bfd *abfd,
|
bfd_mach_o_read_section (bfd *abfd,
|
bfd_mach_o_section *section,
|
|
unsigned int offset,
|
unsigned int offset,
|
unsigned long prot,
|
unsigned long prot,
|
unsigned int wide)
|
unsigned int wide)
|
{
|
{
|
if (wide)
|
if (wide)
|
return bfd_mach_o_read_section_64 (abfd, section, offset, prot);
|
return bfd_mach_o_read_section_64 (abfd, offset, prot);
|
else
|
else
|
return bfd_mach_o_read_section_32 (abfd, section, offset, prot);
|
return bfd_mach_o_read_section_32 (abfd, offset, prot);
|
}
|
}
|
|
|
static int
|
static int
|
bfd_mach_o_read_symtab_symbol (bfd *abfd,
|
bfd_mach_o_read_symtab_symbol (bfd *abfd,
|
bfd_mach_o_symtab_command *sym,
|
bfd_mach_o_symtab_command *sym,
|
Line 1636... |
Line 1765... |
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
unsigned int wide = mach_o_wide_p (&mdata->header);
|
unsigned int wide = mach_o_wide_p (&mdata->header);
|
unsigned int symwidth =
|
unsigned int symwidth =
|
wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
|
wide ? BFD_MACH_O_NLIST_64_SIZE : BFD_MACH_O_NLIST_SIZE;
|
unsigned int symoff = sym->symoff + (i * symwidth);
|
unsigned int symoff = sym->symoff + (i * symwidth);
|
unsigned char buf[16];
|
struct mach_o_nlist_64_external raw;
|
unsigned char type = -1;
|
unsigned char type = -1;
|
unsigned char section = -1;
|
unsigned char section = -1;
|
short desc = -1;
|
short desc = -1;
|
symvalue value = -1;
|
symvalue value = -1;
|
unsigned long stroff = -1;
|
unsigned long stroff = -1;
|
unsigned int symtype = -1;
|
unsigned int symtype = -1;
|
|
|
BFD_ASSERT (sym->strtab != NULL);
|
BFD_ASSERT (sym->strtab != NULL);
|
|
|
if (bfd_seek (abfd, symoff, SEEK_SET) != 0
|
if (bfd_seek (abfd, symoff, SEEK_SET) != 0
|
|| bfd_bread ((void *) buf, symwidth, abfd) != symwidth)
|
|| bfd_bread (&raw, symwidth, abfd) != symwidth)
|
{
|
{
|
(*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"),
|
(*_bfd_error_handler)
|
|
(_("bfd_mach_o_read_symtab_symbol: unable to read %d bytes at %lu"),
|
symwidth, (unsigned long) symoff);
|
symwidth, (unsigned long) symoff);
|
return -1;
|
return -1;
|
}
|
}
|
|
|
stroff = bfd_h_get_32 (abfd, buf);
|
stroff = bfd_h_get_32 (abfd, raw.n_strx);
|
type = bfd_h_get_8 (abfd, buf + 4);
|
type = bfd_h_get_8 (abfd, raw.n_type);
|
symtype = type & BFD_MACH_O_N_TYPE;
|
symtype = type & BFD_MACH_O_N_TYPE;
|
section = bfd_h_get_8 (abfd, buf + 5);
|
section = bfd_h_get_8 (abfd, raw.n_sect);
|
desc = bfd_h_get_16 (abfd, buf + 6);
|
desc = bfd_h_get_16 (abfd, raw.n_desc);
|
if (wide)
|
if (wide)
|
value = bfd_h_get_64 (abfd, buf + 8);
|
value = bfd_h_get_64 (abfd, raw.n_value);
|
else
|
else
|
value = bfd_h_get_32 (abfd, buf + 8);
|
value = bfd_h_get_32 (abfd, raw.n_value);
|
|
|
if (stroff >= sym->strsize)
|
if (stroff >= sym->strsize)
|
{
|
{
|
(*_bfd_error_handler) (_("bfd_mach_o_read_symtab_symbol: symbol name out of range (%lu >= %lu)"),
|
(*_bfd_error_handler)
|
|
(_("bfd_mach_o_read_symtab_symbol: name out of range (%lu >= %lu)"),
|
(unsigned long) stroff,
|
(unsigned long) stroff,
|
(unsigned long) sym->strsize);
|
(unsigned long) sym->strsize);
|
return -1;
|
return -1;
|
}
|
}
|
|
|
Line 1828... |
Line 1959... |
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
bfd_mach_o_symtab_command *sym = mdata->symtab;
|
bfd_mach_o_symtab_command *sym = mdata->symtab;
|
unsigned long i;
|
unsigned long i;
|
int ret;
|
int ret;
|
|
|
if (sym->symbols)
|
if (sym == NULL || sym->symbols)
|
|
{
|
|
/* Return now if there are no symbols or if already loaded. */
|
return 0;
|
return 0;
|
|
}
|
|
|
sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (bfd_mach_o_asymbol));
|
sym->symbols = bfd_alloc (abfd, sym->nsyms * sizeof (bfd_mach_o_asymbol));
|
|
|
if (sym->symbols == NULL)
|
if (sym->symbols == NULL)
|
{
|
{
|
Line 1862... |
Line 1996... |
bfd_mach_o_asymbol *s,
|
bfd_mach_o_asymbol *s,
|
unsigned long i)
|
unsigned long i)
|
{
|
{
|
unsigned long isymoff = dysym->indirectsymoff + (i * 4);
|
unsigned long isymoff = dysym->indirectsymoff + (i * 4);
|
unsigned long sym_index;
|
unsigned long sym_index;
|
unsigned char buf[4];
|
unsigned char raw[4];
|
|
|
BFD_ASSERT (i < dysym->nindirectsyms);
|
BFD_ASSERT (i < dysym->nindirectsyms);
|
|
|
if (bfd_seek (abfd, isymoff, SEEK_SET) != 0
|
if (bfd_seek (abfd, isymoff, SEEK_SET) != 0
|
|| bfd_bread ((void *) buf, 4, abfd) != 4)
|
|| bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
|
{
|
{
|
(*_bfd_error_handler) (_("bfd_mach_o_read_dysymtab_symbol: unable to read %lu bytes at %lu"),
|
(*_bfd_error_handler)
|
(unsigned long) 4, isymoff);
|
(_("bfd_mach_o_read_dysymtab_symbol: unable to read %lu bytes at %lu"),
|
|
(unsigned long) sizeof (raw), isymoff);
|
return -1;
|
return -1;
|
}
|
}
|
sym_index = bfd_h_get_32 (abfd, buf);
|
sym_index = bfd_h_get_32 (abfd, raw);
|
|
|
return bfd_mach_o_read_symtab_symbol (abfd, sym, s, sym_index);
|
return bfd_mach_o_read_symtab_symbol (abfd, sym, s, sym_index);
|
}
|
}
|
|
|
static const char *
|
static const char *
|
Line 1919... |
Line 2054... |
|
|
static int
|
static int
|
bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_command *command)
|
bfd_mach_o_read_dylinker (bfd *abfd, bfd_mach_o_load_command *command)
|
{
|
{
|
bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
|
bfd_mach_o_dylinker_command *cmd = &command->command.dylinker;
|
unsigned char buf[4];
|
struct mach_o_str_command_external raw;
|
unsigned int nameoff;
|
unsigned int nameoff;
|
|
|
BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
|
BFD_ASSERT ((command->type == BFD_MACH_O_LC_ID_DYLINKER)
|
|| (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
|
|| (command->type == BFD_MACH_O_LC_LOAD_DYLINKER));
|
|
|
if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
|
if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
|
|| bfd_bread ((void *) buf, 4, abfd) != 4)
|
|| bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
|
return -1;
|
return -1;
|
|
|
nameoff = bfd_h_get_32 (abfd, buf + 0);
|
nameoff = bfd_h_get_32 (abfd, raw.str);
|
|
|
cmd->name_offset = command->offset + nameoff;
|
cmd->name_offset = command->offset + nameoff;
|
cmd->name_len = command->len - nameoff;
|
cmd->name_len = command->len - nameoff;
|
cmd->name_str = bfd_alloc (abfd, cmd->name_len);
|
cmd->name_str = bfd_alloc (abfd, cmd->name_len);
|
if (cmd->name_str == NULL)
|
if (cmd->name_str == NULL)
|
Line 1946... |
Line 2081... |
|
|
static int
|
static int
|
bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
|
bfd_mach_o_read_dylib (bfd *abfd, bfd_mach_o_load_command *command)
|
{
|
{
|
bfd_mach_o_dylib_command *cmd = &command->command.dylib;
|
bfd_mach_o_dylib_command *cmd = &command->command.dylib;
|
unsigned char buf[16];
|
struct mach_o_dylib_command_external raw;
|
unsigned int nameoff;
|
unsigned int nameoff;
|
|
|
switch (command->type)
|
switch (command->type)
|
{
|
{
|
case BFD_MACH_O_LC_LOAD_DYLIB:
|
case BFD_MACH_O_LC_LOAD_DYLIB:
|
Line 1961... |
Line 2096... |
default:
|
default:
|
BFD_FAIL ();
|
BFD_FAIL ();
|
return -1;
|
return -1;
|
}
|
}
|
|
|
if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
|
if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
|
|| bfd_bread ((void *) buf, 16, abfd) != 16)
|
|| bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
|
return -1;
|
return -1;
|
|
|
nameoff = bfd_h_get_32 (abfd, buf + 0);
|
nameoff = bfd_h_get_32 (abfd, raw.name);
|
cmd->timestamp = bfd_h_get_32 (abfd, buf + 4);
|
cmd->timestamp = bfd_h_get_32 (abfd, raw.timestamp);
|
cmd->current_version = bfd_h_get_32 (abfd, buf + 8);
|
cmd->current_version = bfd_h_get_32 (abfd, raw.current_version);
|
cmd->compatibility_version = bfd_h_get_32 (abfd, buf + 12);
|
cmd->compatibility_version = bfd_h_get_32 (abfd, raw.compatibility_version);
|
|
|
cmd->name_offset = command->offset + nameoff;
|
cmd->name_offset = command->offset + nameoff;
|
cmd->name_len = command->len - nameoff;
|
cmd->name_len = command->len - nameoff;
|
cmd->name_str = bfd_alloc (abfd, cmd->name_len);
|
cmd->name_str = bfd_alloc (abfd, cmd->name_len);
|
if (cmd->name_str == NULL)
|
if (cmd->name_str == NULL)
|
Line 1996... |
Line 2131... |
static int
|
static int
|
bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
|
bfd_mach_o_read_thread (bfd *abfd, bfd_mach_o_load_command *command)
|
{
|
{
|
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
bfd_mach_o_thread_command *cmd = &command->command.thread;
|
bfd_mach_o_thread_command *cmd = &command->command.thread;
|
unsigned char buf[8];
|
|
unsigned int offset;
|
unsigned int offset;
|
unsigned int nflavours;
|
unsigned int nflavours;
|
unsigned int i;
|
unsigned int i;
|
|
|
BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
|
BFD_ASSERT ((command->type == BFD_MACH_O_LC_THREAD)
|
Line 2009... |
Line 2143... |
/* Count the number of threads. */
|
/* Count the number of threads. */
|
offset = 8;
|
offset = 8;
|
nflavours = 0;
|
nflavours = 0;
|
while (offset != command->len)
|
while (offset != command->len)
|
{
|
{
|
|
struct mach_o_thread_command_external raw;
|
|
|
if (offset >= command->len)
|
if (offset >= command->len)
|
return -1;
|
return -1;
|
|
|
if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
|
if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
|
|| bfd_bread ((void *) buf, 8, abfd) != 8)
|
|| bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
|
return -1;
|
return -1;
|
|
|
offset += 8 + bfd_h_get_32 (abfd, buf + 4) * 4;
|
offset += sizeof (raw) + bfd_h_get_32 (abfd, raw.count) * 4;
|
nflavours++;
|
nflavours++;
|
}
|
}
|
|
|
/* Allocate threads. */
|
/* Allocate threads. */
|
cmd->flavours = bfd_alloc
|
cmd->flavours = bfd_alloc
|
Line 2031... |
Line 2167... |
|
|
offset = 8;
|
offset = 8;
|
nflavours = 0;
|
nflavours = 0;
|
while (offset != command->len)
|
while (offset != command->len)
|
{
|
{
|
|
struct mach_o_thread_command_external raw;
|
|
|
if (offset >= command->len)
|
if (offset >= command->len)
|
return -1;
|
return -1;
|
|
|
if (nflavours >= cmd->nflavours)
|
if (nflavours >= cmd->nflavours)
|
return -1;
|
return -1;
|
|
|
if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
|
if (bfd_seek (abfd, command->offset + offset, SEEK_SET) != 0
|
|| bfd_bread ((void *) buf, 8, abfd) != 8)
|
|| bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
|
return -1;
|
return -1;
|
|
|
cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, buf);
|
cmd->flavours[nflavours].flavour = bfd_h_get_32 (abfd, raw.flavour);
|
cmd->flavours[nflavours].offset = command->offset + offset + 8;
|
cmd->flavours[nflavours].offset = command->offset + offset + sizeof (raw);
|
cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, buf + 4) * 4;
|
cmd->flavours[nflavours].size = bfd_h_get_32 (abfd, raw.count) * 4;
|
offset += cmd->flavours[nflavours].size + 8;
|
offset += cmd->flavours[nflavours].size + sizeof (raw);
|
nflavours++;
|
nflavours++;
|
}
|
}
|
|
|
for (i = 0; i < nflavours; i++)
|
for (i = 0; i < nflavours; i++)
|
{
|
{
|
Line 2104... |
Line 2242... |
static int
|
static int
|
bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
|
bfd_mach_o_read_dysymtab (bfd *abfd, bfd_mach_o_load_command *command)
|
{
|
{
|
bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab;
|
bfd_mach_o_dysymtab_command *cmd = &command->command.dysymtab;
|
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
unsigned char buf[72];
|
|
|
|
BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
|
BFD_ASSERT (command->type == BFD_MACH_O_LC_DYSYMTAB);
|
|
|
if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
|
{
|
|| bfd_bread ((void *) buf, 72, abfd) != 72)
|
struct mach_o_dysymtab_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 -1;
|
return -1;
|
|
|
cmd->ilocalsym = bfd_h_get_32 (abfd, buf + 0);
|
cmd->ilocalsym = bfd_h_get_32 (abfd, raw.ilocalsym);
|
cmd->nlocalsym = bfd_h_get_32 (abfd, buf + 4);
|
cmd->nlocalsym = bfd_h_get_32 (abfd, raw.nlocalsym);
|
cmd->iextdefsym = bfd_h_get_32 (abfd, buf + 8);
|
cmd->iextdefsym = bfd_h_get_32 (abfd, raw.iextdefsym);
|
cmd->nextdefsym = bfd_h_get_32 (abfd, buf + 12);
|
cmd->nextdefsym = bfd_h_get_32 (abfd, raw.nextdefsym);
|
cmd->iundefsym = bfd_h_get_32 (abfd, buf + 16);
|
cmd->iundefsym = bfd_h_get_32 (abfd, raw.iundefsym);
|
cmd->nundefsym = bfd_h_get_32 (abfd, buf + 20);
|
cmd->nundefsym = bfd_h_get_32 (abfd, raw.nundefsym);
|
cmd->tocoff = bfd_h_get_32 (abfd, buf + 24);
|
cmd->tocoff = bfd_h_get_32 (abfd, raw.tocoff);
|
cmd->ntoc = bfd_h_get_32 (abfd, buf + 28);
|
cmd->ntoc = bfd_h_get_32 (abfd, raw.ntoc);
|
cmd->modtaboff = bfd_h_get_32 (abfd, buf + 32);
|
cmd->modtaboff = bfd_h_get_32 (abfd, raw.modtaboff);
|
cmd->nmodtab = bfd_h_get_32 (abfd, buf + 36);
|
cmd->nmodtab = bfd_h_get_32 (abfd, raw.nmodtab);
|
cmd->extrefsymoff = bfd_h_get_32 (abfd, buf + 40);
|
cmd->extrefsymoff = bfd_h_get_32 (abfd, raw.extrefsymoff);
|
cmd->nextrefsyms = bfd_h_get_32 (abfd, buf + 44);
|
cmd->nextrefsyms = bfd_h_get_32 (abfd, raw.nextrefsyms);
|
cmd->indirectsymoff = bfd_h_get_32 (abfd, buf + 48);
|
cmd->indirectsymoff = bfd_h_get_32 (abfd, raw.indirectsymoff);
|
cmd->nindirectsyms = bfd_h_get_32 (abfd, buf + 52);
|
cmd->nindirectsyms = bfd_h_get_32 (abfd, raw.nindirectsyms);
|
cmd->extreloff = bfd_h_get_32 (abfd, buf + 56);
|
cmd->extreloff = bfd_h_get_32 (abfd, raw.extreloff);
|
cmd->nextrel = bfd_h_get_32 (abfd, buf + 60);
|
cmd->nextrel = bfd_h_get_32 (abfd, raw.nextrel);
|
cmd->locreloff = bfd_h_get_32 (abfd, buf + 64);
|
cmd->locreloff = bfd_h_get_32 (abfd, raw.locreloff);
|
cmd->nlocrel = bfd_h_get_32 (abfd, buf + 68);
|
cmd->nlocrel = bfd_h_get_32 (abfd, raw.nlocrel);
|
|
}
|
|
|
if (cmd->nmodtab != 0)
|
if (cmd->nmodtab != 0)
|
{
|
{
|
unsigned int i;
|
unsigned int i;
|
int wide = bfd_mach_o_wide_p (abfd);
|
int wide = bfd_mach_o_wide_p (abfd);
|
Line 2149... |
Line 2290... |
|
|
for (i = 0; i < cmd->nmodtab; i++)
|
for (i = 0; i < cmd->nmodtab; i++)
|
{
|
{
|
bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
|
bfd_mach_o_dylib_module *module = &cmd->dylib_module[i];
|
unsigned long v;
|
unsigned long v;
|
|
unsigned char buf[56];
|
|
|
if (bfd_bread ((void *) buf, module_len, abfd) != module_len)
|
if (bfd_bread ((void *) buf, module_len, abfd) != module_len)
|
return -1;
|
return -1;
|
|
|
module->module_name_idx = bfd_h_get_32 (abfd, buf + 0);
|
module->module_name_idx = bfd_h_get_32 (abfd, buf + 0);
|
Line 2195... |
Line 2337... |
if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
|
if (bfd_seek (abfd, cmd->tocoff, SEEK_SET) != 0)
|
return -1;
|
return -1;
|
|
|
for (i = 0; i < cmd->ntoc; i++)
|
for (i = 0; i < cmd->ntoc; i++)
|
{
|
{
|
|
struct mach_o_dylib_table_of_contents_external raw;
|
bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i];
|
bfd_mach_o_dylib_table_of_content *toc = &cmd->dylib_toc[i];
|
|
|
if (bfd_bread ((void *) buf, 8, abfd) != 8)
|
if (bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
|
return -1;
|
return -1;
|
|
|
toc->symbol_index = bfd_h_get_32 (abfd, buf + 0);
|
toc->symbol_index = bfd_h_get_32 (abfd, raw.symbol_index);
|
toc->module_index = bfd_h_get_32 (abfd, buf + 4);
|
toc->module_index = bfd_h_get_32 (abfd, raw.module_index);
|
}
|
}
|
}
|
}
|
|
|
if (cmd->nindirectsyms != 0)
|
if (cmd->nindirectsyms != 0)
|
{
|
{
|
Line 2219... |
Line 2362... |
if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
|
if (bfd_seek (abfd, cmd->indirectsymoff, SEEK_SET) != 0)
|
return -1;
|
return -1;
|
|
|
for (i = 0; i < cmd->nindirectsyms; i++)
|
for (i = 0; i < cmd->nindirectsyms; i++)
|
{
|
{
|
|
unsigned char raw[4];
|
unsigned int *is = &cmd->indirect_syms[i];
|
unsigned int *is = &cmd->indirect_syms[i];
|
|
|
if (bfd_bread ((void *) buf, 4, abfd) != 4)
|
if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
|
return -1;
|
return -1;
|
|
|
*is = bfd_h_get_32 (abfd, buf + 0);
|
*is = bfd_h_get_32 (abfd, raw);
|
}
|
}
|
}
|
}
|
|
|
if (cmd->nextrefsyms != 0)
|
if (cmd->nextrefsyms != 0)
|
{
|
{
|
Line 2243... |
Line 2387... |
if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
|
if (bfd_seek (abfd, cmd->extrefsymoff, SEEK_SET) != 0)
|
return -1;
|
return -1;
|
|
|
for (i = 0; i < cmd->nextrefsyms; i++)
|
for (i = 0; i < cmd->nextrefsyms; i++)
|
{
|
{
|
|
unsigned char raw[4];
|
bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
|
bfd_mach_o_dylib_reference *ref = &cmd->ext_refs[i];
|
|
|
if (bfd_bread ((void *) buf, 4, abfd) != 4)
|
if (bfd_bread (raw, sizeof (raw), abfd) != sizeof (raw))
|
return -1;
|
return -1;
|
|
|
/* Fields isym and flags are written as bit-fields, thus we need
|
/* Fields isym and flags are written as bit-fields, thus we need
|
a specific processing for endianness. */
|
a specific processing for endianness. */
|
v = bfd_h_get_32 (abfd, buf + 0);
|
v = bfd_h_get_32 (abfd, raw);
|
if (bfd_big_endian (abfd))
|
if (bfd_big_endian (abfd))
|
{
|
{
|
ref->isym = (v >> 8) & 0xffffff;
|
ref->isym = (v >> 8) & 0xffffff;
|
ref->flags = v & 0xff;
|
ref->flags = v & 0xff;
|
}
|
}
|
Line 2276... |
Line 2421... |
static int
|
static int
|
bfd_mach_o_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
|
bfd_mach_o_read_symtab (bfd *abfd, bfd_mach_o_load_command *command)
|
{
|
{
|
bfd_mach_o_symtab_command *symtab = &command->command.symtab;
|
bfd_mach_o_symtab_command *symtab = &command->command.symtab;
|
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
unsigned char buf[16];
|
struct mach_o_symtab_command_external raw;
|
|
|
BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
|
BFD_ASSERT (command->type == BFD_MACH_O_LC_SYMTAB);
|
|
|
if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
|
if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
|
|| bfd_bread ((void *) buf, 16, abfd) != 16)
|
|| bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
|
return -1;
|
return -1;
|
|
|
symtab->symoff = bfd_h_get_32 (abfd, buf);
|
symtab->symoff = bfd_h_get_32 (abfd, raw.symoff);
|
symtab->nsyms = bfd_h_get_32 (abfd, buf + 4);
|
symtab->nsyms = bfd_h_get_32 (abfd, raw.nsyms);
|
symtab->stroff = bfd_h_get_32 (abfd, buf + 8);
|
symtab->stroff = bfd_h_get_32 (abfd, raw.stroff);
|
symtab->strsize = bfd_h_get_32 (abfd, buf + 12);
|
symtab->strsize = bfd_h_get_32 (abfd, raw.strsize);
|
symtab->symbols = NULL;
|
symtab->symbols = NULL;
|
symtab->strtab = NULL;
|
symtab->strtab = NULL;
|
|
|
if (symtab->nsyms != 0)
|
if (symtab->nsyms != 0)
|
abfd->flags |= HAS_SYMS;
|
abfd->flags |= HAS_SYMS;
|
Line 2307... |
Line 2452... |
{
|
{
|
bfd_mach_o_uuid_command *cmd = &command->command.uuid;
|
bfd_mach_o_uuid_command *cmd = &command->command.uuid;
|
|
|
BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
|
BFD_ASSERT (command->type == BFD_MACH_O_LC_UUID);
|
|
|
if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
|
if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
|
|| bfd_bread ((void *) cmd->uuid, 16, abfd) != 16)
|
|| bfd_bread (cmd->uuid, 16, abfd) != 16)
|
return -1;
|
return -1;
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
static int
|
static int
|
bfd_mach_o_read_linkedit (bfd *abfd, bfd_mach_o_load_command *command)
|
bfd_mach_o_read_linkedit (bfd *abfd, bfd_mach_o_load_command *command)
|
{
|
{
|
bfd_mach_o_linkedit_command *cmd = &command->command.linkedit;
|
bfd_mach_o_linkedit_command *cmd = &command->command.linkedit;
|
char buf[8];
|
struct mach_o_linkedit_data_command_external raw;
|
|
|
if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
|
if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
|
|| bfd_bread ((void *) buf, 8, abfd) != 8)
|
|| bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
|
return -1;
|
return -1;
|
|
|
cmd->dataoff = bfd_get_32 (abfd, buf + 0);
|
cmd->dataoff = bfd_get_32 (abfd, raw.dataoff);
|
cmd->datasize = bfd_get_32 (abfd, buf + 4);
|
cmd->datasize = bfd_get_32 (abfd, raw.datasize);
|
return 0;
|
return 0;
|
}
|
}
|
|
|
static int
|
static int
|
bfd_mach_o_read_str (bfd *abfd, bfd_mach_o_load_command *command)
|
bfd_mach_o_read_str (bfd *abfd, bfd_mach_o_load_command *command)
|
{
|
{
|
bfd_mach_o_str_command *cmd = &command->command.str;
|
bfd_mach_o_str_command *cmd = &command->command.str;
|
char buf[4];
|
struct mach_o_str_command_external raw;
|
unsigned long off;
|
unsigned long off;
|
|
|
if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
|
if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
|
|| bfd_bread ((void *) buf, 4, abfd) != 4)
|
|| bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
|
return -1;
|
return -1;
|
|
|
off = bfd_get_32 (abfd, buf + 0);
|
off = bfd_get_32 (abfd, raw.str);
|
cmd->stroff = command->offset + off;
|
cmd->stroff = command->offset + off;
|
cmd->str_len = command->len - off;
|
cmd->str_len = command->len - off;
|
cmd->str = bfd_alloc (abfd, cmd->str_len);
|
cmd->str = bfd_alloc (abfd, cmd->str_len);
|
if (cmd->str == NULL)
|
if (cmd->str == NULL)
|
return -1;
|
return -1;
|
Line 2356... |
Line 2501... |
|
|
static int
|
static int
|
bfd_mach_o_read_dyld_info (bfd *abfd, bfd_mach_o_load_command *command)
|
bfd_mach_o_read_dyld_info (bfd *abfd, bfd_mach_o_load_command *command)
|
{
|
{
|
bfd_mach_o_dyld_info_command *cmd = &command->command.dyld_info;
|
bfd_mach_o_dyld_info_command *cmd = &command->command.dyld_info;
|
char buf[40];
|
struct mach_o_dyld_info_command_external raw;
|
|
|
if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
|
if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
|
|| bfd_bread ((void *) buf, sizeof (buf), abfd) != sizeof (buf))
|
|| bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
|
return -1;
|
return -1;
|
|
|
cmd->rebase_off = bfd_get_32 (abfd, buf + 0);
|
cmd->rebase_off = bfd_get_32 (abfd, raw.rebase_off);
|
cmd->rebase_size = bfd_get_32 (abfd, buf + 4);
|
cmd->rebase_size = bfd_get_32 (abfd, raw.rebase_size);
|
cmd->bind_off = bfd_get_32 (abfd, buf + 8);
|
cmd->bind_off = bfd_get_32 (abfd, raw.bind_off);
|
cmd->bind_size = bfd_get_32 (abfd, buf + 12);
|
cmd->bind_size = bfd_get_32 (abfd, raw.bind_size);
|
cmd->weak_bind_off = bfd_get_32 (abfd, buf + 16);
|
cmd->weak_bind_off = bfd_get_32 (abfd, raw.weak_bind_off);
|
cmd->weak_bind_size = bfd_get_32 (abfd, buf + 20);
|
cmd->weak_bind_size = bfd_get_32 (abfd, raw.weak_bind_size);
|
cmd->lazy_bind_off = bfd_get_32 (abfd, buf + 24);
|
cmd->lazy_bind_off = bfd_get_32 (abfd, raw.lazy_bind_off);
|
cmd->lazy_bind_size = bfd_get_32 (abfd, buf + 28);
|
cmd->lazy_bind_size = bfd_get_32 (abfd, raw.lazy_bind_size);
|
cmd->export_off = bfd_get_32 (abfd, buf + 32);
|
cmd->export_off = bfd_get_32 (abfd, raw.export_off);
|
cmd->export_size = bfd_get_32 (abfd, buf + 36);
|
cmd->export_size = bfd_get_32 (abfd, raw.export_size);
|
return 0;
|
return 0;
|
}
|
}
|
|
|
|
static bfd_boolean
|
|
bfd_mach_o_read_version_min (bfd *abfd, bfd_mach_o_load_command *command)
|
|
{
|
|
bfd_mach_o_version_min_command *cmd = &command->command.version_min;
|
|
struct mach_o_version_min_command_external raw;
|
|
unsigned int 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_32 (abfd, raw.version);
|
|
cmd->rel = ver >> 16;
|
|
cmd->maj = ver >> 8;
|
|
cmd->min = ver;
|
|
cmd->reserved = bfd_get_32 (abfd, raw.reserved);
|
|
return TRUE;
|
|
}
|
|
|
static int
|
static int
|
bfd_mach_o_read_segment (bfd *abfd,
|
bfd_mach_o_read_segment (bfd *abfd,
|
bfd_mach_o_load_command *command,
|
bfd_mach_o_load_command *command,
|
unsigned int wide)
|
unsigned int wide)
|
{
|
{
|
unsigned char buf[64];
|
|
bfd_mach_o_segment_command *seg = &command->command.segment;
|
bfd_mach_o_segment_command *seg = &command->command.segment;
|
unsigned long i;
|
unsigned long i;
|
|
|
if (wide)
|
if (wide)
|
{
|
{
|
|
struct mach_o_segment_command_64_external raw;
|
|
|
BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
|
BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT_64);
|
|
|
if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
|
if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
|
|| bfd_bread ((void *) buf, 64, abfd) != 64)
|
|| bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
|
return -1;
|
return -1;
|
|
|
memcpy (seg->segname, buf, 16);
|
memcpy (seg->segname, raw.segname, 16);
|
seg->segname[16] = '\0';
|
seg->segname[16] = '\0';
|
|
|
seg->vmaddr = bfd_h_get_64 (abfd, buf + 16);
|
seg->vmaddr = bfd_h_get_64 (abfd, raw.vmaddr);
|
seg->vmsize = bfd_h_get_64 (abfd, buf + 24);
|
seg->vmsize = bfd_h_get_64 (abfd, raw.vmsize);
|
seg->fileoff = bfd_h_get_64 (abfd, buf + 32);
|
seg->fileoff = bfd_h_get_64 (abfd, raw.fileoff);
|
seg->filesize = bfd_h_get_64 (abfd, buf + 40);
|
seg->filesize = bfd_h_get_64 (abfd, raw.filesize);
|
seg->maxprot = bfd_h_get_32 (abfd, buf + 48);
|
seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
|
seg->initprot = bfd_h_get_32 (abfd, buf + 52);
|
seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
|
seg->nsects = bfd_h_get_32 (abfd, buf + 56);
|
seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
|
seg->flags = bfd_h_get_32 (abfd, buf + 60);
|
seg->flags = bfd_h_get_32 (abfd, raw.flags);
|
}
|
}
|
else
|
else
|
{
|
{
|
|
struct mach_o_segment_command_32_external raw;
|
|
|
BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
|
BFD_ASSERT (command->type == BFD_MACH_O_LC_SEGMENT);
|
|
|
if (bfd_seek (abfd, command->offset + 8, SEEK_SET) != 0
|
if (bfd_seek (abfd, command->offset + BFD_MACH_O_LC_SIZE, SEEK_SET) != 0
|
|| bfd_bread ((void *) buf, 48, abfd) != 48)
|
|| bfd_bread (&raw, sizeof (raw), abfd) != sizeof (raw))
|
return -1;
|
return -1;
|
|
|
memcpy (seg->segname, buf, 16);
|
memcpy (seg->segname, raw.segname, 16);
|
seg->segname[16] = '\0';
|
seg->segname[16] = '\0';
|
|
|
seg->vmaddr = bfd_h_get_32 (abfd, buf + 16);
|
seg->vmaddr = bfd_h_get_32 (abfd, raw.vmaddr);
|
seg->vmsize = bfd_h_get_32 (abfd, buf + 20);
|
seg->vmsize = bfd_h_get_32 (abfd, raw.vmsize);
|
seg->fileoff = bfd_h_get_32 (abfd, buf + 24);
|
seg->fileoff = bfd_h_get_32 (abfd, raw.fileoff);
|
seg->filesize = bfd_h_get_32 (abfd, buf + 28);
|
seg->filesize = bfd_h_get_32 (abfd, raw.filesize);
|
seg->maxprot = bfd_h_get_32 (abfd, buf + 32);
|
seg->maxprot = bfd_h_get_32 (abfd, raw.maxprot);
|
seg->initprot = bfd_h_get_32 (abfd, buf + 36);
|
seg->initprot = bfd_h_get_32 (abfd, raw.initprot);
|
seg->nsects = bfd_h_get_32 (abfd, buf + 40);
|
seg->nsects = bfd_h_get_32 (abfd, raw.nsects);
|
seg->flags = bfd_h_get_32 (abfd, buf + 44);
|
seg->flags = bfd_h_get_32 (abfd, raw.flags);
|
}
|
}
|
|
seg->sect_head = NULL;
|
if (seg->nsects != 0)
|
seg->sect_tail = NULL;
|
{
|
|
seg->sections = bfd_alloc (abfd, seg->nsects
|
|
* sizeof (bfd_mach_o_section));
|
|
if (seg->sections == NULL)
|
|
return -1;
|
|
|
|
for (i = 0; i < seg->nsects; i++)
|
for (i = 0; i < seg->nsects; i++)
|
{
|
{
|
bfd_vma segoff;
|
bfd_vma segoff;
|
|
asection *sec;
|
|
|
if (wide)
|
if (wide)
|
segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
|
segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
|
+ (i * BFD_MACH_O_SECTION_64_SIZE);
|
+ (i * BFD_MACH_O_SECTION_64_SIZE);
|
else
|
else
|
segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
|
segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
|
+ (i * BFD_MACH_O_SECTION_SIZE);
|
+ (i * BFD_MACH_O_SECTION_SIZE);
|
|
|
if (bfd_mach_o_read_section
|
sec = bfd_mach_o_read_section (abfd, segoff, seg->initprot, wide);
|
(abfd, &seg->sections[i], segoff, seg->initprot, wide) != 0)
|
if (sec == NULL)
|
return -1;
|
return -1;
|
}
|
|
|
bfd_mach_o_append_section_to_segment (seg, sec);
|
}
|
}
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
Line 2466... |
Line 2631... |
}
|
}
|
|
|
static int
|
static int
|
bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
|
bfd_mach_o_read_command (bfd *abfd, bfd_mach_o_load_command *command)
|
{
|
{
|
unsigned char buf[8];
|
struct mach_o_load_command_external raw;
|
|
unsigned int cmd;
|
|
|
/* Read command type and length. */
|
/* Read command type and length. */
|
if (bfd_seek (abfd, command->offset, SEEK_SET) != 0
|
if (bfd_seek (abfd, command->offset, SEEK_SET) != 0
|
|| bfd_bread ((void *) buf, 8, abfd) != 8)
|
|| bfd_bread (&raw, BFD_MACH_O_LC_SIZE, abfd) != BFD_MACH_O_LC_SIZE)
|
return -1;
|
return -1;
|
|
|
command->type = bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD;
|
cmd = bfd_h_get_32 (abfd, raw.cmd);
|
command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD
|
command->type = cmd & ~BFD_MACH_O_LC_REQ_DYLD;
|
? TRUE : FALSE);
|
command->type_required = cmd & BFD_MACH_O_LC_REQ_DYLD ? TRUE : FALSE;
|
command->len = bfd_h_get_32 (abfd, buf + 4);
|
command->len = bfd_h_get_32 (abfd, raw.cmdsize);
|
|
|
switch (command->type)
|
switch (command->type)
|
{
|
{
|
case BFD_MACH_O_LC_SEGMENT:
|
case BFD_MACH_O_LC_SEGMENT:
|
if (bfd_mach_o_read_segment_32 (abfd, command) != 0)
|
if (bfd_mach_o_read_segment_32 (abfd, command) != 0)
|
Line 2521... |
Line 2687... |
case BFD_MACH_O_LC_IDFVMLIB:
|
case BFD_MACH_O_LC_IDFVMLIB:
|
case BFD_MACH_O_LC_IDENT:
|
case BFD_MACH_O_LC_IDENT:
|
case BFD_MACH_O_LC_FVMFILE:
|
case BFD_MACH_O_LC_FVMFILE:
|
case BFD_MACH_O_LC_PREPAGE:
|
case BFD_MACH_O_LC_PREPAGE:
|
case BFD_MACH_O_LC_ROUTINES:
|
case BFD_MACH_O_LC_ROUTINES:
|
|
case BFD_MACH_O_LC_ROUTINES_64:
|
break;
|
break;
|
case BFD_MACH_O_LC_SUB_FRAMEWORK:
|
case BFD_MACH_O_LC_SUB_FRAMEWORK:
|
case BFD_MACH_O_LC_SUB_UMBRELLA:
|
case BFD_MACH_O_LC_SUB_UMBRELLA:
|
case BFD_MACH_O_LC_SUB_LIBRARY:
|
case BFD_MACH_O_LC_SUB_LIBRARY:
|
case BFD_MACH_O_LC_SUB_CLIENT:
|
case BFD_MACH_O_LC_SUB_CLIENT:
|
Line 2543... |
Line 2710... |
if (bfd_mach_o_read_uuid (abfd, command) != 0)
|
if (bfd_mach_o_read_uuid (abfd, command) != 0)
|
return -1;
|
return -1;
|
break;
|
break;
|
case BFD_MACH_O_LC_CODE_SIGNATURE:
|
case BFD_MACH_O_LC_CODE_SIGNATURE:
|
case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
|
case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
|
|
case BFD_MACH_O_LC_FUNCTION_STARTS:
|
if (bfd_mach_o_read_linkedit (abfd, command) != 0)
|
if (bfd_mach_o_read_linkedit (abfd, command) != 0)
|
return -1;
|
return -1;
|
break;
|
break;
|
case BFD_MACH_O_LC_DYLD_INFO:
|
case BFD_MACH_O_LC_DYLD_INFO:
|
if (bfd_mach_o_read_dyld_info (abfd, command) != 0)
|
if (bfd_mach_o_read_dyld_info (abfd, command) != 0)
|
return -1;
|
return -1;
|
break;
|
break;
|
|
case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
|
|
case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
|
|
if (!bfd_mach_o_read_version_min (abfd, command))
|
|
return -1;
|
|
break;
|
default:
|
default:
|
(*_bfd_error_handler) (_("unable to read unknown load command 0x%lx"),
|
(*_bfd_error_handler) (_("unable to read unknown load command 0x%lx"),
|
(unsigned long) command->type);
|
(unsigned long) command->type);
|
break;
|
break;
|
}
|
}
|
Line 2564... |
Line 2737... |
static void
|
static void
|
bfd_mach_o_flatten_sections (bfd *abfd)
|
bfd_mach_o_flatten_sections (bfd *abfd)
|
{
|
{
|
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
long csect = 0;
|
long csect = 0;
|
unsigned long i, j;
|
unsigned long i;
|
|
|
/* Count total number of sections. */
|
/* Count total number of sections. */
|
mdata->nsects = 0;
|
mdata->nsects = 0;
|
|
|
for (i = 0; i < mdata->header.ncmds; i++)
|
for (i = 0; i < mdata->header.ncmds; i++)
|
Line 2594... |
Line 2767... |
{
|
{
|
if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
|
if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT
|
|| mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
|
|| mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
|
{
|
{
|
bfd_mach_o_segment_command *seg;
|
bfd_mach_o_segment_command *seg;
|
|
bfd_mach_o_section *sec;
|
|
|
seg = &mdata->commands[i].command.segment;
|
seg = &mdata->commands[i].command.segment;
|
BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
|
BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
|
|
|
for (j = 0; j < seg->nsects; j++)
|
for (sec = seg->sect_head; sec != NULL; sec = sec->next)
|
mdata->sections[csect++] = &seg->sections[j];
|
mdata->sections[csect++] = sec;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
int
|
int
|
Line 2929... |
Line 3103... |
|
|
const bfd_target *
|
const bfd_target *
|
bfd_mach_o_archive_p (bfd *abfd)
|
bfd_mach_o_archive_p (bfd *abfd)
|
{
|
{
|
mach_o_fat_data_struct *adata = NULL;
|
mach_o_fat_data_struct *adata = NULL;
|
unsigned char buf[20];
|
struct mach_o_fat_header_external hdr;
|
unsigned long i;
|
unsigned long i;
|
|
|
if (bfd_seek (abfd, 0, SEEK_SET) != 0
|
if (bfd_seek (abfd, 0, SEEK_SET) != 0
|
|| bfd_bread ((void *) buf, 8, abfd) != 8)
|
|| bfd_bread (&hdr, sizeof (hdr), abfd) != sizeof (hdr))
|
goto error;
|
goto error;
|
|
|
adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
|
adata = bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
|
if (adata == NULL)
|
if (adata == NULL)
|
goto error;
|
goto error;
|
|
|
adata->magic = bfd_getb32 (buf);
|
adata->magic = bfd_getb32 (hdr.magic);
|
adata->nfat_arch = bfd_getb32 (buf + 4);
|
adata->nfat_arch = bfd_getb32 (hdr.nfat_arch);
|
if (adata->magic != 0xcafebabe)
|
if (adata->magic != 0xcafebabe)
|
goto error;
|
goto error;
|
/* Avoid matching Java bytecode files, which have the same magic number.
|
/* Avoid matching Java bytecode files, which have the same magic number.
|
In the Java bytecode file format this field contains the JVM version,
|
In the Java bytecode file format this field contains the JVM version,
|
which starts at 43.0. */
|
which starts at 43.0. */
|
Line 2957... |
Line 3131... |
if (adata->archentries == NULL)
|
if (adata->archentries == NULL)
|
goto error;
|
goto error;
|
|
|
for (i = 0; i < adata->nfat_arch; i++)
|
for (i = 0; i < adata->nfat_arch; i++)
|
{
|
{
|
if (bfd_seek (abfd, 8 + 20 * i, SEEK_SET) != 0
|
struct mach_o_fat_arch_external arch;
|
|| bfd_bread ((void *) buf, 20, abfd) != 20)
|
if (bfd_bread (&arch, sizeof (arch), abfd) != sizeof (arch))
|
goto error;
|
goto error;
|
adata->archentries[i].cputype = bfd_getb32 (buf);
|
adata->archentries[i].cputype = bfd_getb32 (arch.cputype);
|
adata->archentries[i].cpusubtype = bfd_getb32 (buf + 4);
|
adata->archentries[i].cpusubtype = bfd_getb32 (arch.cpusubtype);
|
adata->archentries[i].offset = bfd_getb32 (buf + 8);
|
adata->archentries[i].offset = bfd_getb32 (arch.offset);
|
adata->archentries[i].size = bfd_getb32 (buf + 12);
|
adata->archentries[i].size = bfd_getb32 (arch.size);
|
adata->archentries[i].align = bfd_getb32 (buf + 16);
|
adata->archentries[i].align = bfd_getb32 (arch.align);
|
}
|
}
|
|
|
abfd->tdata.mach_o_fat_data = adata;
|
abfd->tdata.mach_o_fat_data = adata;
|
return abfd->xvec;
|
return abfd->xvec;
|
|
|
Line 3109... |
Line 3283... |
|
|
return NULL;
|
return NULL;
|
}
|
}
|
|
|
int
|
int
|
bfd_mach_o_lookup_section (bfd *abfd,
|
|
asection *section,
|
|
bfd_mach_o_load_command **mcommand,
|
|
bfd_mach_o_section **msection)
|
|
{
|
|
struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
|
|
unsigned int i, j, num;
|
|
|
|
bfd_mach_o_load_command *ncmd = NULL;
|
|
bfd_mach_o_section *nsect = NULL;
|
|
|
|
BFD_ASSERT (mcommand != NULL);
|
|
BFD_ASSERT (msection != NULL);
|
|
|
|
num = 0;
|
|
for (i = 0; i < md->header.ncmds; i++)
|
|
{
|
|
struct bfd_mach_o_load_command *cmd = &md->commands[i];
|
|
struct bfd_mach_o_segment_command *seg = NULL;
|
|
|
|
if (cmd->type != BFD_MACH_O_LC_SEGMENT
|
|
|| cmd->type != BFD_MACH_O_LC_SEGMENT_64)
|
|
continue;
|
|
seg = &cmd->command.segment;
|
|
|
|
for (j = 0; j < seg->nsects; j++)
|
|
{
|
|
struct bfd_mach_o_section *sect = &seg->sections[j];
|
|
|
|
if (sect->bfdsection == section)
|
|
{
|
|
if (num == 0)
|
|
{
|
|
nsect = sect;
|
|
ncmd = cmd;
|
|
}
|
|
num++;
|
|
}
|
|
}
|
|
}
|
|
|
|
*mcommand = ncmd;
|
|
*msection = nsect;
|
|
return num;
|
|
}
|
|
|
|
int
|
|
bfd_mach_o_lookup_command (bfd *abfd,
|
bfd_mach_o_lookup_command (bfd *abfd,
|
bfd_mach_o_load_command_type type,
|
bfd_mach_o_load_command_type type,
|
bfd_mach_o_load_command **mcommand)
|
bfd_mach_o_load_command **mcommand)
|
{
|
{
|
struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
|
struct mach_o_data_struct *md = bfd_mach_o_get_data (abfd);
|
Line 3245... |
Line 3372... |
if (first)
|
if (first)
|
fprintf (file, "-");
|
fprintf (file, "-");
|
}
|
}
|
|
|
static const char *
|
static const char *
|
bfd_mach_o_get_name (const bfd_mach_o_xlat_name *table, unsigned long val)
|
bfd_mach_o_get_name_or_null (const bfd_mach_o_xlat_name *table,
|
|
unsigned long val)
|
{
|
{
|
for (; table->name; table++)
|
for (; table->name; table++)
|
if (table->val == val)
|
if (table->val == val)
|
return table->name;
|
return table->name;
|
|
return NULL;
|
|
}
|
|
|
|
static const char *
|
|
bfd_mach_o_get_name (const bfd_mach_o_xlat_name *table, unsigned long val)
|
|
{
|
|
const char *res = bfd_mach_o_get_name_or_null (table, val);
|
|
|
|
if (res == NULL)
|
return "*UNKNOWN*";
|
return "*UNKNOWN*";
|
|
else
|
|
return res;
|
}
|
}
|
|
|
static bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
|
static bfd_mach_o_xlat_name bfd_mach_o_cpu_name[] =
|
{
|
{
|
{ "vax", BFD_MACH_O_CPU_TYPE_VAX },
|
{ "vax", BFD_MACH_O_CPU_TYPE_VAX },
|
Line 3388... |
Line 3527... |
{ "segment_split_info", BFD_MACH_O_LC_SEGMENT_SPLIT_INFO},
|
{ "segment_split_info", BFD_MACH_O_LC_SEGMENT_SPLIT_INFO},
|
{ "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB},
|
{ "reexport_dylib", BFD_MACH_O_LC_REEXPORT_DYLIB},
|
{ "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB},
|
{ "lazy_load_dylib", BFD_MACH_O_LC_LAZY_LOAD_DYLIB},
|
{ "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO},
|
{ "encryption_info", BFD_MACH_O_LC_ENCRYPTION_INFO},
|
{ "dyld_info", BFD_MACH_O_LC_DYLD_INFO},
|
{ "dyld_info", BFD_MACH_O_LC_DYLD_INFO},
|
|
{ "load_upward_lib", BFD_MACH_O_LC_LOAD_UPWARD_DYLIB},
|
|
{ "version_min_macosx", BFD_MACH_O_LC_VERSION_MIN_MACOSX},
|
|
{ "version_min_iphoneos", BFD_MACH_O_LC_VERSION_MIN_IPHONEOS},
|
|
{ "function_starts", BFD_MACH_O_LC_FUNCTION_STARTS},
|
|
{ "dyld_environment", BFD_MACH_O_LC_DYLD_ENVIRONMENT},
|
{ NULL, 0}
|
{ NULL, 0}
|
};
|
};
|
|
|
|
/* Get the section type from NAME. Return -1 if NAME is unknown. */
|
|
|
|
unsigned int
|
|
bfd_mach_o_get_section_type_from_name (const char *name)
|
|
{
|
|
bfd_mach_o_xlat_name *x;
|
|
|
|
for (x = bfd_mach_o_section_type_name; x->name; x++)
|
|
if (strcmp (x->name, name) == 0)
|
|
return x->val;
|
|
return (unsigned int)-1;
|
|
}
|
|
|
|
/* Get the section attribute from NAME. Return -1 if NAME is unknown. */
|
|
|
|
unsigned int
|
|
bfd_mach_o_get_section_attribute_from_name (const char *name)
|
|
{
|
|
bfd_mach_o_xlat_name *x;
|
|
|
|
for (x = bfd_mach_o_section_attribute_name; x->name; x++)
|
|
if (strcmp (x->name, name) == 0)
|
|
return x->val;
|
|
return (unsigned int)-1;
|
|
}
|
|
|
static void
|
static void
|
bfd_mach_o_print_private_header (bfd *abfd, FILE *file)
|
bfd_mach_o_print_private_header (bfd *abfd, FILE *file)
|
{
|
{
|
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
bfd_mach_o_header *h = &mdata->header;
|
bfd_mach_o_header *h = &mdata->header;
|
Line 3417... |
Line 3587... |
|
|
static void
|
static void
|
bfd_mach_o_print_section_map (bfd *abfd, FILE *file)
|
bfd_mach_o_print_section_map (bfd *abfd, FILE *file)
|
{
|
{
|
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
unsigned int i, j;
|
unsigned int i;
|
unsigned int sec_nbr = 0;
|
unsigned int sec_nbr = 0;
|
|
|
fputs (_("Segments and Sections:\n"), file);
|
fputs (_("Segments and Sections:\n"), file);
|
fputs (_(" #: Segment name Section name Address\n"), file);
|
fputs (_(" #: Segment name Section name Address\n"), file);
|
|
|
for (i = 0; i < mdata->header.ncmds; i++)
|
for (i = 0; i < mdata->header.ncmds; i++)
|
{
|
{
|
bfd_mach_o_segment_command *seg;
|
bfd_mach_o_segment_command *seg;
|
|
bfd_mach_o_section *sec;
|
|
|
if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
|
if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
|
&& mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
|
&& mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
|
continue;
|
continue;
|
|
|
Line 3442... |
Line 3613... |
fputc (' ', file);
|
fputc (' ', file);
|
fputc (seg->initprot & BFD_MACH_O_PROT_READ ? 'r' : '-', file);
|
fputc (seg->initprot & BFD_MACH_O_PROT_READ ? 'r' : '-', file);
|
fputc (seg->initprot & BFD_MACH_O_PROT_WRITE ? 'w' : '-', file);
|
fputc (seg->initprot & BFD_MACH_O_PROT_WRITE ? 'w' : '-', file);
|
fputc (seg->initprot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-', file);
|
fputc (seg->initprot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-', file);
|
fprintf (file, "]\n");
|
fprintf (file, "]\n");
|
for (j = 0; j < seg->nsects; j++)
|
|
|
for (sec = seg->sect_head; sec != NULL; sec = sec->next)
|
{
|
{
|
bfd_mach_o_section *sec = &seg->sections[j];
|
|
fprintf (file, "%02u: %-16s %-16s ", ++sec_nbr,
|
fprintf (file, "%02u: %-16s %-16s ", ++sec_nbr,
|
sec->segname, sec->sectname);
|
sec->segname, sec->sectname);
|
fprintf_vma (file, sec->addr);
|
fprintf_vma (file, sec->addr);
|
fprintf (file, " ");
|
fprintf (file, " ");
|
fprintf_vma (file, sec->size);
|
fprintf_vma (file, sec->size);
|
Line 3510... |
Line 3681... |
static void
|
static void
|
bfd_mach_o_print_segment (bfd *abfd ATTRIBUTE_UNUSED,
|
bfd_mach_o_print_segment (bfd *abfd ATTRIBUTE_UNUSED,
|
bfd_mach_o_load_command *cmd, FILE *file)
|
bfd_mach_o_load_command *cmd, FILE *file)
|
{
|
{
|
bfd_mach_o_segment_command *seg = &cmd->command.segment;
|
bfd_mach_o_segment_command *seg = &cmd->command.segment;
|
unsigned int i;
|
bfd_mach_o_section *sec;
|
|
|
fprintf (file, " name: %s\n", *seg->segname ? seg->segname : "*none*");
|
fprintf (file, " name: %s\n", *seg->segname ? seg->segname : "*none*");
|
fprintf (file, " vmaddr: ");
|
fprintf (file, " vmaddr: ");
|
fprintf_vma (file, seg->vmaddr);
|
fprintf_vma (file, seg->vmaddr);
|
fprintf (file, " vmsize: ");
|
fprintf (file, " vmsize: ");
|
Line 3527... |
Line 3698... |
fprintf (file, " endoff: ");
|
fprintf (file, " endoff: ");
|
fprintf_vma (file, (bfd_vma)(seg->fileoff + seg->filesize));
|
fprintf_vma (file, (bfd_vma)(seg->fileoff + seg->filesize));
|
fprintf (file, "\n");
|
fprintf (file, "\n");
|
fprintf (file, " nsects: %lu ", seg->nsects);
|
fprintf (file, " nsects: %lu ", seg->nsects);
|
fprintf (file, " flags: %lx\n", seg->flags);
|
fprintf (file, " flags: %lx\n", seg->flags);
|
for (i = 0; i < seg->nsects; i++)
|
for (sec = seg->sect_head; sec != NULL; sec = sec->next)
|
bfd_mach_o_print_section (abfd, &seg->sections[i], file);
|
bfd_mach_o_print_section (abfd, sec, file);
|
}
|
}
|
|
|
static void
|
static void
|
bfd_mach_o_print_dysymtab (bfd *abfd ATTRIBUTE_UNUSED,
|
bfd_mach_o_print_dysymtab (bfd *abfd ATTRIBUTE_UNUSED,
|
bfd_mach_o_load_command *cmd, FILE *file)
|
bfd_mach_o_load_command *cmd, FILE *file)
|
Line 3754... |
Line 3925... |
fputc ('\n', file);
|
fputc ('\n', file);
|
|
|
for (i = 0; i < mdata->header.ncmds; i++)
|
for (i = 0; i < mdata->header.ncmds; i++)
|
{
|
{
|
bfd_mach_o_load_command *cmd = &mdata->commands[i];
|
bfd_mach_o_load_command *cmd = &mdata->commands[i];
|
|
const char *cmd_name;
|
|
|
|
cmd_name = bfd_mach_o_get_name_or_null
|
|
(bfd_mach_o_load_command_name, cmd->type);
|
|
fprintf (file, "Load command ");
|
|
if (cmd_name == NULL)
|
|
fprintf (file, "0x%02x:", cmd->type);
|
|
else
|
|
fprintf (file, "%s:", cmd_name);
|
|
|
fprintf (file, "Load command %s:",
|
|
bfd_mach_o_get_name (bfd_mach_o_load_command_name, cmd->type));
|
|
switch (cmd->type)
|
switch (cmd->type)
|
{
|
{
|
case BFD_MACH_O_LC_SEGMENT:
|
case BFD_MACH_O_LC_SEGMENT:
|
case BFD_MACH_O_LC_SEGMENT_64:
|
case BFD_MACH_O_LC_SEGMENT_64:
|
bfd_mach_o_print_segment (abfd, cmd, file);
|
bfd_mach_o_print_segment (abfd, cmd, file);
|
Line 3814... |
Line 3992... |
fprintf (file, "\n");
|
fprintf (file, "\n");
|
bfd_mach_o_print_dysymtab (abfd, cmd, file);
|
bfd_mach_o_print_dysymtab (abfd, cmd, file);
|
break;
|
break;
|
case BFD_MACH_O_LC_CODE_SIGNATURE:
|
case BFD_MACH_O_LC_CODE_SIGNATURE:
|
case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
|
case BFD_MACH_O_LC_SEGMENT_SPLIT_INFO:
|
|
case BFD_MACH_O_LC_FUNCTION_STARTS:
|
{
|
{
|
bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
|
bfd_mach_o_linkedit_command *linkedit = &cmd->command.linkedit;
|
fprintf
|
fprintf
|
(file, "\n"
|
(file, "\n"
|
" dataoff: 0x%08lx datasize: 0x%08lx (endoff: 0x%08lx)\n",
|
" dataoff: 0x%08lx datasize: 0x%08lx (endoff: 0x%08lx)\n",
|
Line 3868... |
Line 4047... |
}
|
}
|
case BFD_MACH_O_LC_DYLD_INFO:
|
case BFD_MACH_O_LC_DYLD_INFO:
|
fprintf (file, "\n");
|
fprintf (file, "\n");
|
bfd_mach_o_print_dyld_info (abfd, cmd, file);
|
bfd_mach_o_print_dyld_info (abfd, cmd, file);
|
break;
|
break;
|
|
case BFD_MACH_O_LC_VERSION_MIN_MACOSX:
|
|
case BFD_MACH_O_LC_VERSION_MIN_IPHONEOS:
|
|
{
|
|
bfd_mach_o_version_min_command *ver = &cmd->command.version_min;
|
|
|
|
fprintf (file, " %u.%u.%u\n", ver->rel, ver->maj, ver->min);
|
|
}
|
|
break;
|
default:
|
default:
|
fprintf (file, "\n");
|
fprintf (file, "\n");
|
|
fprintf (file, " offset: 0x%08lx\n", (unsigned long)cmd->offset);
|
|
fprintf (file, " size: 0x%08lx\n", (unsigned long)cmd->len);
|
break;
|
break;
|
}
|
}
|
fputc ('\n', file);
|
fputc ('\n', file);
|
}
|
}
|
|
|