Don't include libbfd.h outside of bfd, part 5
A rewrite of the code in bucomm.c supporting objdump -i, to use bfd_iterate_over_targets rather than accessing bfd_target_vector directly. Calculates widest arch string rather than using an out of date constant. Stashes info from the first display of valid target/arch combinations for use in second tabular display. binutils/ * bucomm.c: Don't include libbfd.h. (endian_string, display_target_list): Delete forward declaration. (display_info_table, display_target_tables): Likewise. (LONGEST_ARCH): Delete. (struct display_target): New. (do_display_target): New function. (display_target_list, display_info): Rewrite functions. (display_info_table): Delete. (do_info_size, do_info_header, do_info_row): New functions.
This commit is contained in:
parent
4212b42d79
commit
aac502f7d7
|
@ -1,3 +1,15 @@
|
||||||
|
2016-07-16 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* bucomm.c: Don't include libbfd.h.
|
||||||
|
(endian_string, display_target_list): Delete forward declaration.
|
||||||
|
(display_info_table, display_target_tables): Likewise.
|
||||||
|
(LONGEST_ARCH): Delete.
|
||||||
|
(struct display_target): New.
|
||||||
|
(do_display_target): New function.
|
||||||
|
(display_target_list, display_info): Rewrite functions.
|
||||||
|
(display_info_table): Delete.
|
||||||
|
(do_info_size, do_info_header, do_info_row): New functions.
|
||||||
|
|
||||||
2016-07-16 Alan Modra <amodra@gmail.com>
|
2016-07-16 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
* elfcomm.h (HOST_WIDEST_INT): Move to..
|
* elfcomm.h (HOST_WIDEST_INT): Move to..
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include "bfd.h"
|
#include "bfd.h"
|
||||||
#include "libiberty.h"
|
#include "libiberty.h"
|
||||||
#include "filenames.h"
|
#include "filenames.h"
|
||||||
#include "libbfd.h"
|
|
||||||
|
|
||||||
#include <time.h> /* ctime, maybe time_t */
|
#include <time.h> /* ctime, maybe time_t */
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -36,11 +35,6 @@
|
||||||
typedef long time_t;
|
typedef long time_t;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char * endian_string (enum bfd_endian);
|
|
||||||
static int display_target_list (void);
|
|
||||||
static int display_info_table (int, int);
|
|
||||||
static int display_target_tables (void);
|
|
||||||
|
|
||||||
/* Error reporting. */
|
/* Error reporting. */
|
||||||
|
|
||||||
|
@ -216,9 +210,6 @@ list_supported_architectures (const char *name, FILE *f)
|
||||||
free (arches);
|
free (arches);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The length of the longest architecture name + 1. */
|
|
||||||
#define LONGEST_ARCH sizeof ("powerpc:common")
|
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
endian_string (enum bfd_endian endian)
|
endian_string (enum bfd_endian endian)
|
||||||
{
|
{
|
||||||
|
@ -230,184 +221,205 @@ endian_string (enum bfd_endian endian)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Data passed to do_display_target and other target iterators. */
|
||||||
|
|
||||||
|
struct display_target {
|
||||||
|
/* Temp file. */
|
||||||
|
char *filename;
|
||||||
|
/* Return status. */
|
||||||
|
int error;
|
||||||
|
/* Number of targets. */
|
||||||
|
int count;
|
||||||
|
/* Size of info in bytes. */
|
||||||
|
size_t alloc;
|
||||||
|
/* Per-target info. */
|
||||||
|
struct {
|
||||||
|
/* Target name. */
|
||||||
|
const char *name;
|
||||||
|
/* Non-zero if target/arch combination supported. */
|
||||||
|
unsigned char arch[bfd_arch_last - bfd_arch_obscure - 1];
|
||||||
|
} *info;
|
||||||
|
};
|
||||||
|
|
||||||
/* List the targets that BFD is configured to support, each followed
|
/* List the targets that BFD is configured to support, each followed
|
||||||
by its endianness and the architectures it supports. */
|
by its endianness and the architectures it supports. Also build
|
||||||
|
info about target/archs. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
display_target_list (void)
|
do_display_target (const bfd_target *targ, void *data)
|
||||||
{
|
{
|
||||||
char *dummy_name;
|
struct display_target *param = (struct display_target *) data;
|
||||||
int t;
|
bfd *abfd;
|
||||||
int ret = 1;
|
size_t amt;
|
||||||
|
|
||||||
dummy_name = make_temp_file (NULL);
|
param->count += 1;
|
||||||
for (t = 0; bfd_target_vector[t]; t++)
|
amt = param->count * sizeof (*param->info);
|
||||||
|
if (param->alloc < amt)
|
||||||
{
|
{
|
||||||
const bfd_target *p = bfd_target_vector[t];
|
size_t size = ((param->count < 64 ? 64 : param->count)
|
||||||
bfd *abfd = bfd_openw (dummy_name, p->name);
|
* sizeof (*param->info) * 2);
|
||||||
int a;
|
param->info = xrealloc (param->info, size);
|
||||||
|
memset ((char *) param->info + param->alloc, 0, size - param->alloc);
|
||||||
|
param->alloc = size;
|
||||||
|
}
|
||||||
|
param->info[param->count - 1].name = targ->name;
|
||||||
|
|
||||||
printf (_("%s\n (header %s, data %s)\n"), p->name,
|
printf (_("%s\n (header %s, data %s)\n"), targ->name,
|
||||||
endian_string (p->header_byteorder),
|
endian_string (targ->header_byteorder),
|
||||||
endian_string (p->byteorder));
|
endian_string (targ->byteorder));
|
||||||
|
|
||||||
|
abfd = bfd_openw (param->filename, targ->name);
|
||||||
if (abfd == NULL)
|
if (abfd == NULL)
|
||||||
{
|
{
|
||||||
bfd_nonfatal (dummy_name);
|
bfd_nonfatal (param->filename);
|
||||||
ret = 0;
|
param->error = 1;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
else if (!bfd_set_format (abfd, bfd_object))
|
||||||
if (! bfd_set_format (abfd, bfd_object))
|
|
||||||
{
|
{
|
||||||
if (bfd_get_error () != bfd_error_invalid_operation)
|
if (bfd_get_error () != bfd_error_invalid_operation)
|
||||||
{
|
{
|
||||||
bfd_nonfatal (p->name);
|
bfd_nonfatal (targ->name);
|
||||||
ret = 0;
|
param->error = 1;
|
||||||
}
|
|
||||||
bfd_close_all_done (abfd);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
|
|
||||||
if (bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
|
|
||||||
printf (" %s\n",
|
|
||||||
bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
|
|
||||||
bfd_close_all_done (abfd);
|
|
||||||
}
|
|
||||||
unlink (dummy_name);
|
|
||||||
free (dummy_name);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print a table showing which architectures are supported for entries
|
|
||||||
FIRST through LAST-1 of bfd_target_vector (targets across,
|
|
||||||
architectures down). */
|
|
||||||
|
|
||||||
static int
|
|
||||||
display_info_table (int first, int last)
|
|
||||||
{
|
|
||||||
int t;
|
|
||||||
int ret = 1;
|
|
||||||
char *dummy_name;
|
|
||||||
int a;
|
|
||||||
|
|
||||||
/* Print heading of target names. */
|
|
||||||
printf ("\n%*s", (int) LONGEST_ARCH, " ");
|
|
||||||
for (t = first; t < last && bfd_target_vector[t]; t++)
|
|
||||||
printf ("%s ", bfd_target_vector[t]->name);
|
|
||||||
putchar ('\n');
|
|
||||||
|
|
||||||
dummy_name = make_temp_file (NULL);
|
|
||||||
for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
|
|
||||||
if (strcmp (bfd_printable_arch_mach ((enum bfd_architecture) a, 0),
|
|
||||||
"UNKNOWN!") != 0)
|
|
||||||
{
|
|
||||||
printf ("%*s ", (int) LONGEST_ARCH - 1,
|
|
||||||
bfd_printable_arch_mach ((enum bfd_architecture) a, 0));
|
|
||||||
for (t = first; t < last && bfd_target_vector[t]; t++)
|
|
||||||
{
|
|
||||||
const bfd_target *p = bfd_target_vector[t];
|
|
||||||
bfd_boolean ok = TRUE;
|
|
||||||
bfd *abfd = bfd_openw (dummy_name, p->name);
|
|
||||||
|
|
||||||
if (abfd == NULL)
|
|
||||||
{
|
|
||||||
bfd_nonfatal (p->name);
|
|
||||||
ret = 0;
|
|
||||||
ok = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ok)
|
|
||||||
{
|
|
||||||
if (! bfd_set_format (abfd, bfd_object))
|
|
||||||
{
|
|
||||||
if (bfd_get_error () != bfd_error_invalid_operation)
|
|
||||||
{
|
|
||||||
bfd_nonfatal (p->name);
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
ok = FALSE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ok)
|
|
||||||
{
|
|
||||||
if (! bfd_set_arch_mach (abfd, (enum bfd_architecture) a, 0))
|
|
||||||
ok = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ok)
|
|
||||||
printf ("%s ", p->name);
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int l = strlen (p->name);
|
enum bfd_architecture a;
|
||||||
while (l--)
|
|
||||||
putchar ('-');
|
for (a = bfd_arch_obscure + 1; a < bfd_arch_last; a++)
|
||||||
putchar (' ');
|
if (bfd_set_arch_mach (abfd, a, 0))
|
||||||
|
{
|
||||||
|
printf (" %s\n", bfd_printable_arch_mach (a, 0));
|
||||||
|
param->info[param->count - 1].arch[a - bfd_arch_obscure - 1] = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (abfd != NULL)
|
if (abfd != NULL)
|
||||||
bfd_close_all_done (abfd);
|
bfd_close_all_done (abfd);
|
||||||
}
|
|
||||||
putchar ('\n');
|
|
||||||
}
|
|
||||||
unlink (dummy_name);
|
|
||||||
free (dummy_name);
|
|
||||||
|
|
||||||
return ret;
|
return param->error;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
display_target_list (struct display_target *arg)
|
||||||
|
{
|
||||||
|
arg->filename = make_temp_file (NULL);
|
||||||
|
arg->error = 0;
|
||||||
|
arg->count = 0;
|
||||||
|
arg->alloc = 0;
|
||||||
|
arg->info = NULL;
|
||||||
|
|
||||||
|
bfd_iterate_over_targets (do_display_target, arg);
|
||||||
|
|
||||||
|
unlink (arg->filename);
|
||||||
|
free (arg->filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate how many targets we can print across the page. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_info_size (int targ, int width, const struct display_target *arg)
|
||||||
|
{
|
||||||
|
while (targ < arg->count)
|
||||||
|
{
|
||||||
|
width -= strlen (arg->info[targ].name) + 1;
|
||||||
|
if (width < 0)
|
||||||
|
return targ;
|
||||||
|
++targ;
|
||||||
|
}
|
||||||
|
return targ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print header of target names. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_info_header (int targ, int stop_targ, const struct display_target *arg)
|
||||||
|
{
|
||||||
|
while (targ != stop_targ)
|
||||||
|
printf ("%s ", arg->info[targ++].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print a table row. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_info_row (int targ, int stop_targ, enum bfd_architecture a,
|
||||||
|
const struct display_target *arg)
|
||||||
|
{
|
||||||
|
while (targ != stop_targ)
|
||||||
|
{
|
||||||
|
if (arg->info[targ].arch[a - bfd_arch_obscure - 1])
|
||||||
|
fputs (arg->info[targ].name, stdout);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int l = strlen (arg->info[targ].name);
|
||||||
|
while (l--)
|
||||||
|
putchar ('-');
|
||||||
|
}
|
||||||
|
++targ;
|
||||||
|
if (targ != stop_targ)
|
||||||
|
putchar (' ');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print tables of all the target-architecture combinations that
|
/* Print tables of all the target-architecture combinations that
|
||||||
BFD has been configured to support. */
|
BFD has been configured to support. */
|
||||||
|
|
||||||
static int
|
static void
|
||||||
display_target_tables (void)
|
display_target_tables (const struct display_target *arg)
|
||||||
{
|
{
|
||||||
int t;
|
const char *columns;
|
||||||
int columns;
|
int width, start_targ, stop_targ;
|
||||||
int ret = 1;
|
enum bfd_architecture arch;
|
||||||
char *colum;
|
int longest_arch = 0;
|
||||||
|
|
||||||
columns = 0;
|
for (arch = bfd_arch_obscure + 1; arch < bfd_arch_last; arch++)
|
||||||
colum = getenv ("COLUMNS");
|
|
||||||
if (colum != NULL)
|
|
||||||
columns = atoi (colum);
|
|
||||||
if (columns == 0)
|
|
||||||
columns = 80;
|
|
||||||
|
|
||||||
t = 0;
|
|
||||||
while (bfd_target_vector[t] != NULL)
|
|
||||||
{
|
{
|
||||||
int oldt = t, wid;
|
const char *s = bfd_printable_arch_mach (arch, 0);
|
||||||
|
int len = strlen (s);
|
||||||
wid = LONGEST_ARCH + strlen (bfd_target_vector[t]->name) + 1;
|
if (len > longest_arch)
|
||||||
++t;
|
longest_arch = len;
|
||||||
while (wid < columns && bfd_target_vector[t] != NULL)
|
|
||||||
{
|
|
||||||
int newwid;
|
|
||||||
|
|
||||||
newwid = wid + strlen (bfd_target_vector[t]->name) + 1;
|
|
||||||
if (newwid >= columns)
|
|
||||||
break;
|
|
||||||
wid = newwid;
|
|
||||||
++t;
|
|
||||||
}
|
|
||||||
if (! display_info_table (oldt, t))
|
|
||||||
ret = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
width = 0;
|
||||||
|
columns = getenv ("COLUMNS");
|
||||||
|
if (columns != NULL)
|
||||||
|
width = atoi (columns);
|
||||||
|
if (width == 0)
|
||||||
|
width = 80;
|
||||||
|
|
||||||
|
for (start_targ = 0; start_targ < arg->count; start_targ = stop_targ)
|
||||||
|
{
|
||||||
|
stop_targ = do_info_size (start_targ, width - longest_arch - 1, arg);
|
||||||
|
|
||||||
|
printf ("\n%*s", longest_arch + 1, " ");
|
||||||
|
do_info_header (start_targ, stop_targ, arg);
|
||||||
|
putchar ('\n');
|
||||||
|
|
||||||
|
for (arch = bfd_arch_obscure + 1; arch < bfd_arch_last; arch++)
|
||||||
|
{
|
||||||
|
if (strcmp (bfd_printable_arch_mach (arch, 0), "UNKNOWN!") != 0)
|
||||||
|
{
|
||||||
|
printf ("%*s ", longest_arch,
|
||||||
|
bfd_printable_arch_mach (arch, 0));
|
||||||
|
|
||||||
|
do_info_row (start_targ, stop_targ, arch, arg);
|
||||||
|
putchar ('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
display_info (void)
|
display_info (void)
|
||||||
{
|
{
|
||||||
|
struct display_target arg;
|
||||||
|
|
||||||
printf (_("BFD header file version %s\n"), BFD_VERSION_STRING);
|
printf (_("BFD header file version %s\n"), BFD_VERSION_STRING);
|
||||||
if (! display_target_list () || ! display_target_tables ())
|
|
||||||
return 1;
|
display_target_list (&arg);
|
||||||
else
|
if (!arg.error)
|
||||||
return 0;
|
display_target_tables (&arg);
|
||||||
|
|
||||||
|
return arg.error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Display the archive header for an element as if it were an ls -l listing:
|
/* Display the archive header for an element as if it were an ls -l listing:
|
||||||
|
|
Loading…
Reference in New Issue