* nlmconv.c (main): Force creation of .bss section. Set up the

sections before looking at the symbols.  Move all common symbols
	into .bss section.  Automatically define _edata and _end.  Only
	export symbols in the export list, with multiple prefixes if
	necessary.  Warn if no version.  Always create extended header.
	Set date automatically if not already set.
	(setup_sections): Count size of bss sections.
	(mangle_relocs, i386_mangle_relocs): Accept section argument, and
	take reloc_count as a changeable pointer; changed callers.
	(i386_mangle_relocs): Remove PC relative relocs within a section,
	as they require no adjustment.
	* nlmheader.y: Fixed memory allocation throughout: token STRING is
	now allocated on the heap, and freed if not needed.  Null
	terminated copyright message.  Accept version with only two
	strings.
	(symbol_list_opt): New nonterminal, either symbol_list or empty.
	(symbol_list): Use left recursion to avoid overflowing parser
	stack.
	(yylex): Rearranged beginning of line check.  Accept quoted
	strings using single quotes.  End generic argument at comment
	character or parentheses.
	(string_list_append): Fixed.
	(string_list_append1): New function.
This commit is contained in:
Ian Lance Taylor 1993-08-31 17:47:58 +00:00
parent f993f087da
commit ef5b53687b
2 changed files with 347 additions and 39 deletions

View File

@ -1,3 +1,62 @@
Tue Aug 31 13:29:12 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
* nlmconv.c (main): Force creation of .bss section. Set up the
sections before looking at the symbols. Move all common symbols
into .bss section. Automatically define _edata and _end. Only
export symbols in the export list, with multiple prefixes if
necessary. Warn if no version. Always create extended header.
Set date automatically if not already set.
(setup_sections): Count size of bss sections.
(mangle_relocs, i386_mangle_relocs): Accept section argument, and
take reloc_count as a changeable pointer; changed callers.
(i386_mangle_relocs): Remove PC relative relocs within a section,
as they require no adjustment.
* nlmheader.y: Fixed memory allocation throughout: token STRING is
now allocated on the heap, and freed if not needed. Null
terminated copyright message. Accept version with only two
strings.
(symbol_list_opt): New nonterminal, either symbol_list or empty.
(symbol_list): Use left recursion to avoid overflowing parser
stack.
(yylex): Rearranged beginning of line check. Accept quoted
strings using single quotes. End generic argument at comment
character or parentheses.
(string_list_append): Fixed.
(string_list_append1): New function.
* bucomm.h: The first argument to xrealloc is PTR, not char *.
* bucomm.c (xrealloc): Use PTR rather than char *.
* Makefile.in (objdump.o): Depend upon config.status to notice
--with-targets changes.
(nlmconv.o): Depend upon bucomm.h.
Tue Aug 17 09:46:01 1993 David J. Mackenzie (djm@thepub.cygnus.com)
* configure.in: Don't pass cpu to config.bfd.
Thu Aug 12 16:43:04 1993 David J. Mackenzie (djm@thepub.cygnus.com)
* Makefile.in ($(NM_PROG)): Depend on demangle.o.
(demangle.o): New target.
(cplus-dem.o): Depend on it, to force compilation order when doing
parallel compiles.
* nm.c (print_symbol_info_{bsd,sysv,posix}): Take a bfd arg.
(struct output_fns print_symbol_info): Ditto.
(long_options, usage, main): Add -C --demangle option.
(print_symname): New function, demangling if requested.
(print_symbols, print_symbol_info_{bsd,sysv,posix}): Use it.
Wed Aug 11 22:57:23 1993 David J. Mackenzie (djm@thepub.cygnus.com)
* Makefile.in: Put CFLAGS last in compilation rules and omit from
linking rules. Use ARCHDEFS to compile objdump.c.
Update dependencies.
* configure.in: Construct ARCHDEFS based on the BFD target makefile
fragments.
* objdump.c: Conditionalize calls to the print_insn_ARCH functions
according to ARCHDEFS.
Thu Aug 12 08:06:15 1993 Ian Lance Taylor (ian@cygnus.com)
* ar.c: Removed obsolete and non-functional GNU960 code.

View File

