/* objdump.c -- dump information about an object file.
- Copyright (C) 1990-2019 Free Software Foundation, Inc.
+ Copyright (C) 1990-2020 Free Software Foundation, Inc.
This file is part of GNU Binutils.
struct objdump_disasm_info
{
bfd * abfd;
- asection * sec;
bfd_boolean require_sec;
arelent ** dynrelbuf;
long dynrelcount;
-w, --wide Format output for more than 80 columns\n\
-z, --disassemble-zeroes Do not skip blocks of zeroes when disassembling\n\
--start-address=ADDR Only process data whose address is >= ADDR\n\
- --stop-address=ADDR Only process data whose address is <= ADDR\n\
+ --stop-address=ADDR Only process data whose address is < ADDR\n\
--prefix-addresses Print complete address alongside disassembly\n\
--[no-]show-raw-insn Display hex alongside symbolic disassembly\n\
--insn-width=WIDTH Display WIDTH bytes on a single line for -d\n\
dump_section_header (bfd *abfd, asection *section, void *data)
{
char *comma = "";
- unsigned int opb = bfd_octets_per_byte (abfd);
+ unsigned int opb = bfd_octets_per_byte (abfd, section);
int longest_section_name = *((int *) data);
/* Ignore linker created section. See elfNN_ia64_object_p in
return;
printf ("%3d %-*s %08lx ", section->index, longest_section_name,
- sanitize_string (bfd_get_section_name (abfd, section)),
- (unsigned long) bfd_section_size (abfd, section) / opb);
- bfd_printf_vma (abfd, bfd_get_section_vma (abfd, section));
+ sanitize_string (bfd_section_name (section)),
+ (unsigned long) bfd_section_size (section) / opb);
+ bfd_printf_vma (abfd, bfd_section_vma (section));
printf (" ");
bfd_printf_vma (abfd, section->lma);
printf (" %08lx 2**%u", (unsigned long) section->filepos,
- bfd_get_section_alignment (abfd, section));
+ bfd_section_alignment (section));
if (! wide_output)
printf ("\n ");
printf (" ");
PF (SEC_COFF_NOREAD, "NOREAD");
}
else if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
- PF (SEC_ELF_PURECODE, "PURECODE");
+ {
+ PF (SEC_ELF_OCTETS, "OCTETS");
+ PF (SEC_ELF_PURECODE, "PURECODE");
+ }
PF (SEC_THREAD_LOCAL, "THREAD_LOCAL");
PF (SEC_GROUP, "GROUP");
if (bfd_get_arch (abfd) == bfd_arch_mep)
DATA which contains the string length of the longest section name. */
static void
-find_longest_section_name (bfd *abfd, asection *section, void *data)
+find_longest_section_name (bfd *abfd ATTRIBUTE_UNUSED,
+ asection *section, void *data)
{
int *longest_so_far = (int *) data;
const char *name;
if (! process_section_p (section))
return;
- name = bfd_get_section_name (abfd, section);
+ name = bfd_section_name (section);
len = (int) strlen (name);
if (len > *longest_so_far)
*longest_so_far = len;
return out_ptr - symbols;
}
+static const asection *compare_section;
+
/* Sort symbols into value order. */
static int
const char *bn;
size_t anl;
size_t bnl;
- bfd_boolean af;
- bfd_boolean bf;
+ bfd_boolean as, af, bs, bf;
flagword aflags;
flagword bflags;
else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
return -1;
- if (a->section > b->section)
- return 1;
- else if (a->section < b->section)
+ /* Prefer symbols from the section currently being disassembled.
+ Don't sort symbols from other sections by section, since there
+ isn't much reason to prefer one section over another otherwise.
+ See sym_ok comment for why we compare by section name. */
+ as = strcmp (compare_section->name, a->section->name) == 0;
+ bs = strcmp (compare_section->name, b->section->name) == 0;
+ if (as && !bs)
return -1;
+ if (!as && bs)
+ return 1;
an = bfd_asymbol_name (a);
bn = bfd_asymbol_name (b);
#define file_symbol(s, sn, snl) \
(((s)->flags & BSF_FILE) != 0 \
- || ((sn)[(snl) - 2] == '.' \
+ || ((snl) > 2 \
+ && (sn)[(snl) - 2] == '.' \
&& ((sn)[(snl) - 1] == 'o' \
|| (sn)[(snl) - 1] == 'a')))
if (! af && bf)
return -1;
- /* Try to sort global symbols before local symbols before function
- symbols before debugging symbols. */
+ /* Sort function and object symbols before global symbols before
+ local symbols before section symbols before debugging symbols. */
aflags = a->flags;
bflags = b->flags;
else
return -1;
}
+ if ((aflags & BSF_SECTION_SYM) != (bflags & BSF_SECTION_SYM))
+ {
+ if ((aflags & BSF_SECTION_SYM) != 0)
+ return 1;
+ else
+ return -1;
+ }
if ((aflags & BSF_FUNCTION) != (bflags & BSF_FUNCTION))
{
if ((aflags & BSF_FUNCTION) != 0)
else
return 1;
}
+ if ((aflags & BSF_OBJECT) != (bflags & BSF_OBJECT))
+ {
+ if ((aflags & BSF_OBJECT) != 0)
+ return -1;
+ else
+ return 1;
+ }
if ((aflags & BSF_LOCAL) != (bflags & BSF_LOCAL))
{
if ((aflags & BSF_LOCAL) != 0)
if ((sym->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0)
version_string = bfd_get_symbol_version_string (abfd, sym, &hidden);
- if (bfd_is_und_section (bfd_get_section (sym)))
+ if (bfd_is_und_section (bfd_asymbol_section (sym)))
hidden = TRUE;
name = sanitize_string (name);
debug info file, whilst the section we want is in a normal file.
So the section pointers will be different, but the section names
will be the same. */
- if (strcmp (bfd_section_name (abfd, sorted_syms[place]->section),
- bfd_section_name (abfd, sec)) != 0)
+ if (strcmp (bfd_section_name (sorted_syms[place]->section),
+ bfd_section_name (sec)) != 0)
return FALSE;
}
aux = (struct objdump_disasm_info *) inf->application_data;
abfd = aux->abfd;
- sec = aux->sec;
+ sec = inf->section;
opb = inf->octets_per_byte;
/* Perform a binary search looking for the closest symbol to the
/* The symbol we want is now in min, the low end of the range we
were searching. If there are several symbols with the same
- value, we want the first (non-section/non-debugging) one. */
+ value, we want the first one. */
thisplace = min;
while (thisplace > 0
&& (bfd_asymbol_value (sorted_syms[thisplace])
- == bfd_asymbol_value (sorted_syms[thisplace - 1]))
- && ((sorted_syms[thisplace - 1]->flags
- & (BSF_SECTION_SYM | BSF_DEBUGGING)) == 0)
- )
+ == bfd_asymbol_value (sorted_syms[thisplace - 1])))
--thisplace;
/* Prefer a symbol in the current section if we have multple symbols
Also give the target a chance to reject symbols. */
want_section = (aux->require_sec
|| ((abfd->flags & HAS_RELOC) != 0
- && vma >= bfd_get_section_vma (abfd, sec)
- && vma < (bfd_get_section_vma (abfd, sec)
- + bfd_section_size (abfd, sec) / opb)));
+ && vma >= bfd_section_vma (sec)
+ && vma < (bfd_section_vma (sec)
+ + bfd_section_size (sec) / opb)));
if (! sym_ok (want_section, abfd, thisplace, sec, inf))
{
bfd_vma secaddr;
(*inf->fprintf_func) (inf->stream, " <%s",
- sanitize_string (bfd_get_section_name (abfd, sec)));
- secaddr = bfd_get_section_vma (abfd, sec);
+ sanitize_string (bfd_section_name (sec)));
+ secaddr = bfd_section_vma (sec);
if (vma < secaddr)
{
(*inf->fprintf_func) (inf->stream, "-0x");
if (display_file_offsets)
inf->fprintf_func (inf->stream, _(" (File Offset: 0x%lx)"),
- (long int)(aux->sec->filepos + (vma - aux->sec->vma)));
+ (long int) (inf->section->filepos
+ + (vma - inf->section->vma)));
return;
}
/* Adjust the vma to the reloc. */
vma += bfd_asymbol_value (sym);
- if (bfd_is_und_section (bfd_get_section (sym)))
+ if (bfd_is_und_section (bfd_asymbol_section (sym)))
skip_find = TRUE;
}
if (!skip_find)
sym = find_symbol_for_address (vma, inf, NULL);
- objdump_print_addr_with_sym (aux->abfd, aux->sec, sym, vma, inf,
+ objdump_print_addr_with_sym (aux->abfd, inf->section, sym, vma, inf,
skip_zeroes);
}
SFILE sfile;
aux = (struct objdump_disasm_info *) inf->application_data;
- section = aux->sec;
+ section = inf->section;
sfile.alloc = 120;
sfile.buffer = (char *) xmalloc (sfile.alloc);
{
asection *sym_sec;
- sym_sec = bfd_get_section (*q->sym_ptr_ptr);
- sym_name = bfd_get_section_name (aux->abfd, sym_sec);
+ sym_sec = bfd_asymbol_section (*q->sym_ptr_ptr);
+ sym_name = bfd_section_name (sym_sec);
if (sym_name == NULL || *sym_name == '\0')
sym_name = "*unknown*";
printf ("%s", sanitize_string (sym_name));
if (! process_section_p (section))
return;
- datasize = bfd_get_section_size (section);
+ datasize = bfd_section_size (section);
if (datasize == 0)
return;
return;
}
- paux->sec = section;
pinfo->buffer = data;
pinfo->buffer_vma = section->vma;
pinfo->buffer_length = datasize;
pinfo->section = section;
+ /* Sort the symbols into value and section order. */
+ compare_section = section;
+ qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
+
/* Skip over the relocs belonging to addresses below the
start address. */
while (rel_pp < rel_ppend
else
{
#define is_valid_next_sym(SYM) \
- (strcmp (bfd_section_name (abfd, (SYM)->section), bfd_section_name (abfd, section)) == 0 \
+ (strcmp (bfd_section_name ((SYM)->section), bfd_section_name (section)) == 0 \
&& (bfd_asymbol_value (SYM) > bfd_asymbol_value (sym)) \
&& pinfo->symbol_is_valid (SYM, pinfo))
++sorted_symcount;
}
- /* Sort the symbols into section and symbol order. */
- qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
-
init_disassemble_info (&disasm_info, stdout, (fprintf_ftype) fprintf);
disasm_info.application_data = (void *) &aux;
disasm_info.arch = bfd_get_arch (abfd);
disasm_info.mach = bfd_get_mach (abfd);
disasm_info.disassembler_options = disassembler_options;
- disasm_info.octets_per_byte = bfd_octets_per_byte (abfd);
+ disasm_info.octets_per_byte = bfd_octets_per_byte (abfd, NULL);
disasm_info.skip_zeroes = DEFAULT_SKIP_ZEROES;
disasm_info.skip_zeroes_at_end = DEFAULT_SKIP_ZEROES_AT_END;
disasm_info.disassembler_needs_relocs = FALSE;
if (aux.dynrelbuf != NULL)
free (aux.dynrelbuf);
free (sorted_syms);
+ disassemble_free_target (&disasm_info);
}
\f
static bfd_boolean
section->filename = bfd_get_filename (abfd);
section->reloc_info = NULL;
section->num_relocs = 0;
- section->address = bfd_get_section_vma (abfd, sec);
+ section->address = bfd_section_vma (sec);
section->user_data = sec;
- section->size = bfd_get_section_size (sec);
+ section->size = bfd_section_size (sec);
/* PR 24360: On 32-bit hosts sizeof (size_t) < sizeof (bfd_size_type). */
alloced = amt = section->size + 1;
if (alloced != amt || alloced == 0)
return data;
}
+#if HAVE_LIBDEBUGINFOD
+/* Return a hex string represention of the build-id. */
+
+unsigned char *
+get_build_id (void * data)
+{
+ unsigned i;
+ char * build_id_str;
+ bfd * abfd = (bfd *) data;
+ const struct bfd_build_id * build_id;
+
+ build_id = abfd->build_id;
+ if (build_id == NULL)
+ return NULL;
+
+ build_id_str = malloc (build_id->size * 2 + 1);
+ if (build_id_str == NULL)
+ return NULL;
+
+ for (i = 0; i < build_id->size; i++)
+ sprintf (build_id_str + (i * 2), "%02x", build_id->data[i]);
+ build_id_str[build_id->size * 2] = '\0';
+
+ return (unsigned char *)build_id_str;
+}
+#endif /* HAVE_LIBDEBUGINFOD */
+
static void
dump_dwarf_section (bfd *abfd, asection *section,
void *arg ATTRIBUTE_UNUSED)
{
- const char *name = bfd_get_section_name (abfd, section);
+ const char *name = bfd_section_name (section);
const char *match;
int i;
return;
}
- eh_addr_size = bfd_arch_bits_per_address (abfd) / 8;
-
switch (bfd_get_arch (abfd))
{
- case bfd_arch_i386:
- switch (bfd_get_mach (abfd))
- {
- case bfd_mach_x86_64:
- case bfd_mach_x86_64_intel_syntax:
- case bfd_mach_x86_64_nacl:
- case bfd_mach_x64_32:
- case bfd_mach_x64_32_intel_syntax:
- case bfd_mach_x64_32_nacl:
- init_dwarf_regnames_x86_64 ();
- break;
-
- default:
- init_dwarf_regnames_i386 ();
- break;
- }
- break;
-
- case bfd_arch_iamcu:
- init_dwarf_regnames_iamcu ();
- break;
-
- case bfd_arch_aarch64:
- init_dwarf_regnames_aarch64();
- break;
-
- case bfd_arch_s390:
- init_dwarf_regnames_s390 ();
- break;
-
- case bfd_arch_riscv:
- init_dwarf_regnames_riscv ();
- break;
-
case bfd_arch_s12z:
/* S12Z has a 24 bit address space. But the only known
producer of dwarf_info encodes addresses into 32 bits. */
break;
default:
+ eh_addr_size = bfd_arch_bits_per_address (abfd) / 8;
break;
}
+ init_dwarf_regnames_by_bfd_arch_and_mach (bfd_get_arch (abfd),
+ bfd_get_mach (abfd));
+
bfd_map_over_sections (abfd, dump_dwarf_section, NULL);
}
\f
return NULL;
}
- *size_ptr = bfd_section_size (abfd, stabsect);
+ *size_ptr = bfd_section_size (stabsect);
if (entsize_ptr)
*entsize_ptr = stabsect->entsize;
dump_ctf_archive_member (ctf_file_t *ctf, const char *name, void *arg)
{
ctf_file_t *parent = (ctf_file_t *) arg;
- const char *things[] = {"Labels", "Data objects", "Function objects",
- "Variables", "Types", "Strings", ""};
+ const char *things[] = {"Header", "Labels", "Data objects",
+ "Function objects", "Variables", "Types", "Strings",
+ ""};
const char **thing;
size_t i;
/* Only print out the name of non-default-named archive members.
The name .ctf appears everywhere, even for things that aren't
- really archives, so printing it out is liable to be confusing. */
+ really archives, so printing it out is liable to be confusing.
+
+ The parent, if there is one, is the default-owned archive member:
+ avoid importing it into itself. (This does no harm, but looks
+ confusing.) */
+
if (strcmp (name, ".ctf") != 0)
- printf (_("\nCTF archive member: %s:\n"), sanitize_string (name));
+ {
+ printf (_("\nCTF archive member: %s:\n"), sanitize_string (name));
+ ctf_import (ctf, parent);
+ }
- ctf_import (ctf, parent);
- for (i = 1, thing = things; *thing[0]; thing++, i++)
+ for (i = 0, thing = things; *thing[0]; thing++, i++)
{
ctf_dump_state_t *s = NULL;
char *item;
static void
dump_ctf (bfd *abfd, const char *sect_name, const char *parent_name)
{
- ctf_archive_t *ctfa, *parenta = NULL;
+ ctf_archive_t *ctfa, *parenta = NULL, *lookparent;
bfd_byte *ctfdata, *parentdata = NULL;
bfd_size_type ctfsize, parentsize;
ctf_sect_t ctfsect;
bfd_fatal (bfd_get_filename (abfd));
}
- /* Assume that the applicable parent archive member is the default one.
- (This is what all known implementations are expected to do, if they
- put CTFs and their parents in archives together.) */
- if ((parent = ctf_arc_open_by_name (parenta, NULL, &err)) == NULL)
- {
- non_fatal (_("CTF open failure: %s\n"), ctf_errmsg (err));
- bfd_fatal (bfd_get_filename (abfd));
- }
+ lookparent = parenta;
+ }
+ else
+ lookparent = ctfa;
+
+ /* Assume that the applicable parent archive member is the default one.
+ (This is what all known implementations are expected to do, if they
+ put CTFs and their parents in archives together.) */
+ if ((parent = ctf_arc_open_by_name (lookparent, NULL, &err)) == NULL)
+ {
+ non_fatal (_("CTF open failure: %s\n"), ctf_errmsg (err));
+ bfd_fatal (bfd_get_filename (abfd));
}
printf (_("Contents of CTF section %s:\n"), sanitize_string (sect_name));
bfd_vma addr_offset;
bfd_vma start_offset;
bfd_vma stop_offset;
- unsigned int opb = bfd_octets_per_byte (abfd);
+ unsigned int opb = bfd_octets_per_byte (abfd, section);
/* Bytes per line. */
const int onaline = 16;
char buf[64];
if (! process_section_p (section))
return;
- if ((datasize = bfd_section_size (abfd, section)) == 0)
+ if ((datasize = bfd_section_size (section)) == 0)
return;
/* Compute the address range to display. */
case OPTION_DWARF_CHECK:
dwarf_check = TRUE;
break;
- case OPTION_CTF:
- dump_ctf_section_info = TRUE;
- dump_ctf_section_name = xstrdup (optarg);
- seenflag = TRUE;
- break;
+ case OPTION_CTF:
+ dump_ctf_section_info = TRUE;
+ dump_ctf_section_name = xstrdup (optarg);
+ seenflag = TRUE;
+ break;
case OPTION_CTF_PARENT:
dump_ctf_parent_name = xstrdup (optarg);
break;