2011-08-08 Tristan Gingold <gingold@adacore.com>
* mach-o.h (BFD_MACH_O_SEGNAME_SIZE): New macro. (BFD_MACH_O_SECTNAME_SIZE): Ditto. (bfd_mach_o_section): Use them. Add next field. (bfd_mach_o_segment_command): Replace sections array by sect_head and sect_tail. (bfd_mach_o_get_mach_o_section): New macro. (bfd_mach_o_lookup_section): Remove. (bfd_mach_o_new_section_hook): New function. * mach-o.c (bfd_mach_o_normalize_section_name): Use strncmp instead of strcmp. (bfd_mach_o_convert_section_name_to_bfd): Replaces section parameter with segname and sectname parameters. Adjust. (bfd_mach_o_append_section_to_segment): New function. Use a linked list for Mach-O sections. (bfd_mach_o_write_segment_32): Adjust. (bfd_mach_o_write_segment_64): Ditto. (bfd_mach_o_build_commands): Fix comment. Adjust. (bfd_mach_o_flatten_sections): Adjust. (bfd_mach_o_print_section_map): Adjust. (bfd_mach_o_set_section_flags_from_bfd): Ditto. (bfd_mach_o_new_section_hook): New function. (bfd_mach_o_init_section_from_mach_o): Ditto. (bfd_mach_o_read_section_32): Remove section parameter. Return a section instead. (bfd_mach_o_read_section_64): Ditto. (bfd_mach_o_read_section): Ditto. (bfd_mach_o_make_bfd_section): Adjust. (bfd_mach_o_read_segment): Adjust for new profile of bfd_mach_o_read_section. (bfd_mach_o_lookup_section): Remove. * mach-o-target.c (bfd_mach_o_new_section_hook): Remove.
This commit is contained in:
parent
edbdea0ed7
commit
f1bde64c90
@ -1,3 +1,37 @@
|
||||
2011-08-08 Tristan Gingold <gingold@adacore.com>
|
||||
|
||||
* mach-o.h (BFD_MACH_O_SEGNAME_SIZE): New macro.
|
||||
(BFD_MACH_O_SECTNAME_SIZE): Ditto.
|
||||
(bfd_mach_o_section): Use them. Add next field.
|
||||
(bfd_mach_o_segment_command): Replace sections array by
|
||||
sect_head and sect_tail.
|
||||
(bfd_mach_o_get_mach_o_section): New macro.
|
||||
(bfd_mach_o_lookup_section): Remove.
|
||||
(bfd_mach_o_new_section_hook): New function.
|
||||
* mach-o.c (bfd_mach_o_normalize_section_name): Use strncmp
|
||||
instead of strcmp.
|
||||
(bfd_mach_o_convert_section_name_to_bfd): Replaces section
|
||||
parameter with segname and sectname parameters. Adjust.
|
||||
(bfd_mach_o_append_section_to_segment): New function. Use a
|
||||
linked list for Mach-O sections.
|
||||
(bfd_mach_o_write_segment_32): Adjust.
|
||||
(bfd_mach_o_write_segment_64): Ditto.
|
||||
(bfd_mach_o_build_commands): Fix comment. Adjust.
|
||||
(bfd_mach_o_flatten_sections): Adjust.
|
||||
(bfd_mach_o_print_section_map): Adjust.
|
||||
(bfd_mach_o_set_section_flags_from_bfd): Ditto.
|
||||
(bfd_mach_o_new_section_hook): New function.
|
||||
(bfd_mach_o_init_section_from_mach_o): Ditto.
|
||||
(bfd_mach_o_read_section_32): Remove section parameter.
|
||||
Return a section instead.
|
||||
(bfd_mach_o_read_section_64): Ditto.
|
||||
(bfd_mach_o_read_section): Ditto.
|
||||
(bfd_mach_o_make_bfd_section): Adjust.
|
||||
(bfd_mach_o_read_segment): Adjust for new profile of
|
||||
bfd_mach_o_read_section.
|
||||
(bfd_mach_o_lookup_section): Remove.
|
||||
* mach-o-target.c (bfd_mach_o_new_section_hook): Remove.
|
||||
|
||||
2011-08-08 Tristan Gingold <gingold@adacore.com>
|
||||
|
||||
* mach-o.h (bfd_mach_o_version_min_command): New structure.
|
||||
|
@ -27,7 +27,6 @@
|
||||
|
||||
#define bfd_mach_o_close_and_cleanup _bfd_generic_close_and_cleanup
|
||||
#define bfd_mach_o_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
|
||||
#define bfd_mach_o_new_section_hook _bfd_generic_new_section_hook
|
||||
#define bfd_mach_o_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
|
||||
#define bfd_mach_o_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
|
||||
#define bfd_mach_o_bfd_is_local_label_name bfd_generic_is_local_label_name
|
||||
|
365
bfd/mach-o.c
365
bfd/mach-o.c
@ -159,13 +159,14 @@ bfd_mach_o_normalize_section_name (const char *segname, const char *sectname,
|
||||
|
||||
for (seg = segsec_names_xlat; seg->segname; seg++)
|
||||
{
|
||||
if (strcmp (seg->segname, segname) == 0)
|
||||
if (strncmp (seg->segname, segname, BFD_MACH_O_SEGNAME_SIZE) == 0)
|
||||
{
|
||||
const struct mach_o_section_name_xlat *sec;
|
||||
|
||||
for (sec = seg->sections; sec->mach_o_name; sec++)
|
||||
{
|
||||
if (strcmp (sec->mach_o_name, sectname) == 0)
|
||||
if (strncmp (sec->mach_o_name, sectname,
|
||||
BFD_MACH_O_SECTNAME_SIZE) == 0)
|
||||
{
|
||||
*name = sec->bfd_name;
|
||||
*flags = sec->flags;
|
||||
@ -178,27 +179,26 @@ bfd_mach_o_normalize_section_name (const char *segname, const char *sectname,
|
||||
}
|
||||
|
||||
static void
|
||||
bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, bfd_mach_o_section *section,
|
||||
const char **name, flagword *flags)
|
||||
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 (section->segname, section->sectname,
|
||||
name, flags);
|
||||
bfd_mach_o_normalize_section_name (segname, sectname, name, flags);
|
||||
|
||||
/* Return now if found. */
|
||||
if (*name)
|
||||
return;
|
||||
|
||||
len = strlen (section->segname) + 1
|
||||
+ strlen (section->sectname) + 1;
|
||||
len = strlen (segname) + 1 + strlen (sectname) + 1;
|
||||
|
||||
/* Put "LC_SEGMENT." prefix if the segment name is weird (ie doesn't start
|
||||
with an underscore. */
|
||||
if (section->segname[0] != '_')
|
||||
if (segname[0] != '_')
|
||||
{
|
||||
static const char seg_pfx[] = "LC_SEGMENT.";
|
||||
|
||||
@ -209,7 +209,7 @@ bfd_mach_o_convert_section_name_to_bfd (bfd *abfd, bfd_mach_o_section *section,
|
||||
res = bfd_alloc (abfd, len);
|
||||
if (res == NULL)
|
||||
return;
|
||||
snprintf (res, len, "%s%s.%s", pfx, section->segname, section->sectname);
|
||||
snprintf (res, len, "%s%s.%s", pfx, segname, sectname);
|
||||
*name = res;
|
||||
*flags = SEC_NO_FLAGS;
|
||||
}
|
||||
@ -1000,12 +1000,12 @@ bfd_mach_o_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
|
||||
{
|
||||
struct mach_o_segment_command_32_external raw;
|
||||
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);
|
||||
|
||||
for (i = 0; i < seg->nsects; i++)
|
||||
if (!bfd_mach_o_write_relocs (abfd, &seg->sections[i]))
|
||||
for (sec = seg->sect_head; sec != NULL; sec = sec->next)
|
||||
if (!bfd_mach_o_write_relocs (abfd, sec))
|
||||
return -1;
|
||||
|
||||
memcpy (raw.segname, seg->segname, 16);
|
||||
@ -1022,8 +1022,8 @@ bfd_mach_o_write_segment_32 (bfd *abfd, bfd_mach_o_load_command *command)
|
||||
|| bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < seg->nsects; i++)
|
||||
if (bfd_mach_o_write_section_32 (abfd, &seg->sections[i]))
|
||||
for (sec = seg->sect_head; sec != NULL; sec = sec->next)
|
||||
if (bfd_mach_o_write_section_32 (abfd, sec))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
@ -1034,12 +1034,12 @@ bfd_mach_o_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
|
||||
{
|
||||
struct mach_o_segment_command_64_external raw;
|
||||
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);
|
||||
|
||||
for (i = 0; i < seg->nsects; i++)
|
||||
if (!bfd_mach_o_write_relocs (abfd, &seg->sections[i]))
|
||||
for (sec = seg->sect_head; sec != NULL; sec = sec->next)
|
||||
if (!bfd_mach_o_write_relocs (abfd, sec))
|
||||
return -1;
|
||||
|
||||
memcpy (raw.segname, seg->segname, 16);
|
||||
@ -1056,8 +1056,8 @@ bfd_mach_o_write_segment_64 (bfd *abfd, bfd_mach_o_load_command *command)
|
||||
|| bfd_bwrite (&raw, sizeof (raw), abfd) != sizeof (raw))
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < seg->nsects; i++)
|
||||
if (bfd_mach_o_write_section_64 (abfd, &seg->sections[i]))
|
||||
for (sec = seg->sect_head; sec != NULL; sec = sec->next)
|
||||
if (bfd_mach_o_write_section_64 (abfd, sec))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
@ -1299,6 +1299,40 @@ bfd_mach_o_write_contents (bfd *abfd)
|
||||
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. */
|
||||
|
||||
bfd_boolean
|
||||
@ -1307,7 +1341,6 @@ bfd_mach_o_build_commands (bfd *abfd)
|
||||
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
||||
unsigned int wide = mach_o_wide_p (&mdata->header);
|
||||
bfd_mach_o_segment_command *seg;
|
||||
bfd_mach_o_section *sections;
|
||||
asection *sec;
|
||||
bfd_mach_o_load_command *cmd;
|
||||
bfd_mach_o_load_command *symtab_cmd;
|
||||
@ -1317,7 +1350,8 @@ bfd_mach_o_build_commands (bfd *abfd)
|
||||
if (mdata->header.ncmds)
|
||||
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->commands = bfd_alloc (abfd, mdata->header.ncmds
|
||||
* sizeof (bfd_mach_o_load_command));
|
||||
@ -1327,10 +1361,6 @@ bfd_mach_o_build_commands (bfd *abfd)
|
||||
seg = &cmd->command.segment;
|
||||
|
||||
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. */
|
||||
if (wide)
|
||||
@ -1376,30 +1406,31 @@ bfd_mach_o_build_commands (bfd *abfd)
|
||||
target_index = 0;
|
||||
for (sec = abfd->sections; sec; sec = sec->next)
|
||||
{
|
||||
sections->bfdsection = sec;
|
||||
bfd_mach_o_convert_section_name_to_mach_o (abfd, sec, sections);
|
||||
sections->addr = bfd_get_section_vma (abfd, sec);
|
||||
sections->size = bfd_get_section_size (sec);
|
||||
sections->align = bfd_get_section_alignment (abfd, sec);
|
||||
bfd_mach_o_section *msect = bfd_mach_o_get_mach_o_section (sec);
|
||||
|
||||
if (sections->size != 0)
|
||||
bfd_mach_o_append_section_to_segment (seg, sec);
|
||||
|
||||
if (msect->flags == 0)
|
||||
{
|
||||
mdata->filelen = FILE_ALIGN (mdata->filelen, sections->align);
|
||||
sections->offset = mdata->filelen;
|
||||
/* We suppose it hasn't been set. Convert from BFD flags. */
|
||||
bfd_mach_o_set_section_flags_from_bfd (abfd, sec);
|
||||
}
|
||||
msect->addr = bfd_get_section_vma (abfd, sec);
|
||||
msect->size = bfd_get_section_size (sec);
|
||||
msect->align = bfd_get_section_alignment (abfd, sec);
|
||||
|
||||
if (msect->size != 0)
|
||||
{
|
||||
mdata->filelen = FILE_ALIGN (mdata->filelen, msect->align);
|
||||
msect->offset = mdata->filelen;
|
||||
}
|
||||
else
|
||||
sections->offset = 0;
|
||||
sections->reloff = 0;
|
||||
sections->nreloc = 0;
|
||||
sections->reserved1 = 0;
|
||||
sections->reserved2 = 0;
|
||||
sections->reserved3 = 0;
|
||||
msect->offset = 0;
|
||||
|
||||
sec->filepos = sections->offset;
|
||||
sec->filepos = msect->offset;
|
||||
sec->target_index = ++target_index;
|
||||
|
||||
mdata->filelen += sections->size;
|
||||
sections++;
|
||||
mdata->filelen += msect->size;
|
||||
}
|
||||
seg->filesize = mdata->filelen - seg->fileoff;
|
||||
seg->vmsize = seg->filesize;
|
||||
@ -1524,17 +1555,51 @@ bfd_mach_o_read_header (bfd *abfd, bfd_mach_o_header *header)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static asection *
|
||||
bfd_mach_o_make_bfd_section (bfd *abfd, bfd_mach_o_section *section,
|
||||
unsigned long prot)
|
||||
bfd_boolean
|
||||
bfd_mach_o_new_section_hook (bfd *abfd, asection *sec)
|
||||
{
|
||||
asection *bfdsec;
|
||||
const char *sname;
|
||||
flagword flags;
|
||||
bfd_mach_o_section *s;
|
||||
|
||||
bfd_mach_o_convert_section_name_to_bfd (abfd, section, &sname, &flags);
|
||||
if (sname == NULL)
|
||||
return NULL;
|
||||
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)
|
||||
{
|
||||
flagword flags;
|
||||
bfd_mach_o_section *section;
|
||||
|
||||
flags = bfd_get_section_flags (abfd, sec);
|
||||
section = bfd_mach_o_get_mach_o_section (sec);
|
||||
|
||||
if (flags == SEC_NO_FLAGS)
|
||||
{
|
||||
@ -1568,39 +1633,57 @@ bfd_mach_o_make_bfd_section (bfd *abfd, bfd_mach_o_section *section,
|
||||
if (section->nreloc != 0)
|
||||
flags |= SEC_RELOC;
|
||||
|
||||
bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, flags);
|
||||
if (bfdsec == NULL)
|
||||
return NULL;
|
||||
bfd_set_section_flags (abfd, sec, flags);
|
||||
|
||||
bfdsec->vma = section->addr;
|
||||
bfdsec->lma = section->addr;
|
||||
bfdsec->size = section->size;
|
||||
bfdsec->filepos = section->offset;
|
||||
bfdsec->alignment_power = section->align;
|
||||
bfdsec->segment_mark = 0;
|
||||
bfdsec->reloc_count = section->nreloc;
|
||||
bfdsec->rel_filepos = section->reloff;
|
||||
|
||||
return bfdsec;
|
||||
sec->vma = section->addr;
|
||||
sec->lma = section->addr;
|
||||
sec->size = section->size;
|
||||
sec->filepos = section->offset;
|
||||
sec->alignment_power = section->align;
|
||||
sec->segment_mark = 0;
|
||||
sec->reloc_count = section->nreloc;
|
||||
sec->rel_filepos = section->reloff;
|
||||
}
|
||||
|
||||
static int
|
||||
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 asection *
|
||||
bfd_mach_o_read_section_32 (bfd *abfd,
|
||||
bfd_mach_o_section *section,
|
||||
unsigned int offset,
|
||||
unsigned long prot)
|
||||
{
|
||||
struct mach_o_section_32_external raw;
|
||||
asection *sec;
|
||||
bfd_mach_o_section *section;
|
||||
|
||||
if (bfd_seek (abfd, offset, SEEK_SET) != 0
|
||||
|| (bfd_bread (&raw, BFD_MACH_O_SECTION_SIZE, abfd)
|
||||
!= BFD_MACH_O_SECTION_SIZE))
|
||||
return -1;
|
||||
return NULL;
|
||||
|
||||
memcpy (section->sectname, raw.sectname, 16);
|
||||
section->sectname[16] = '\0';
|
||||
memcpy (section->segname, raw.segname, 16);
|
||||
section->segname[16] = '\0';
|
||||
sec = bfd_mach_o_make_bfd_section (abfd, raw.sectname, raw.segname);
|
||||
if (sec == NULL)
|
||||
return NULL;
|
||||
|
||||
section = bfd_mach_o_get_mach_o_section (sec);
|
||||
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_32 (abfd, raw.addr);
|
||||
section->size = bfd_h_get_32 (abfd, raw.size);
|
||||
section->offset = bfd_h_get_32 (abfd, raw.offset);
|
||||
@ -1611,31 +1694,35 @@ bfd_mach_o_read_section_32 (bfd *abfd,
|
||||
section->reserved1 = bfd_h_get_32 (abfd, raw.reserved1);
|
||||
section->reserved2 = bfd_h_get_32 (abfd, raw.reserved2);
|
||||
section->reserved3 = 0;
|
||||
section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
|
||||
|
||||
if (section->bfdsection == NULL)
|
||||
return -1;
|
||||
bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
|
||||
|
||||
return 0;
|
||||
return sec;
|
||||
}
|
||||
|
||||
static int
|
||||
static asection *
|
||||
bfd_mach_o_read_section_64 (bfd *abfd,
|
||||
bfd_mach_o_section *section,
|
||||
unsigned int offset,
|
||||
unsigned long prot)
|
||||
{
|
||||
struct mach_o_section_64_external raw;
|
||||
asection *sec;
|
||||
bfd_mach_o_section *section;
|
||||
|
||||
if (bfd_seek (abfd, offset, SEEK_SET) != 0
|
||||
|| (bfd_bread (&raw, BFD_MACH_O_SECTION_64_SIZE, abfd)
|
||||
!= BFD_MACH_O_SECTION_64_SIZE))
|
||||
return -1;
|
||||
return NULL;
|
||||
|
||||
memcpy (section->sectname, raw.sectname, 16);
|
||||
section->sectname[16] = '\0';
|
||||
memcpy (section->segname, raw.segname, 16);
|
||||
section->segname[16] = '\0';
|
||||
sec = bfd_mach_o_make_bfd_section (abfd, raw.sectname, raw.segname);
|
||||
if (sec == NULL)
|
||||
return NULL;
|
||||
|
||||
section = bfd_mach_o_get_mach_o_section (sec);
|
||||
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);
|
||||
@ -1646,25 +1733,22 @@ bfd_mach_o_read_section_64 (bfd *abfd,
|
||||
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);
|
||||
section->bfdsection = bfd_mach_o_make_bfd_section (abfd, section, prot);
|
||||
|
||||
if (section->bfdsection == NULL)
|
||||
return -1;
|
||||
bfd_mach_o_init_section_from_mach_o (abfd, sec, prot);
|
||||
|
||||
return 0;
|
||||
return sec;
|
||||
}
|
||||
|
||||
static int
|
||||
static asection *
|
||||
bfd_mach_o_read_section (bfd *abfd,
|
||||
bfd_mach_o_section *section,
|
||||
unsigned int offset,
|
||||
unsigned long prot,
|
||||
unsigned int 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
|
||||
return bfd_mach_o_read_section_32 (abfd, section, offset, prot);
|
||||
return bfd_mach_o_read_section_32 (abfd, offset, prot);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -2505,27 +2589,23 @@ bfd_mach_o_read_segment (bfd *abfd,
|
||||
seg->flags = bfd_h_get_32 (abfd, raw.flags);
|
||||
}
|
||||
|
||||
if (seg->nsects != 0)
|
||||
for (i = 0; i < seg->nsects; i++)
|
||||
{
|
||||
seg->sections = bfd_alloc (abfd, seg->nsects
|
||||
* sizeof (bfd_mach_o_section));
|
||||
if (seg->sections == NULL)
|
||||
return -1;
|
||||
bfd_vma segoff;
|
||||
asection *sec;
|
||||
|
||||
for (i = 0; i < seg->nsects; i++)
|
||||
{
|
||||
bfd_vma segoff;
|
||||
if (wide)
|
||||
segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
|
||||
+ (i * BFD_MACH_O_SECTION_64_SIZE);
|
||||
else
|
||||
segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
|
||||
+ (i * BFD_MACH_O_SECTION_SIZE);
|
||||
if (wide)
|
||||
segoff = command->offset + BFD_MACH_O_LC_SEGMENT_64_SIZE
|
||||
+ (i * BFD_MACH_O_SECTION_64_SIZE);
|
||||
else
|
||||
segoff = command->offset + BFD_MACH_O_LC_SEGMENT_SIZE
|
||||
+ (i * BFD_MACH_O_SECTION_SIZE);
|
||||
|
||||
if (bfd_mach_o_read_section
|
||||
(abfd, &seg->sections[i], segoff, seg->initprot, wide) != 0)
|
||||
return -1;
|
||||
}
|
||||
sec = bfd_mach_o_read_section (abfd, segoff, seg->initprot, wide);
|
||||
if (sec == NULL)
|
||||
return -1;
|
||||
|
||||
bfd_mach_o_append_section_to_segment (seg, sec);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -2652,7 +2732,7 @@ bfd_mach_o_flatten_sections (bfd *abfd)
|
||||
{
|
||||
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
||||
long csect = 0;
|
||||
unsigned long i, j;
|
||||
unsigned long i;
|
||||
|
||||
/* Count total number of sections. */
|
||||
mdata->nsects = 0;
|
||||
@ -2682,12 +2762,13 @@ bfd_mach_o_flatten_sections (bfd *abfd)
|
||||
|| mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT_64)
|
||||
{
|
||||
bfd_mach_o_segment_command *seg;
|
||||
bfd_mach_o_section *sec;
|
||||
|
||||
seg = &mdata->commands[i].command.segment;
|
||||
BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
|
||||
|
||||
for (j = 0; j < seg->nsects; j++)
|
||||
mdata->sections[csect++] = &seg->sections[j];
|
||||
for (sec = seg->sect_head; sec != NULL; sec = sec->next)
|
||||
mdata->sections[csect++] = sec;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3196,53 +3277,6 @@ bfd_mach_o_fat_extract (bfd *abfd,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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_load_command_type type,
|
||||
@ -3548,7 +3582,7 @@ static void
|
||||
bfd_mach_o_print_section_map (bfd *abfd, FILE *file)
|
||||
{
|
||||
bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
|
||||
unsigned int i, j;
|
||||
unsigned int i;
|
||||
unsigned int sec_nbr = 0;
|
||||
|
||||
fputs (_("Segments and Sections:\n"), file);
|
||||
@ -3557,6 +3591,7 @@ bfd_mach_o_print_section_map (bfd *abfd, FILE *file)
|
||||
for (i = 0; i < mdata->header.ncmds; i++)
|
||||
{
|
||||
bfd_mach_o_segment_command *seg;
|
||||
bfd_mach_o_section *sec;
|
||||
|
||||
if (mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT
|
||||
&& mdata->commands[i].type != BFD_MACH_O_LC_SEGMENT_64)
|
||||
@ -3573,9 +3608,9 @@ bfd_mach_o_print_section_map (bfd *abfd, FILE *file)
|
||||
fputc (seg->initprot & BFD_MACH_O_PROT_WRITE ? 'w' : '-', file);
|
||||
fputc (seg->initprot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-', file);
|
||||
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,
|
||||
sec->segname, sec->sectname);
|
||||
fprintf_vma (file, sec->addr);
|
||||
@ -3641,7 +3676,7 @@ bfd_mach_o_print_segment (bfd *abfd ATTRIBUTE_UNUSED,
|
||||
bfd_mach_o_load_command *cmd, FILE *file)
|
||||
{
|
||||
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, " vmaddr: ");
|
||||
@ -3658,8 +3693,8 @@ bfd_mach_o_print_segment (bfd *abfd ATTRIBUTE_UNUSED,
|
||||
fprintf (file, "\n");
|
||||
fprintf (file, " nsects: %lu ", seg->nsects);
|
||||
fprintf (file, " flags: %lx\n", seg->flags);
|
||||
for (i = 0; i < seg->nsects; i++)
|
||||
bfd_mach_o_print_section (abfd, &seg->sections[i], file);
|
||||
for (sec = seg->sect_head; sec != NULL; sec = sec->next)
|
||||
bfd_mach_o_print_section (abfd, sec, file);
|
||||
}
|
||||
|
||||
static void
|
||||
|
21
bfd/mach-o.h
21
bfd/mach-o.h
@ -41,11 +41,14 @@ typedef struct bfd_mach_o_header
|
||||
}
|
||||
bfd_mach_o_header;
|
||||
|
||||
#define BFD_MACH_O_SEGNAME_SIZE 16
|
||||
#define BFD_MACH_O_SECTNAME_SIZE 16
|
||||
|
||||
typedef struct bfd_mach_o_section
|
||||
{
|
||||
/* Fields present in the file. */
|
||||
char sectname[16 + 1];
|
||||
char segname[16 + 1];
|
||||
char sectname[BFD_MACH_O_SECTNAME_SIZE + 1]; /* Always NUL padded. */
|
||||
char segname[BFD_MACH_O_SEGNAME_SIZE + 1];
|
||||
bfd_vma addr;
|
||||
bfd_vma size;
|
||||
bfd_vma offset;
|
||||
@ -59,6 +62,9 @@ typedef struct bfd_mach_o_section
|
||||
|
||||
/* Corresponding bfd section. */
|
||||
asection *bfdsection;
|
||||
|
||||
/* Simply linked list. */
|
||||
struct bfd_mach_o_section *next;
|
||||
}
|
||||
bfd_mach_o_section;
|
||||
|
||||
@ -73,7 +79,10 @@ typedef struct bfd_mach_o_segment_command
|
||||
unsigned long initprot; /* Initial protection. */
|
||||
unsigned long nsects;
|
||||
unsigned long flags;
|
||||
bfd_mach_o_section *sections;
|
||||
|
||||
/* Linked list of sections. */
|
||||
bfd_mach_o_section *sect_head;
|
||||
bfd_mach_o_section *sect_tail;
|
||||
}
|
||||
bfd_mach_o_segment_command;
|
||||
|
||||
@ -525,6 +534,10 @@ bfd_mach_o_backend_data;
|
||||
#define bfd_mach_o_get_backend_data(abfd) \
|
||||
((bfd_mach_o_backend_data*)(abfd)->xvec->backend_data)
|
||||
|
||||
/* Get the Mach-O header for section SEC. */
|
||||
#define bfd_mach_o_get_mach_o_section(sec) \
|
||||
((bfd_mach_o_section *)(sec)->used_by_bfd)
|
||||
|
||||
bfd_boolean bfd_mach_o_valid (bfd *);
|
||||
int bfd_mach_o_read_dysymtab_symbol (bfd *, bfd_mach_o_dysymtab_command *, bfd_mach_o_symtab_command *, bfd_mach_o_asymbol *, unsigned long);
|
||||
int bfd_mach_o_scan_start_address (bfd *);
|
||||
@ -536,8 +549,8 @@ const bfd_target *bfd_mach_o_archive_p (bfd *);
|
||||
bfd *bfd_mach_o_openr_next_archived_file (bfd *, bfd *);
|
||||
bfd_boolean bfd_mach_o_set_arch_mach (bfd *, enum bfd_architecture,
|
||||
unsigned long);
|
||||
int bfd_mach_o_lookup_section (bfd *, asection *, bfd_mach_o_load_command **, bfd_mach_o_section **);
|
||||
int bfd_mach_o_lookup_command (bfd *, bfd_mach_o_load_command_type, bfd_mach_o_load_command **);
|
||||
bfd_boolean bfd_mach_o_new_section_hook (bfd *, asection *);
|
||||
bfd_boolean bfd_mach_o_write_contents (bfd *);
|
||||
bfd_boolean bfd_mach_o_bfd_copy_private_symbol_data (bfd *, asymbol *,
|
||||
bfd *, asymbol *);
|
||||
|
Loading…
Reference in New Issue
Block a user