@ -28,6 +28,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <stdio.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <assert.h>
@ -43,6 +44,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
since it will handle undefined values. */
#undef strerror
extern char *strerror ();
#ifndef localtime
extern struct tm *localtime ();
#endif
#ifndef SEEK_SET
#define SEEK_SET 0
#endif
/* Global variables. */
@ -52,19 +61,22 @@ char *program_name;
/* The version number. */
extern char *program_version;
/* The symbols table. */
/* Local variables. */
/* The symbol table. */
static asymbol **symbols;
/* Local variables. */
/* The total amount of bss space. */
static bfd_size_type total_bss_size;
/* The list of long options. */
static struct option long_options[] =
{
{ "header-info", required_argument, 0, 'T' },
{ "help", no_argument, 0, 'H' },
{ "help", no_argument, 0, 'h' },
{ "input-format", required_argument, 0, 'I' },
{ "output-format", required_argument, 0, 'O' },
{ "version", no_argument, 0, 'v' },
{ "version", no_argument, 0, 'V' },
{ NULL, no_argument, 0, 0 }
};
@ -76,11 +88,12 @@ static const char *select_output_format PARAMS ((enum bfd_architecture,
long, boolean));
static void setup_sections PARAMS ((bfd *, asection *, PTR));
static void copy_sections PARAMS ((bfd *, asection *, PTR));
static void mangle_relocs PARAMS ((bfd *, arelent **,
bfd_size_type, char *,
static void mangle_relocs PARAMS ((bfd *, asection *, arelent **,
bfd_size_type *, char *,
bfd_size_type));
static void i386_mangle_relocs PARAMS ((bfd *, arelent **, bfd_size_type,
char *, bfd_size_type));
static void i386_mangle_relocs PARAMS ((bfd *, asection *, arelent **,
bfd_size_type *, char *,
bfd_size_type));
/* The main routine. */
@ -95,27 +108,33 @@ main (argc, argv)
const char *header_file = NULL;
bfd *inbfd;
bfd *outbfd;
unsigned int symcount;
asymbol **newsyms, **outsyms;
unsigned int symcount, newsymalloc, newsymcount;
asection *bss_sec;
asymbol *endsym;
unsigned int i;
char inlead, outlead;
boolean gotstart, gotexit, gotcheck;
struct stat st;
FILE *custom_data, *help_data, *message_data, *rpc_data;
FILE *custom_data, *help_data, *message_data, *rpc_data, *shared_data;
bfd_size_type custom_size, help_size, message_size, module_size, rpc_size;
asection *custom_section, *help_section, *message_section, *module_section;
asection *rpc_section;
asection *rpc_section, *shared_section;
bfd *sharedbfd;
bfd_size_type shared_offset, shared_size;
Nlm_Internal_Fixed_Header sharedhdr;
int len;
program_name = argv[0];
bfd_init ();
while ((opt = getopt_long (argc, argv, "HI:O:T:v", long_options, (int *) 0))
while ((opt = getopt_long (argc, argv, "hI:O:T:V", long_options, (int *) 0))
!= EOF)
{
switch (opt)
{
case 'H':
case 'h':
show_help ();
/*NOTREACHED*/
case 'I':
@ -127,7 +146,7 @@ main (argc, argv)
case 'T':
header_file = optarg;
break;
case 'v':
case 'V':
printf ("GNU %s version %s\n", program_name, program_version);
exit (0);
/*NOTREACHED*/
@ -215,12 +234,31 @@ main (argc, argv)
symbols = (asymbol **) xmalloc (get_symtab_upper_bound (inbfd));
symcount = bfd_canonicalize_symtab (inbfd, symbols);
/* Make sure we have a .bss section. Doing this first is an attempt
to ensure that it will be the first bss section. */
bss_sec = bfd_get_section_by_name (outbfd, NLM_UNINITIALIZED_DATA_NAME);
if (bss_sec == NULL)
{
bss_sec = bfd_make_section (outbfd, NLM_UNINITIALIZED_DATA_NAME);
if (bss_sec == NULL)
bfd_fatal ("make .bss section");
bss_sec->flags = SEC_ALLOC;
bss_sec->alignment_power = bfd_log2 (0); /* FIXME */
}
/* Set up the sections. */
bfd_map_over_sections (inbfd, setup_sections, (PTR) outbfd);
/* Adjust symbol information. */
inlead = bfd_get_symbol_leading_char (inbfd);
outlead = bfd_get_symbol_leading_char (outbfd);
gotstart = false;
gotexit = false;
gotcheck = false;
newsymalloc = 10;
newsyms = (asymbol **) xmalloc (newsymalloc * sizeof (asymbol *));
newsymcount = 0;
endsym = NULL;
for (i = 0; i < symcount; i++)
{
register asymbol *sym;
@ -258,17 +296,55 @@ main (argc, argv)
}
}
/* If this is a global symbol, see if it's in the export list.
Change the prefix if necessary. */
if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0
&& export_symbols != NULL)
/* NLM's have an uninitialized data section, but they do not
have a common section in the Unix sense. Move all common
symbols into the .bss section, and mark them as exported. */
if (bfd_is_com_section (bfd_get_section (sym)))
{
bfd_vma size;
bfd_size_type align;
sym->section = bss_sec;
size = sym->value;
sym->value = bss_sec->_raw_size;
bss_sec->_raw_size += size;
align = 1 << bss_sec->alignment_power;
bss_sec->_raw_size = (bss_sec->_raw_size + align - 1) &~ (align - 1);
total_bss_size += bss_sec->_raw_size - sym->value;
sym->flags |= BSF_EXPORT | BSF_GLOBAL;
}
/* Force _edata and _end to be defined. This would normally be
done by the linker, but the manipulation of the common
symbols will confuse it. */
if (bfd_asymbol_name (sym)[0] == '_'
&& bfd_get_section (sym) == &bfd_und_section)
{
if (strcmp (bfd_asymbol_name (sym), "_edata") == 0)
{
sym->section = bss_sec;
sym->value = 0;
}
if (strcmp (bfd_asymbol_name (sym), "_end") == 0)
{
sym->section = bss_sec;
endsym = sym;
}
}
/* If this is a global symbol, check the export list. */
if ((sym->flags & (BSF_EXPORT | BSF_GLOBAL)) != 0)
{
register struct string_list *l;
int found_simple;
/* Unfortunately, a symbol can appear multiple times on the
export list, with and without prefixes. */
found_simple = 0;
for (l = export_symbols; l != NULL; l = l->next)
{
if (strcmp (l->string, bfd_asymbol_name (sym)) == 0)
break;
found_simple = 1;
else
{
char *zbase;
@ -277,15 +353,30 @@ main (argc, argv)
if (zbase != NULL
&& strcmp (zbase + 1, bfd_asymbol_name (sym)) == 0)
{
sym->name = l->string;
break;
/* We must add a symbol with this prefix. */
if (newsymcount >= newsymalloc)
{
newsymalloc += 10;
newsyms = ((asymbol **)
xrealloc (newsyms,
(newsymalloc
* sizeof (asymbol *))));
}
newsyms[newsymcount] =
(asymbol *) xmalloc (sizeof (asymbol));
*newsyms[newsymcount] = *sym;
newsyms[newsymcount]->name = l->string;
++newsymcount;
}
}
}
if (l == NULL)
fprintf (stderr,
"%s: warning: symbol %s exported but not in export list\n",
program_name, bfd_asymbol_name (sym));
if (! found_simple)
{
/* The unmodified symbol is actually not exported at
all. */
sym->flags &=~ (BSF_GLOBAL | BSF_EXPORT);
sym->flags |= BSF_LOCAL;
}
}
/* If it's an undefined symbol, see if it's on the import list.
@ -340,7 +431,21 @@ main (argc, argv)
}
}
bfd_set_symtab (outbfd, symbols, symcount);
if (endsym != NULL)
endsym->value = total_bss_size;
if (newsymcount == 0)
outsyms = symbols;
else
{
outsyms = (asymbol **) xmalloc ((symcount + newsymcount + 1)
* sizeof (asymbol *));
memcpy (outsyms, symbols, symcount * sizeof (asymbol *));
memcpy (outsyms + symcount, newsyms, newsymcount * sizeof (asymbol *));
outsyms[symcount + newsymcount] = NULL;
}
bfd_set_symtab (outbfd, outsyms, symcount + newsymcount);
if (! gotstart)
fprintf (stderr, "%s: warning: START procedure %s not defined\n",
@ -353,9 +458,6 @@ main (argc, argv)
fprintf (stderr, "%s: warning: CHECK procedure %s not defined\n",
program_name, check_procedure);
/* Set up the sections. */
bfd_map_over_sections (inbfd, setup_sections, (PTR) outbfd);
/* Add additional sections required for the header information. */
if (custom_file != NULL)
{
@ -458,6 +560,83 @@ main (argc, argv)
strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
}
}
if (sharelib_file != NULL)
{
sharedbfd = bfd_openr (sharelib_file, output_format);
if (sharedbfd == NULL
|| ! bfd_check_format (sharedbfd, bfd_object))
{
fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
bfd_errmsg (bfd_error));
sharelib_file = NULL;
}
else
{
sharedhdr = *nlm_fixed_header (sharedbfd);
bfd_close (sharedbfd);
shared_data = fopen (sharelib_file, "r");
if (shared_data == NULL
|| (fstat (fileno (shared_data), &st) < 0))
{
fprintf (stderr, "%s:%s: %s\n", program_name, sharelib_file,
strerror (errno));
sharelib_file = NULL;
}
else
{
/* If we were clever, we could just copy out the
sections of the shared library which we actually
need. However, we would have to figure out the sizes
of the external and public information, and that can
not be done without reading through them. */
shared_offset = st.st_size;
if (shared_offset > sharedhdr.codeImageOffset)
shared_offset = sharedhdr.codeImageOffset;
if (shared_offset > sharedhdr.dataImageOffset)
shared_offset = sharedhdr.dataImageOffset;
if (shared_offset > sharedhdr.relocationFixupOffset)
shared_offset = sharedhdr.relocationFixupOffset;
if (shared_offset > sharedhdr.externalReferencesOffset)
shared_offset = sharedhdr.externalReferencesOffset;
if (shared_offset > sharedhdr.publicsOffset)
shared_offset = sharedhdr.publicsOffset;
shared_size = st.st_size - shared_offset;
shared_section = bfd_make_section (outbfd, ".nlmshared");
if (shared_section == NULL
|| ! bfd_set_section_size (outbfd, shared_section,
shared_size)
|| ! bfd_set_section_flags (outbfd, shared_section,
SEC_HAS_CONTENTS))
bfd_fatal ("shared section");
strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
}
}
}
/* Check whether a version was given. */
if (strncmp (version_hdr->stamp, "VeRsIoN#", 8) != 0)
fprintf (stderr, "%s: warning: No version number given\n",
program_name);
/* At least for now, always create an extended header, because that
is what NLMLINK does. */
strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
/* If the date was not given, force it in. */
if (nlm_version_header (outbfd)->month == 0
&& nlm_version_header (outbfd)->day == 0
&& nlm_version_header (outbfd)->year == 0)
{
unsigned long now; /* FIXME: should be time_t. */
struct tm *ptm;
time (&now);
ptm = localtime (&now);
nlm_version_header (outbfd)->month = ptm->tm_mon + 1;
nlm_version_header (outbfd)->day = ptm->tm_mday;
nlm_version_header (outbfd)->year = ptm->tm_year + 1900;
strncpy (version_hdr->stamp, "VeRsIoN#", 8);
}
/* Copy over the sections. */
bfd_map_over_sections (inbfd, copy_sections, (PTR) outbfd);
@ -583,6 +762,51 @@ main (argc, argv)
}
free (data);
}
if (sharelib_file != NULL)
{
PTR data;
data = xmalloc (shared_size);
if (fseek (shared_data, shared_offset, SEEK_SET) != 0
|| fread (data, 1, shared_size, shared_data) != shared_size)
fprintf (stderr, "%s:%s: read: %s\n", program_name, sharelib_file,
strerror (errno));
else
{
if (! bfd_set_section_contents (outbfd, shared_section, data,
(file_ptr) 0, shared_size))
bfd_fatal ("shared section");
}
nlm_extended_header (outbfd)->sharedCodeOffset =
sharedhdr.codeImageOffset - shared_offset + shared_section->filepos;
nlm_extended_header (outbfd)->sharedCodeLength =
sharedhdr.codeImageSize;
nlm_extended_header (outbfd)->sharedDataOffset =
sharedhdr.dataImageOffset - shared_offset + shared_section->filepos;
nlm_extended_header (outbfd)->sharedDataLength =
sharedhdr.dataImageSize;
nlm_extended_header (outbfd)->sharedRelocationFixupOffset =
(sharedhdr.relocationFixupOffset
- shared_offset
+ shared_section->filepos);
nlm_extended_header (outbfd)->sharedRelocationFixupCount =
sharedhdr.numberOfRelocationFixups;
nlm_extended_header (outbfd)->sharedExternalReferenceOffset =
(sharedhdr.externalReferencesOffset
- shared_offset
+ shared_section->filepos);
nlm_extended_header (outbfd)->sharedExternalReferenceCount =
sharedhdr.numberOfExternalReferences;
nlm_extended_header (outbfd)->sharedPublicsOffset =
sharedhdr.publicsOffset - shared_offset + shared_section->filepos;
nlm_extended_header (outbfd)->sharedPublicsCount =
sharedhdr.numberOfPublics;
nlm_extended_header (outbfd)->SharedInitializationOffset =
sharedhdr.codeStartOffset;
nlm_extended_header (outbfd)->SharedExitProcedureOffset =
sharedhdr.exitProcedureOffset;
free (data);
}
len = strlen (argv[optind + 1]);
if (len > NLM_MODULE_NAME_SIZE - 2)
len = NLM_MODULE_NAME_SIZE - 2;
@ -619,7 +843,7 @@ show_usage (file, status)
int status;
{
fprintf (file, "\
Usage: %s [-Hv] [-I format] [-O format] [-T header-file]\n\
Usage: %s [-hV] [-I format] [-O format] [-T header-file]\n\
[--input-format=format] [--output-format=format]\n\
[--header-file=file] [--help] [--version]\n\
in-file out-file\n",
@ -661,6 +885,7 @@ setup_sections (inbfd, insec, data_ptr)
{
bfd *outbfd = (bfd *) data_ptr;
asection *outsec;
flagword f;
outsec = bfd_get_section_by_name (outbfd, bfd_section_name (inbfd, insec));
if (outsec == NULL)
@ -685,9 +910,12 @@ setup_sections (inbfd, insec, data_ptr)
bfd_section_alignment (inbfd, insec)))
bfd_fatal ("set section alignment");
if (! bfd_set_section_flags (outbfd, outsec,
bfd_get_section_flags (inbfd, insec)))
f = bfd_get_section_flags (inbfd, insec);
if (! bfd_set_section_flags (outbfd, outsec, f))
bfd_fatal ("set section flags");
if ((f & SEC_LOAD) == 0 && (f & SEC_ALLOC) != 0)
total_bss_size += bfd_section_size (inbfd, insec);
}
/* Copy the section contents. */
@ -735,7 +963,8 @@ copy_sections (inbfd, insec, data_ptr)
relocs = (arelent **) xmalloc (reloc_size);
reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
mangle_relocs (outbfd, relocs, reloc_count, (char *) contents, size);
mangle_relocs (outbfd, insec, relocs, &reloc_count, (char *) contents,
size);
bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
}
@ -752,17 +981,18 @@ copy_sections (inbfd, insec, data_ptr)
by the input formats. */
static void
mangle_relocs (outbfd, relocs, reloc_count, contents, contents_size)
mangle_relocs (outbfd, insec, relocs, reloc_count_ptr, contents, contents_size)
bfd *outbfd;
asection *insec;
arelent **relocs;
bfd_size_type reloc_count;
bfd_size_type *reloc_count_ptr;
char *contents;
bfd_size_type contents_size;
{
switch (bfd_get_arch (outbfd))
{
case bfd_arch_i386:
i386_mangle_relocs (outbfd, relocs, reloc_count, contents,
i386_mangle_relocs (outbfd, insec, relocs, reloc_count_ptr, contents,
contents_size);
break;
default:
@ -792,14 +1022,19 @@ static reloc_howto_type nlm_i386_pcrel_howto =
true); /* pcrel_offset */
static void
i386_mangle_relocs (outbfd, relocs, reloc_count, contents, contents_size)
i386_mangle_relocs (outbfd, insec, relocs, reloc_count_ptr, contents,
contents_size)
bfd *outbfd;
asection *insec;
arelent **relocs;
bfd_size_type reloc_count;
bfd_size_type *reloc_count_ptr;
char *contents;
bfd_size_type contents_size;
{
while (reloc_count-- != 0)
bfd_size_type reloc_count, i;
reloc_count = *reloc_count_ptr;
for (i = 0; i < reloc_count; i++)
{
arelent *rel;
asymbol *sym;
@ -816,6 +1051,20 @@ i386_mangle_relocs (outbfd, relocs, reloc_count, contents, contents_size)
if (rel->address + 4 > contents_size)
continue;
/* A PC relative reloc entirely within a single section is
completely unnecessary. This can be generated by ld -r. */
if (sym == insec->symbol
&& rel->howto != NULL
&& rel->howto->pc_relative
&& ! rel->howto->pcrel_offset)
{
--*reloc_count_ptr;
--relocs;
memmove (relocs, relocs + 1,
(reloc_count - i) * sizeof (arelent *));
continue;
}
/* NetWare doesn't support reloc addends, so we get rid of them
here by simply adding them into the object data. We handle
the symbol value, if any, the same way. */