Back to index

cell-binutils  2.17cvs20070401
Defines | Functions | Variables
nlmconv.c File Reference
#include "bfd.h"
#include "libiberty.h"
#include "bucomm.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 "libnlm.h"
#include "nlmconv.h"

Go to the source code of this file.

Defines

#define R_OK   4
#define W_OK   2
#define X_OK   1
#define LD_NAME   "ld"

Functions

char * strerror (int)
int main (int, char **)
static void show_usage (FILE *, int)
static const char * select_output_format (enum bfd_architecture, unsigned long, bfd_boolean)
static void setup_sections (bfd *, asection *, void *)
static void copy_sections (bfd *, asection *, void *)
static void mangle_relocs (bfd *, asection *, arelent ***, long *, char *, bfd_size_type)
static void default_mangle_relocs (bfd *, asection *, arelent ***, long *, char *, bfd_size_type)
static char * link_inputs (struct string_list *, char *, char *)
static const char * select_output_format (enum bfd_architecture arch, unsigned long mach, bfd_boolean bigendian ATTRIBUTE_UNUSED)
static void setup_sections (bfd *inbfd ATTRIBUTE_UNUSED, asection *insec, void *data_ptr)
static void default_mangle_relocs (bfd *outbfd ATTRIBUTE_UNUSED, asection *insec, arelent ***relocs_ptr, long *reloc_count_ptr, char *contents ATTRIBUTE_UNUSED, bfd_size_type contents_size ATTRIBUTE_UNUSED)

Variables

char * program_name
static int debug
static asymbol ** symbols
static asectionsecsec
static char * unlink_on_exit
static struct option []

Define Documentation

#define LD_NAME   "ld"

Definition at line 2036 of file nlmconv.c.

#define R_OK   4

Definition at line 66 of file nlmconv.c.

#define W_OK   2

Definition at line 67 of file nlmconv.c.

#define X_OK   1

Definition at line 68 of file nlmconv.c.


Function Documentation

static void copy_sections ( bfd inbfd,
asection insec,
void *  data_ptr 
) [static]

Definition at line 1221 of file nlmconv.c.

{
  static bfd_size_type secsecoff = 0;
  bfd *outbfd = (bfd *) data_ptr;
  const char *inname;
  asection *outsec;
  bfd_size_type size;
  void *contents;
  long reloc_size;
  bfd_byte buf[4];
  bfd_size_type add;

  inname = bfd_section_name (inbfd, insec);

  outsec = insec->output_section;
  assert (outsec != NULL);

  size = bfd_get_section_size (insec);

  if ((bfd_get_section_flags (inbfd, insec) & SEC_HAS_CONTENTS) == 0)
    contents = NULL;
  else
    {
      contents = xmalloc (size);
      if (! bfd_get_section_contents (inbfd, insec, contents,
                                  (file_ptr) 0, size))
       bfd_fatal (bfd_get_filename (inbfd));
    }

  reloc_size = bfd_get_reloc_upper_bound (inbfd, insec);
  if (reloc_size < 0)
    bfd_fatal (bfd_get_filename (inbfd));
  if (reloc_size != 0)
    {
      arelent **relocs;
      long reloc_count;

      relocs = (arelent **) xmalloc (reloc_size);
      reloc_count = bfd_canonicalize_reloc (inbfd, insec, relocs, symbols);
      if (reloc_count < 0)
       bfd_fatal (bfd_get_filename (inbfd));
      mangle_relocs (outbfd, insec, &relocs, &reloc_count, (char *) contents,
                   size);

      /* FIXME: refers to internal BFD fields.  */
      if (outsec->orelocation != (arelent **) NULL)
       {
         bfd_size_type total_count;
         arelent **combined;

         total_count = reloc_count + outsec->reloc_count;
         combined = (arelent **) xmalloc (total_count * sizeof (arelent *));
         memcpy (combined, outsec->orelocation,
                outsec->reloc_count * sizeof (arelent *));
         memcpy (combined + outsec->reloc_count, relocs,
                (size_t) (reloc_count * sizeof (arelent *)));
         free (outsec->orelocation);
         reloc_count = total_count;
         relocs = combined;
       }

      bfd_set_reloc (outbfd, outsec, relocs, reloc_count);
    }

  if (contents != NULL)
    {
      if (! bfd_set_section_contents (outbfd, outsec, contents,
                                  insec->output_offset, size))
       bfd_fatal (bfd_get_filename (outbfd));
      free (contents);
    }

  /* Add this section to .nlmsections.  */
  if (! bfd_set_section_contents (outbfd, secsec, (void *) inname, secsecoff,
                              strlen (inname) + 1))
    bfd_fatal (_("set .nlmsection contents"));
  secsecoff += strlen (inname) + 1;

  add = ((secsecoff + 3) &~ 3) - secsecoff;
  if (add != 0)
    {
      bfd_h_put_32 (outbfd, (bfd_vma) 0, buf);
      if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, add))
       bfd_fatal (_("set .nlmsection contents"));
      secsecoff += add;
    }

  if (contents != NULL)
    bfd_h_put_32 (outbfd, (bfd_vma) outsec->filepos, buf);
  else
    bfd_h_put_32 (outbfd, (bfd_vma) 0, buf);
  if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, 4))
    bfd_fatal (_("set .nlmsection contents"));
  secsecoff += 4;

  bfd_h_put_32 (outbfd, (bfd_vma) size, buf);
  if (! bfd_set_section_contents (outbfd, secsec, buf, secsecoff, 4))
    bfd_fatal (_("set .nlmsection contents"));
  secsecoff += 4;
}

