/* nlmconv.c -- NLM conversion program
- Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1993-2017 Free Software Foundation, Inc.
This file is part of GNU Binutils.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
/* Written by Ian Lance Taylor <ian@cygnus.com>.
#endif
#endif
+#include "sysdep.h"
#include "bfd.h"
#include "libiberty.h"
-#include "bucomm.h"
+#include "filenames.h"
#include "safe-ctype.h"
#include "ansidecl.h"
#include <time.h>
-#include <sys/stat.h>
-#include <sys/file.h>
#include <assert.h>
#include "getopt.h"
#include "coff/ecoff.h"
#endif
+#include "bucomm.h"
+
/* If strerror is just a macro, we want to use the one from libiberty
since it will handle undefined values. */
#undef strerror
extern char *strerror (int);
-#ifndef localtime
-extern struct tm *localtime ();
-#endif
-
#ifndef SEEK_SET
#define SEEK_SET 0
#endif
bfd *sharedbfd;
size_t shared_offset = 0;
size_t shared_size = 0;
- Nlm_Internal_Fixed_Header sharedhdr;
+ static Nlm_Internal_Fixed_Header sharedhdr;
int len;
char *modname;
char **matching;
program_name = argv[0];
xmalloc_set_program_name (program_name);
+ bfd_set_error_program_name (program_name);
+
+ expandargv (&argc, &argv);
bfd_init ();
set_default_bfd_target ();
++optind;
if (optind < argc)
show_usage (stderr, 1);
- if (strcmp (input_file, output_file) == 0)
+ if (filename_cmp (input_file, output_file) == 0)
{
fatal (_("input and output files must be different"));
}
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);
+ bss_sec = bfd_make_section_with_flags (outbfd,
+ NLM_UNINITIALIZED_DATA_NAME,
+ SEC_ALLOC);
if (bss_sec == NULL
- || ! bfd_set_section_flags (outbfd, bss_sec, SEC_ALLOC)
|| ! bfd_set_section_alignment (outbfd, bss_sec, 1))
bfd_fatal (_("make .bss section"));
}
so that programs which understand it can resurrect the original
sections from the NLM. We will put a pointer to .nlmsections in
the NLM header area. */
- secsec = bfd_make_section (outbfd, ".nlmsections");
+ secsec = bfd_make_section_with_flags (outbfd, ".nlmsections",
+ SEC_HAS_CONTENTS);
if (secsec == NULL)
bfd_fatal (_("make .nlmsections section"));
- if (! bfd_set_section_flags (outbfd, secsec, SEC_HAS_CONTENTS))
- bfd_fatal (_("set .nlmsections flags"));
#ifdef NLMCONV_POWERPC
/* For PowerPC NetWare we need to build stubs for calls to undefined
++sym->name;
else
{
- char *new;
+ char *new_name;
- new = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);
- new[0] = outlead;
- strcpy (new + 1, bfd_asymbol_name (sym) + 1);
- sym->name = new;
+ new_name = xmalloc (strlen (bfd_asymbol_name (sym)) + 1);
+ new_name[0] = outlead;
+ strcpy (new_name + 1, bfd_asymbol_name (sym) + 1);
+ sym->name = new_name;
}
}
}
else
{
- char *new;
+ char *new_name;
- new = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);
- new[0] = outlead;
- strcpy (new + 1, bfd_asymbol_name (sym));
- sym->name = new;
+ new_name = xmalloc (strlen (bfd_asymbol_name (sym)) + 2);
+ new_name[0] = outlead;
+ strcpy (new_name + 1, bfd_asymbol_name (sym));
+ sym->name = new_name;
}
}
else
{
custom_size = st.st_size;
- custom_section = bfd_make_section (outbfd, ".nlmcustom");
+ custom_section = bfd_make_section_with_flags (outbfd, ".nlmcustom",
+ SEC_HAS_CONTENTS);
if (custom_section == NULL
- || ! bfd_set_section_size (outbfd, custom_section, custom_size)
- || ! bfd_set_section_flags (outbfd, custom_section,
- SEC_HAS_CONTENTS))
+ || ! bfd_set_section_size (outbfd, custom_section, custom_size))
bfd_fatal (_("custom section"));
}
}
else
{
help_size = st.st_size;
- help_section = bfd_make_section (outbfd, ".nlmhelp");
+ help_section = bfd_make_section_with_flags (outbfd, ".nlmhelp",
+ SEC_HAS_CONTENTS);
if (help_section == NULL
- || ! bfd_set_section_size (outbfd, help_section, help_size)
- || ! bfd_set_section_flags (outbfd, help_section,
- SEC_HAS_CONTENTS))
+ || ! bfd_set_section_size (outbfd, help_section, help_size))
bfd_fatal (_("help section"));
- strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
+ LITMEMCPY (nlm_extended_header (outbfd)->stamp, "MeSsAgEs");
}
}
if (message_file != NULL)
else
{
message_size = st.st_size;
- message_section = bfd_make_section (outbfd, ".nlmmessages");
+ message_section = bfd_make_section_with_flags (outbfd,
+ ".nlmmessages",
+ SEC_HAS_CONTENTS);
if (message_section == NULL
- || ! bfd_set_section_size (outbfd, message_section, message_size)
- || ! bfd_set_section_flags (outbfd, message_section,
- SEC_HAS_CONTENTS))
+ || ! bfd_set_section_size (outbfd, message_section, message_size))
bfd_fatal (_("message section"));
- strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
+ LITMEMCPY (nlm_extended_header (outbfd)->stamp, "MeSsAgEs");
}
}
if (modules != NULL)
module_size = 0;
for (l = modules; l != NULL; l = l->next)
module_size += strlen (l->string) + 1;
- module_section = bfd_make_section (outbfd, ".nlmmodules");
+ module_section = bfd_make_section_with_flags (outbfd, ".nlmmodules",
+ SEC_HAS_CONTENTS);
if (module_section == NULL
- || ! bfd_set_section_size (outbfd, module_section, module_size)
- || ! bfd_set_section_flags (outbfd, module_section,
- SEC_HAS_CONTENTS))
+ || ! bfd_set_section_size (outbfd, module_section, module_size))
bfd_fatal (_("module section"));
}
if (rpc_file != NULL)
else
{
rpc_size = st.st_size;
- rpc_section = bfd_make_section (outbfd, ".nlmrpc");
+ rpc_section = bfd_make_section_with_flags (outbfd, ".nlmrpc",
+ SEC_HAS_CONTENTS);
if (rpc_section == NULL
- || ! bfd_set_section_size (outbfd, rpc_section, rpc_size)
- || ! bfd_set_section_flags (outbfd, rpc_section,
- SEC_HAS_CONTENTS))
+ || ! bfd_set_section_size (outbfd, rpc_section, rpc_size))
bfd_fatal (_("rpc section"));
- strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
+ LITMEMCPY (nlm_extended_header (outbfd)->stamp, "MeSsAgEs");
}
}
if (sharelib_file != NULL)
if (shared_offset > (size_t) sharedhdr.publicsOffset)
shared_offset = sharedhdr.publicsOffset;
shared_size = st.st_size - shared_offset;
- shared_section = bfd_make_section (outbfd, ".nlmshared");
+ shared_section = bfd_make_section_with_flags (outbfd,
+ ".nlmshared",
+ SEC_HAS_CONTENTS);
if (shared_section == NULL
|| ! bfd_set_section_size (outbfd, shared_section,
- shared_size)
- || ! bfd_set_section_flags (outbfd, shared_section,
- SEC_HAS_CONTENTS))
+ shared_size))
bfd_fatal (_("shared section"));
- strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
+ LITMEMCPY (nlm_extended_header (outbfd)->stamp, "MeSsAgEs");
}
}
}
/* Check whether a version was given. */
- if (strncmp (version_hdr->stamp, "VeRsIoN#", 8) != 0)
+ if (!CONST_STRNEQ (version_hdr->stamp, "VeRsIoN#"))
non_fatal (_("warning: No version number given"));
/* At least for now, always create an extended header, because that
is what NLMLINK does. */
- strncpy (nlm_extended_header (outbfd)->stamp, "MeSsAgEs", 8);
+ LITMEMCPY (nlm_extended_header (outbfd)->stamp, "MeSsAgEs");
- strncpy (nlm_cygnus_ext_header (outbfd)->stamp, "CyGnUsEx", 8);
+ LITMEMCPY (nlm_cygnus_ext_header (outbfd)->stamp, "CyGnUsEx");
/* If the date was not given, force it in. */
if (nlm_version_header (outbfd)->month == 0
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);
+ LITMEMCPY (version_hdr->stamp, "VeRsIoN#");
}
#ifdef NLMCONV_POWERPC
for (l = modules; l != NULL; l = l->next)
{
*set = strlen (l->string);
- strncpy (set + 1, l->string, *set);
+ strncpy ((char *) set + 1, l->string, *set);
set += *set + 1;
++c;
}
{
const int max_len = NLM_MODULE_NAME_SIZE - 2;
const char * filename = lbasename (output_file);
-
+
len = strlen (filename);
if (len > max_len)
len = max_len;
-T --header-file=<file> Read <file> for NLM header information\n\
-l --linker=<linker> Use <linker> for any linking\n\
-d --debug Display on stderr the linker command line\n\
+ @<file> Read options from <file>.\n\
-h --help Display this information\n\
-v --version Display the program's version\n\
"));
- if (status == 0)
+ if (REPORT_BUGS_TO[0] && status == 0)
fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
exit (status);
}
const char *inname;
asection *outsec;
bfd_size_type size;
- void *contents;
+ bfd_byte *contents;
long reloc_size;
bfd_byte buf[4];
bfd_size_type add;
contents = NULL;
else
{
- contents = xmalloc (size);
- if (! bfd_get_section_contents (inbfd, insec, contents,
- (file_ptr) 0, size))
+ if (!bfd_malloc_and_get_section (inbfd, insec, &contents))
bfd_fatal (bfd_get_filename (inbfd));
}
bfd_vma addend;
rel = *relocs++;
+ /* PR 17512: file: 057f89c1. */
+ if (rel->sym_ptr_ptr == NULL)
+ continue;
sym = *rel->sym_ptr_ptr;
/* We're moving the relocs from the input section to the output
/* Make a section to hold stubs. We don't set SEC_HAS_CONTENTS for
the section to prevent copy_sections from reading from it. */
- stub_sec = bfd_make_section (inbfd, ".stubs");
+ stub_sec = bfd_make_section_with_flags (inbfd, ".stubs",
+ (SEC_CODE
+ | SEC_RELOC
+ | SEC_ALLOC
+ | SEC_LOAD));
if (stub_sec == (asection *) NULL
- || ! bfd_set_section_flags (inbfd, stub_sec,
- (SEC_CODE
- | SEC_RELOC
- | SEC_ALLOC
- | SEC_LOAD))
|| ! bfd_set_section_alignment (inbfd, stub_sec, 2))
bfd_fatal (".stubs");
got_sec = bfd_get_section_by_name (inbfd, ".got");
if (got_sec == (asection *) NULL)
{
- got_sec = bfd_make_section (inbfd, ".got");
+ got_sec = bfd_make_section_with_flags (inbfd, ".got",
+ (SEC_DATA
+ | SEC_RELOC
+ | SEC_ALLOC
+ | SEC_LOAD
+ | SEC_HAS_CONTENTS));
if (got_sec == (asection *) NULL
- || ! bfd_set_section_flags (inbfd, got_sec,
- (SEC_DATA
- | SEC_RELOC
- | SEC_ALLOC
- | SEC_LOAD
- | SEC_HAS_CONTENTS))
|| ! bfd_set_section_alignment (inbfd, got_sec, 2))
bfd_fatal (".got");
}
/* Make a new undefined symbol with the same name but without
the leading `.'. */
- newsym = (asymbol *) xmalloc (sizeof (asymbol));
+ newsym = xmalloc (sizeof (asymbol));
*newsym = *sym;
- newname = (char *) xmalloc (strlen (bfd_asymbol_name (sym)));
+ newname = xmalloc (strlen (bfd_asymbol_name (sym)));
strcpy (newname, bfd_asymbol_name (sym) + 1);
newsym->name = newname;
toc_howto = bfd_reloc_type_lookup (insec->owner, BFD_RELOC_PPC_TOC16);
if (toc_howto == (reloc_howto_type *) NULL)
- abort ();
+ fatal (_("Unable to locate PPC_TOC16 reloc information"));
/* If this is the .got section, clear out all the contents beyond
the initial size. We must do this here because copy_sections is
}
}
+ /* PR 17512: file: 70cfde95. */
+ if (rel->howto == NULL)
+ continue;
+
/* We must be able to resolve all PC relative relocs at this
point. If we get a branch to an undefined symbol we build a
stub, since NetWare will resolve undefined symbols into a
{
bfd_vma val;
+ if (rel->address > contents_size - 4)
+ {
+ non_fatal (_("Out of range relocation: %lx"),
+ (long) rel->address);
+ break;
+ }
+
assert (rel->howto->size == 2 && rel->howto->pcrel_offset);
val = bfd_get_32 (outbfd, (bfd_byte *) contents + rel->address);
val = ((val &~ rel->howto->dst_mask)
switch (rel->howto->size)
{
case 1:
+ if (rel->address > contents_size - 2)
+ {
+ non_fatal (_("Out of range relocation: %lx"),
+ (long) rel->address);
+ break;
+ }
+
val = bfd_get_16 (outbfd,
(bfd_byte *) contents + rel->address);
val = ((val &~ rel->howto->dst_mask)
break;
case 2:
+ /* PR 17512: file: 0455a112. */
+ if (rel->address > contents_size - 4)
+ {
+ non_fatal (_("Out of range relocation: %lx"),
+ (long) rel->address);
+ break;
+ }
+
val = bfd_get_32 (outbfd,
(bfd_byte *) contents + rel->address);
val = ((val &~ rel->howto->dst_mask)
break;
default:
- abort ();
+ fatal (_("Unsupported relocation size: %d"), rel->howto->size);
}
if (! bfd_is_und_section (bfd_get_section (sym)))
file. */
static char *
-link_inputs (struct string_list *inputs, char *ld, char * map_file)
+link_inputs (struct string_list *inputs, char *ld, char * mfile)
{
size_t c;
struct string_list *q;
for (q = inputs; q != NULL; q = q->next)
++c;
- argv = (char **) alloca ((c + 7) * sizeof (char *));
+ argv = (char **) xmalloc ((c + 7) * sizeof (char *));
#ifndef __MSDOS__
if (ld == NULL)
argv[3] = unlink_on_exit;
/* If we have been given the name of a mapfile and that
name is not 'stderr' then pass it on to the linker. */
- if (map_file
- && * map_file
- && strcmp (map_file, "stderr") == 0)
+ if (mfile
+ && * mfile
+ && strcmp (mfile, "stderr") == 0)
{
argv[4] = (char *) "-Map";
- argv[5] = map_file;
+ argv[5] = mfile;
i = 6;
}
else
pid = pexecute (ld, argv, program_name, (char *) NULL, &errfmt, &errarg,
PEXECUTE_SEARCH | PEXECUTE_ONE);
+ free (argv);
+
if (pid == -1)
{
fprintf (stderr, _("%s: execution of %s failed: "), program_name, ld);