mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-08-02 02:35:00 +08:00
Mach-O: add objdump -P function_starts to display function starts.
bfd/ * mach-o.h (bfd_mach_o_get_base_address): New prototype. * mach-o.c (bfd_mach_o_write_symtab) (bfd_mach_o_write_contents) (bfd_mach_o_set_section_flags_from_bfd) (bfd_mach_o_build_seg_command): Fix indentation. (bfd_mach_o_get_base_address): New function. binutils/ * od-macho.c (OPT_FUNCTION_STARTS): New macro. (options): Add entry for function_starts. (mach_o_help): Ditto. (disp_segment_prot): New function. (dump_section_map): Call disp_segment_prot. (dump_function_starts): New function. (dump_obj_compact_unwind): Fix ouput indentation. (dump_exe_compact_unwind): Fix ouput indentation. (mach_o_dump): Handle function_starts.
This commit is contained in:
@ -1,3 +1,15 @@
|
||||
2014-03-27 Tristan Gingold <gingold@adacore.com>
|
||||
|
||||
* od-macho.c (OPT_FUNCTION_STARTS): New macro.
|
||||
(options): Add entry for function_starts.
|
||||
(mach_o_help): Ditto.
|
||||
(disp_segment_prot): New function.
|
||||
(dump_section_map): Call disp_segment_prot.
|
||||
(dump_function_starts): New function.
|
||||
(dump_obj_compact_unwind): Fix ouput indentation.
|
||||
(dump_exe_compact_unwind): Fix ouput indentation.
|
||||
(mach_o_dump): Handle function_starts.
|
||||
|
||||
2014-03-26 Tristan Gingold <gingold@adacore.com>
|
||||
|
||||
* od-macho.c (bfd_mach_o_cpu_name): Add BFD_MACH_O_CPU_TYPE_ARM64.
|
||||
|
@ -42,6 +42,7 @@
|
||||
#define OPT_CODESIGN 5
|
||||
#define OPT_SEG_SPLIT_INFO 6
|
||||
#define OPT_COMPACT_UNWIND 7
|
||||
#define OPT_FUNCTION_STARTS 8
|
||||
|
||||
/* List of actions. */
|
||||
static struct objdump_private_option options[] =
|
||||
@ -54,6 +55,7 @@ static struct objdump_private_option options[] =
|
||||
{ "codesign", 0 },
|
||||
{ "seg_split_info", 0 },
|
||||
{ "compact_unwind", 0 },
|
||||
{ "function_starts", 0 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
@ -64,14 +66,15 @@ mach_o_help (FILE *stream)
|
||||
{
|
||||
fprintf (stream, _("\
|
||||
For Mach-O files:\n\
|
||||
header Display the file header\n\
|
||||
section Display the segments and sections commands\n\
|
||||
map Display the section map\n\
|
||||
load Display the load commands\n\
|
||||
dysymtab Display the dynamic symbol table\n\
|
||||
codesign Display code signature\n\
|
||||
seg_split_info Display segment split info\n\
|
||||
compact_unwind Display compact unwinding info\n\
|
||||
header Display the file header\n\
|
||||
section Display the segments and sections commands\n\
|
||||
map Display the section map\n\
|
||||
load Display the load commands\n\
|
||||
dysymtab Display the dynamic symbol table\n\
|
||||
codesign Display code signature\n\
|
||||
seg_split_info Display segment split info\n\
|
||||
compact_unwind Display compact unwinding info\n\
|
||||
function_starts Display start address of functions\n\
|
||||
"));
|
||||
}
|
||||
|
||||
@ -283,6 +286,14 @@ dump_header (bfd *abfd)
|
||||
printf (_(" reserved : %08x\n"), h->reserved);
|
||||
}
|
||||
|
||||
static void
|
||||
disp_segment_prot (unsigned int prot)
|
||||
{
|
||||
putchar (prot & BFD_MACH_O_PROT_READ ? 'r' : '-');
|
||||
putchar (prot & BFD_MACH_O_PROT_WRITE ? 'w' : '-');
|
||||
putchar (prot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-');
|
||||
}
|
||||
|
||||
static void
|
||||
dump_section_map (bfd *abfd)
|
||||
{
|
||||
@ -309,9 +320,7 @@ dump_section_map (bfd *abfd)
|
||||
putchar ('-');
|
||||
printf_vma (seg->vmaddr + seg->vmsize - 1);
|
||||
putchar (' ');
|
||||
putchar (seg->initprot & BFD_MACH_O_PROT_READ ? 'r' : '-');
|
||||
putchar (seg->initprot & BFD_MACH_O_PROT_WRITE ? 'w' : '-');
|
||||
putchar (seg->initprot & BFD_MACH_O_PROT_EXECUTE ? 'x' : '-');
|
||||
disp_segment_prot (seg->initprot);
|
||||
printf ("]\n");
|
||||
|
||||
for (sec = seg->sect_head; sec != NULL; sec = sec->next)
|
||||
@ -393,8 +402,13 @@ dump_segment (bfd *abfd ATTRIBUTE_UNUSED, bfd_mach_o_load_command *cmd)
|
||||
printf (" endoff: ");
|
||||
printf_vma ((bfd_vma)(seg->fileoff + seg->filesize));
|
||||
printf ("\n");
|
||||
printf (" nsects: %lu ", seg->nsects);
|
||||
printf (" flags: %lx\n", seg->flags);
|
||||
printf (" nsects: %lu", seg->nsects);
|
||||
printf (" flags: %lx", seg->flags);
|
||||
printf (" initprot: ");
|
||||
disp_segment_prot (seg->initprot);
|
||||
printf (" maxprot: ");
|
||||
disp_segment_prot (seg->maxprot);
|
||||
printf ("\n");
|
||||
for (sec = seg->sect_head; sec != NULL; sec = sec->next)
|
||||
dump_section_header (abfd, sec);
|
||||
}
|
||||
@ -911,6 +925,55 @@ dump_segment_split_info (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
|
||||
free (buf);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_function_starts (bfd *abfd, bfd_mach_o_linkedit_command *cmd)
|
||||
{
|
||||
unsigned char *buf = xmalloc (cmd->datasize);
|
||||
unsigned char *end_buf = buf + cmd->datasize;
|
||||
unsigned char *p;
|
||||
bfd_vma addr;
|
||||
|
||||
if (bfd_seek (abfd, cmd->dataoff, SEEK_SET) != 0
|
||||
|| bfd_bread (buf, cmd->datasize, abfd) != cmd->datasize)
|
||||
{
|
||||
non_fatal (_("cannot read function starts"));
|
||||
free (buf);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Function starts are delta encoded, starting from the base address. */
|
||||
addr = bfd_mach_o_get_base_address (abfd);
|
||||
|
||||
for (p = buf; ;)
|
||||
{
|
||||
bfd_vma delta = 0;
|
||||
unsigned int shift = 0;
|
||||
|
||||
if (*p == 0 || p == end_buf)
|
||||
break;
|
||||
while (1)
|
||||
{
|
||||
unsigned char b = *p++;
|
||||
|
||||
delta |= (b & 0x7f) << shift;
|
||||
if ((b & 0x80) == 0)
|
||||
break;
|
||||
if (p == end_buf)
|
||||
{
|
||||
fputs (" [truncated]\n", stdout);
|
||||
break;
|
||||
}
|
||||
shift += 7;
|
||||
}
|
||||
|
||||
addr += delta;
|
||||
fputs (" ", stdout);
|
||||
bfd_printf_vma (abfd, addr);
|
||||
putchar ('\n');
|
||||
}
|
||||
free (buf);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
|
||||
bfd_boolean verbose)
|
||||
@ -1005,6 +1068,8 @@ dump_load_command (bfd *abfd, bfd_mach_o_load_command *cmd,
|
||||
dump_code_signature (abfd, linkedit);
|
||||
else if (verbose && cmd->type == BFD_MACH_O_LC_SEGMENT_SPLIT_INFO)
|
||||
dump_segment_split_info (abfd, linkedit);
|
||||
else if (verbose && cmd->type == BFD_MACH_O_LC_FUNCTION_STARTS)
|
||||
dump_function_starts (abfd, linkedit);
|
||||
break;
|
||||
}
|
||||
case BFD_MACH_O_LC_SUB_FRAMEWORK:
|
||||
@ -1260,7 +1325,7 @@ dump_obj_compact_unwind (bfd *abfd,
|
||||
int is_64 = mdata->header.version == 2;
|
||||
const unsigned char *p;
|
||||
|
||||
printf (" compact unwind info:\n");
|
||||
printf ("Compact unwind info:\n");
|
||||
printf (" start length personality lsda\n");
|
||||
|
||||
if (is_64)
|
||||
@ -1309,7 +1374,7 @@ dump_exe_compact_unwind (bfd *abfd,
|
||||
unsigned int i;
|
||||
|
||||
/* The header. */
|
||||
printf (" compact unwind info:\n");
|
||||
printf ("Compact unwind info:\n");
|
||||
|
||||
hdr = (struct mach_o_unwind_info_header *) content;
|
||||
if (size < sizeof (*hdr))
|
||||
@ -1544,6 +1609,8 @@ mach_o_dump (bfd *abfd)
|
||||
dump_load_commands (abfd, BFD_MACH_O_LC_CODE_SIGNATURE, 0);
|
||||
if (options[OPT_SEG_SPLIT_INFO].selected)
|
||||
dump_load_commands (abfd, BFD_MACH_O_LC_SEGMENT_SPLIT_INFO, 0);
|
||||
if (options[OPT_FUNCTION_STARTS].selected)
|
||||
dump_load_commands (abfd, BFD_MACH_O_LC_FUNCTION_STARTS, 0);
|
||||
if (options[OPT_COMPACT_UNWIND].selected)
|
||||
{
|
||||
dump_section_content (abfd, "__LD", "__compact_unwind",
|
||||
|
Reference in New Issue
Block a user