mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-23 03:29:47 +08:00
bfd:
* mach-o.c (bfd_mach_o_build_commands): Make the building of each command type independent.
This commit is contained in:
@ -1,3 +1,8 @@
|
|||||||
|
2012-01-11 Iain Sandoe <idsandoe@googlemail.com>
|
||||||
|
|
||||||
|
* mach-o.c (bfd_mach_o_build_commands): Make the building of each
|
||||||
|
command type independent.
|
||||||
|
|
||||||
2012-01-11 Alan Modra <amodra@gmail.com>
|
2012-01-11 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* elf64-ppc.c: Define more insns used in plt call stubs.
|
* elf64-ppc.c: Define more insns used in plt call stubs.
|
||||||
|
134
bfd/mach-o.c
134
bfd/mach-o.c
@ -2153,11 +2153,11 @@ 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 wide = mach_o_wide_p (&mdata->header);
|
||||||
bfd_mach_o_segment_command *seg = NULL;
|
int segcmd_idx = -1;
|
||||||
bfd_mach_o_load_command *cmd;
|
int symtab_idx = -1;
|
||||||
bfd_mach_o_load_command *symtab_cmd;
|
int dysymtab_idx = -1;
|
||||||
unsigned symcind;
|
unsigned long base_offset = 0;
|
||||||
|
|
||||||
/* Return now if commands are already present. */
|
/* Return now if commands are already present. */
|
||||||
if (mdata->header.ncmds)
|
if (mdata->header.ncmds)
|
||||||
@ -2187,31 +2187,48 @@ bfd_mach_o_build_commands (bfd *abfd)
|
|||||||
if (!bfd_mach_o_mangle_symbols (abfd))
|
if (!bfd_mach_o_mangle_symbols (abfd))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* It's valid to have a file with only absolute symbols... */
|
/* Very simple command set (only really applicable to MH_OBJECTs):
|
||||||
if (mdata->nsects > 0)
|
All the commands are optional - present only when there is suitable data.
|
||||||
{
|
(i.e. it is valid to have an empty file)
|
||||||
mdata->header.ncmds = 1;
|
|
||||||
symcind = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
symcind = 0;
|
|
||||||
|
|
||||||
/* It's OK to have a file with only section statements. */
|
|
||||||
if (bfd_get_symcount (abfd) > 0)
|
|
||||||
mdata->header.ncmds += 1;
|
|
||||||
|
|
||||||
/* Very simple version (only really applicable to MH_OBJECTs):
|
|
||||||
a command (segment) to contain all the sections,
|
a command (segment) to contain all the sections,
|
||||||
a command for the symbol table
|
command for the symbol table,
|
||||||
a n (optional) command for the dysymtab.
|
a command for the dysymtab.
|
||||||
|
|
||||||
??? maybe we should assert that this is an MH_OBJECT? */
|
??? maybe we should assert that this is an MH_OBJECT? */
|
||||||
|
|
||||||
if (bfd_mach_o_should_emit_dysymtab ()
|
if (mdata->nsects > 0)
|
||||||
&& bfd_get_symcount (abfd) > 0)
|
{
|
||||||
mdata->header.ncmds += 1;
|
segcmd_idx = 0;
|
||||||
|
mdata->header.ncmds = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* A bit weird, but looks like no content;
|
if (bfd_get_symcount (abfd) > 0)
|
||||||
|
{
|
||||||
|
mdata->header.ncmds++;
|
||||||
|
symtab_idx = segcmd_idx + 1; /* 0 if the seg command is absent. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME:
|
||||||
|
This is a rather crude test for whether we should build a dysymtab. */
|
||||||
|
if (bfd_mach_o_should_emit_dysymtab ()
|
||||||
|
&& bfd_get_symcount (abfd))
|
||||||
|
{
|
||||||
|
mdata->header.ncmds++;
|
||||||
|
/* If there should be a case where a dysymtab could be emitted without
|
||||||
|
a symtab (seems improbable), this would need amending. */
|
||||||
|
dysymtab_idx = symtab_idx + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wide)
|
||||||
|
base_offset = BFD_MACH_O_HEADER_64_SIZE;
|
||||||
|
else
|
||||||
|
base_offset = BFD_MACH_O_HEADER_SIZE;
|
||||||
|
|
||||||
|
/* Well, we must have a header, at least. */
|
||||||
|
mdata->filelen = base_offset;
|
||||||
|
|
||||||
|
/* A bit unusual, but no content is valid;
|
||||||
as -n empty.s -o empty.o */
|
as -n empty.s -o empty.o */
|
||||||
if (mdata->header.ncmds == 0)
|
if (mdata->header.ncmds == 0)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -2221,10 +2238,10 @@ bfd_mach_o_build_commands (bfd *abfd)
|
|||||||
if (mdata->commands == NULL)
|
if (mdata->commands == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (mdata->nsects > 0)
|
if (segcmd_idx >= 0)
|
||||||
{
|
{
|
||||||
cmd = &mdata->commands[0];
|
bfd_mach_o_load_command *cmd = &mdata->commands[segcmd_idx];
|
||||||
seg = &cmd->command.segment;
|
bfd_mach_o_segment_command *seg = &cmd->command.segment;
|
||||||
|
|
||||||
/* Count the segctions in the special blank segment used for MH_OBJECT. */
|
/* Count the segctions in the special blank segment used for MH_OBJECT. */
|
||||||
seg->nsects = bfd_mach_o_count_sections_for_seg (NULL, mdata);
|
seg->nsects = bfd_mach_o_count_sections_for_seg (NULL, mdata);
|
||||||
@ -2232,52 +2249,61 @@ bfd_mach_o_build_commands (bfd *abfd)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* Init segment command. */
|
/* Init segment command. */
|
||||||
|
cmd->offset = base_offset;
|
||||||
if (wide)
|
if (wide)
|
||||||
{
|
{
|
||||||
cmd->type = BFD_MACH_O_LC_SEGMENT_64;
|
cmd->type = BFD_MACH_O_LC_SEGMENT_64;
|
||||||
cmd->offset = BFD_MACH_O_HEADER_64_SIZE;
|
|
||||||
cmd->len = BFD_MACH_O_LC_SEGMENT_64_SIZE
|
cmd->len = BFD_MACH_O_LC_SEGMENT_64_SIZE
|
||||||
+ BFD_MACH_O_SECTION_64_SIZE * seg->nsects;
|
+ BFD_MACH_O_SECTION_64_SIZE * seg->nsects;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cmd->type = BFD_MACH_O_LC_SEGMENT;
|
cmd->type = BFD_MACH_O_LC_SEGMENT;
|
||||||
cmd->offset = BFD_MACH_O_HEADER_SIZE;
|
|
||||||
cmd->len = BFD_MACH_O_LC_SEGMENT_SIZE
|
cmd->len = BFD_MACH_O_LC_SEGMENT_SIZE
|
||||||
+ BFD_MACH_O_SECTION_SIZE * seg->nsects;
|
+ BFD_MACH_O_SECTION_SIZE * seg->nsects;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd->type_required = FALSE;
|
cmd->type_required = FALSE;
|
||||||
mdata->header.sizeofcmds = cmd->len;
|
mdata->header.sizeofcmds = cmd->len;
|
||||||
mdata->filelen = cmd->offset + cmd->len;
|
mdata->filelen += cmd->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bfd_get_symcount (abfd) > 0)
|
if (symtab_idx >= 0)
|
||||||
{
|
{
|
||||||
/* Init symtab command. */
|
/* Init symtab command. */
|
||||||
symtab_cmd = &mdata->commands[symcind];
|
bfd_mach_o_load_command *cmd = &mdata->commands[symtab_idx];
|
||||||
|
|
||||||
symtab_cmd->type = BFD_MACH_O_LC_SYMTAB;
|
cmd->type = BFD_MACH_O_LC_SYMTAB;
|
||||||
if (symcind > 0)
|
cmd->offset = base_offset;
|
||||||
symtab_cmd->offset = mdata->commands[0].offset
|
if (segcmd_idx >= 0)
|
||||||
+ mdata->commands[0].len;
|
cmd->offset += mdata->commands[segcmd_idx].len;
|
||||||
else
|
|
||||||
symtab_cmd->offset = 0;
|
cmd->len = sizeof (struct mach_o_symtab_command_external)
|
||||||
symtab_cmd->len = 6 * 4;
|
+ BFD_MACH_O_LC_SIZE;
|
||||||
symtab_cmd->type_required = FALSE;
|
cmd->type_required = FALSE;
|
||||||
|
mdata->header.sizeofcmds += cmd->len;
|
||||||
mdata->header.sizeofcmds += symtab_cmd->len;
|
mdata->filelen += cmd->len;
|
||||||
mdata->filelen += symtab_cmd->len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If required, setup symtab command. */
|
/* If required, setup symtab command, see comment above about the quality
|
||||||
if (bfd_mach_o_should_emit_dysymtab ()
|
of this test. */
|
||||||
&& bfd_get_symcount (abfd) > 0)
|
if (dysymtab_idx >= 0)
|
||||||
{
|
{
|
||||||
cmd = &mdata->commands[symcind+1];
|
bfd_mach_o_load_command *cmd = &mdata->commands[dysymtab_idx];
|
||||||
|
|
||||||
cmd->type = BFD_MACH_O_LC_DYSYMTAB;
|
cmd->type = BFD_MACH_O_LC_DYSYMTAB;
|
||||||
cmd->offset = symtab_cmd->offset + symtab_cmd->len;
|
if (symtab_idx >= 0)
|
||||||
|
cmd->offset = mdata->commands[symtab_idx].offset
|
||||||
|
+ mdata->commands[symtab_idx].len;
|
||||||
|
else if (segcmd_idx >= 0)
|
||||||
|
cmd->offset = mdata->commands[segcmd_idx].offset
|
||||||
|
+ mdata->commands[segcmd_idx].len;
|
||||||
|
else
|
||||||
|
cmd->offset = base_offset;
|
||||||
|
|
||||||
cmd->type_required = FALSE;
|
cmd->type_required = FALSE;
|
||||||
cmd->len = 18 * 4 + BFD_MACH_O_LC_SIZE;
|
cmd->len = sizeof (struct mach_o_dysymtab_command_external)
|
||||||
|
+ BFD_MACH_O_LC_SIZE;
|
||||||
|
|
||||||
mdata->header.sizeofcmds += cmd->len;
|
mdata->header.sizeofcmds += cmd->len;
|
||||||
mdata->filelen += cmd->len;
|
mdata->filelen += cmd->len;
|
||||||
@ -2285,15 +2311,15 @@ bfd_mach_o_build_commands (bfd *abfd)
|
|||||||
|
|
||||||
/* So, now we have sized the commands and the filelen set to that.
|
/* So, now we have sized the commands and the filelen set to that.
|
||||||
Now we can build the segment command and set the section file offsets. */
|
Now we can build the segment command and set the section file offsets. */
|
||||||
if (mdata->nsects > 0
|
if (segcmd_idx >= 0
|
||||||
&& ! bfd_mach_o_build_seg_command (NULL, mdata, seg))
|
&& ! bfd_mach_o_build_seg_command
|
||||||
|
(NULL, mdata, &mdata->commands[segcmd_idx].command.segment))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* If we're doing a dysymtab, cmd points to its load command. */
|
/* If we're doing a dysymtab, cmd points to its load command. */
|
||||||
if (bfd_mach_o_should_emit_dysymtab ()
|
if (dysymtab_idx >= 0
|
||||||
&& bfd_get_symcount (abfd) > 0
|
|
||||||
&& ! bfd_mach_o_build_dysymtab_command (abfd, mdata,
|
&& ! bfd_mach_o_build_dysymtab_command (abfd, mdata,
|
||||||
&mdata->commands[symcind+1]))
|
&mdata->commands[dysymtab_idx]))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* The symtab command is filled in when the symtab is written. */
|
/* The symtab command is filled in when the symtab is written. */
|
||||||
|
Reference in New Issue
Block a user