Here is the call graph for this function:

static void default_mangle_relocs ( bfd ,
asection ,
arelent ***  ,
long ,
char *  ,
bfd_size_type   
) [static]

Here is the caller graph for this function:

static void default_mangle_relocs ( bfd *outbfd  ATTRIBUTE_UNUSED,
asection insec,
arelent ***  relocs_ptr,
long reloc_count_ptr,
char *contents  ATTRIBUTE_UNUSED,
bfd_size_type contents_size  ATTRIBUTE_UNUSED 
) [static]

Definition at line 1361 of file nlmconv.c.

{
  if (insec->output_offset != 0)
    {
      long reloc_count;
      arelent **relocs;
      long i;

      reloc_count = *reloc_count_ptr;
      relocs = *relocs_ptr;
      for (i = 0; i < reloc_count; i++, relocs++)
       (*relocs)->address += insec->output_offset;
    }
}
static char * link_inputs ( struct string_list inputs,
char *  ld,
char *  map_file 
) [static]

Definition at line 2044 of file nlmconv.c.

{
  size_t c;
  struct string_list *q;
  char **argv;
  size_t i;
  int pid;
  int status;
  char *errfmt;
  char *errarg;

  c = 0;
  for (q = inputs; q != NULL; q = q->next)
    ++c;

  argv = (char **) alloca ((c + 7) * sizeof (char *));

#ifndef __MSDOS__
  if (ld == NULL)
    {
      char *p;

      /* Find the linker to invoke based on how nlmconv was run.  */
      p = program_name + strlen (program_name);
      while (p != program_name)
       {
         if (p[-1] == '/')
           {
             ld = (char *) xmalloc (p - program_name + strlen (LD_NAME) + 1);
             memcpy (ld, program_name, p - program_name);
             strcpy (ld + (p - program_name), LD_NAME);
             break;
           }
         --p;
       }
    }
#endif

  if (ld == NULL)
    ld = (char *) LD_NAME;

  unlink_on_exit = make_temp_file (".O");

  argv[0] = ld;
  argv[1] = (char *) "-Ur";
  argv[2] = (char *) "-o";
  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)
    {
      argv[4] = (char *) "-Map";
      argv[5] = map_file;
      i = 6;
    }
  else
    i = 4;

  for (q = inputs; q != NULL; q = q->next, i++)
    argv[i] = q->string;
  argv[i] = NULL;

  if (debug)
    {
      for (i = 0; argv[i] != NULL; i++)
       fprintf (stderr, " %s", argv[i]);
      fprintf (stderr, "\n");
    }

  pid = pexecute (ld, argv, program_name, (char *) NULL, &errfmt, &errarg,
                PEXECUTE_SEARCH | PEXECUTE_ONE);
  if (pid == -1)
    {
      fprintf (stderr, _("%s: execution of %s failed: "), program_name, ld);
      fprintf (stderr, errfmt, errarg);
      unlink (unlink_on_exit);
      exit (1);
    }

  if (pwait (pid, &status, 0) < 0)
    {
      perror ("pwait");
      unlink (unlink_on_exit);
      exit (1);
    }

  if (status != 0)
    {
      non_fatal (_("Execution of %s failed"), ld);
      unlink (unlink_on_exit);
      exit (1);
    }

  return unlink_on_exit;
}

Here is the call graph for this function:

int main ( int  argc,
char **  argv 
)
static void mangle_relocs ( bfd outbfd,
asection insec,
arelent ***  relocs_ptr,
long reloc_count_ptr,
char *  contents,
bfd_size_type  contents_size 
) [static]

Definition at line 1326 of file nlmconv.c.

{
  switch (bfd_get_arch (outbfd))
    {
#ifdef NLMCONV_I386
    case bfd_arch_i386:
      i386_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
                       contents, contents_size);
      break;
#endif
#ifdef NLMCONV_ALPHA
    case bfd_arch_alpha:
      alpha_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
                        contents, contents_size);
      break;
#endif
#ifdef NLMCONV_POWERPC
    case bfd_arch_powerpc:
      powerpc_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
                          contents, contents_size);
      break;
#endif
    default:
      default_mangle_relocs (outbfd, insec, relocs_ptr, reloc_count_ptr,
                          contents, contents_size);
      break;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static const char* select_output_format ( enum  bfd_architecture,
unsigned  long,
bfd_boolean   
) [static]
static const char* select_output_format ( enum bfd_architecture  arch,
unsigned long  mach,
bfd_boolean bigendian  ATTRIBUTE_UNUSED 
) [static]

Definition at line 1121 of file nlmconv.c.

{
  switch (arch)
    {
#ifdef NLMCONV_I386
    case bfd_arch_i386:
      return "nlm32-i386";
#endif
#ifdef NLMCONV_SPARC
    case bfd_arch_sparc:
      return "nlm32-sparc";
#endif
#ifdef NLMCONV_ALPHA
    case bfd_arch_alpha:
      return "nlm32-alpha";
#endif
#ifdef NLMCONV_POWERPC
    case bfd_arch_powerpc:
      return "nlm32-powerpc";
#endif
    default:
      fatal (_("support not compiled in for %s"),
            bfd_printable_arch_mach (arch, mach));
    }
  /*NOTREACHED*/
}

Here is the call graph for this function:

static void setup_sections ( bfd ,
asection ,
void *   
) [static]
static void setup_sections ( bfd *inbfd  ATTRIBUTE_UNUSED,
asection insec,
void *  data_ptr 
) [static]

Definition at line 1154 of file nlmconv.c.

{
  bfd *outbfd = (bfd *) data_ptr;
  flagword f;
  const char *outname;
  asection *outsec;
  bfd_vma offset;
  bfd_size_type align;
  bfd_size_type add;
  bfd_size_type secsecsize;

  f = bfd_get_section_flags (inbfd, insec);
  if (f & SEC_CODE)
    outname = NLM_CODE_NAME;
  else if ((f & SEC_LOAD) && (f & SEC_HAS_CONTENTS))
    outname = NLM_INITIALIZED_DATA_NAME;
  else if (f & SEC_ALLOC)
    outname = NLM_UNINITIALIZED_DATA_NAME;
  else
    outname = bfd_section_name (inbfd, insec);

  outsec = bfd_get_section_by_name (outbfd, outname);
  if (outsec == NULL)
    {
      outsec = bfd_make_section (outbfd, outname);
      if (outsec == NULL)
       bfd_fatal (_("make section"));
    }

  insec->output_section = outsec;

  offset = bfd_section_size (outbfd, outsec);
  align = 1 << bfd_section_alignment (inbfd, insec);
  add = ((offset + align - 1) &~ (align - 1)) - offset;
  insec->output_offset = offset + add;

  if (! bfd_set_section_size (outbfd, outsec,
                           (bfd_section_size (outbfd, outsec)
                            + bfd_section_size (inbfd, insec)
                            + add)))
    bfd_fatal (_("set section size"));

  if ((bfd_section_alignment (inbfd, insec)
       > bfd_section_alignment (outbfd, outsec))
      && ! bfd_set_section_alignment (outbfd, outsec,
                                  bfd_section_alignment (inbfd, insec)))
    bfd_fatal (_("set section alignment"));

  if (! bfd_set_section_flags (outbfd, outsec,
                            f | bfd_get_section_flags (outbfd, outsec)))
    bfd_fatal (_("set section flags"));

  bfd_set_reloc (outbfd, outsec, (arelent **) NULL, 0);

  /* For each input section we allocate space for an entry in
     .nlmsections.  */
  secsecsize = bfd_section_size (outbfd, secsec);
  secsecsize += strlen (bfd_section_name (inbfd, insec)) + 1;
  secsecsize = (secsecsize + 3) &~ 3;
  secsecsize += 8;
  if (! bfd_set_section_size (outbfd, secsec, secsecsize))
    bfd_fatal (_("set .nlmsections size"));
}

Here is the call graph for this function:

static void show_usage ( FILE *  file,
int  status 
) [static]

Definition at line 1098 of file nlmconv.c.

{
  fprintf (file, _("Usage: %s [option(s)] [in-file [out-file]]\n"), program_name);
  fprintf (file, _(" Convert an object file into a NetWare Loadable Module\n"));
  fprintf (file, _(" The options are:\n\
  -I --input-target=<bfdname>   Set the input binary file format\n\
  -O --output-target=<bfdname>  Set the output binary file format\n\
  -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 (REPORT_BUGS_TO[0] && status == 0)
    fprintf (file, _("Report bugs to %s\n"), REPORT_BUGS_TO);
  exit (status);
}

Here is the call graph for this function:

char* strerror ( int  )

Definition at line 626 of file strerror.c.

{
  const char *msg;
  static char buf[32];

#ifndef HAVE_SYS_ERRLIST

  if (error_names == NULL)
    {
      init_error_tables ();
    }

#endif

  if ((errnoval < 0) || (errnoval >= sys_nerr))
    {
#ifdef EVMSERR
      if (errnoval == evmserr.value)
       msg = evmserr.msg;
      else
#endif
      /* Out of range, just return NULL */
      msg = NULL;
    }
  else if ((sys_errlist == NULL) || (sys_errlist[errnoval] == NULL))
    {
      /* In range, but no sys_errlist or no entry at this index. */
      sprintf (buf, "Error %d", errnoval);
      msg = buf;
    }
  else
    {
      /* In range, and a valid message.  Just return the message. */
      msg = (char *) sys_errlist[errnoval];
    }
  
  return (msg);
}

Here is the caller graph for this function:


Variable Documentation

int debug [static]

Definition at line 80 of file nlmconv.c.

struct option[] [static]
Initial value:
{
  { "debug", no_argument, 0, 'd' },
  { "header-file", required_argument, 0, 'T' },
  { "help", no_argument, 0, 'h' },
  { "input-target", required_argument, 0, 'I' },
  { "input-format", required_argument, 0, 'I' }, 
  { "linker", required_argument, 0, 'l' },
  { "output-target", required_argument, 0, 'O' },
  { "output-format", required_argument, 0, 'O' }, 
  { "version", no_argument, 0, 'V' },
  { NULL, no_argument, 0, 0 }
}

Definition at line 105 of file nlmconv.c.

char* program_name

Definition at line 74 of file nlmconv.c.

asection* secsec [static]

Definition at line 97 of file nlmconv.c.

asymbol** symbols [static]

Definition at line 83 of file nlmconv.c.

char* unlink_on_exit [static]

Definition at line 102 of file nlmconv.c.