Back to index

cell-binutils  2.17cvs20070401
Classes | Typedefs | Functions | Variables
ldfile.c File Reference
#include "bfd.h"
#include "sysdep.h"
#include "bfdlink.h"
#include "safe-ctype.h"
#include "ld.h"
#include "ldmisc.h"
#include "ldexp.h"
#include "ldlang.h"
#include "ldfile.h"
#include "ldmain.h"
#include <ldgram.h>
#include "ldlex.h"
#include "ldemul.h"
#include "libiberty.h"
#include "filenames.h"

Go to the source code of this file.

Classes

struct  search_arch

Typedefs

typedef enum bfd_architecture
search_dirs_type *static
search_head char *slash struct
search_arch 
search_arch_type

Functions

static bfd_boolean is_sysrooted_pathname (const char *name, bfd_boolean notsame)
void ldfile_add_library_path (const char *name, bfd_boolean cmdline)
bfd_boolean ldfile_try_open_bfd (const char *attempt, lang_input_statement_type *entry)
bfd_boolean ldfile_open_file_search (const char *arch, lang_input_statement_type *entry, const char *lib, const char *suffix)
void ldfile_open_file (lang_input_statement_type *entry)
static FILE * try_open (const char *name, const char *exten)
static FILE * ldfile_find_command_file (const char *name, const char *extend)
void ldfile_open_command_file (const char *name)
void ldfile_add_arch (const char *in_name)
void ldfile_set_output_arch (const char *string, enum bfd_architecture defarch)

Variables

const char * ldfile_input_filename
bfd_boolean ldfile_assumed_script = FALSE
const char * ldfile_output_machine_name = ""
unsigned long ldfile_output_machine
static search_dirs_type ** search_tail_ptr = &search_head
static search_arch_typesearch_arch_head
static search_arch_type ** search_arch_tail_ptr = &search_arch_head

Class Documentation

struct search_arch

Definition at line 57 of file ldfile.c.

Collaboration diagram for search_arch:
Class Members
char * name
struct search_arch * next

Typedef Documentation


Function Documentation

static bfd_boolean is_sysrooted_pathname ( const char *  name,
bfd_boolean  notsame 
) [static]

Definition at line 71 of file ldfile.c.

{
  char * realname = ld_canon_sysroot ? lrealpath (name) : NULL;
  int len;
  bfd_boolean result;

  if (! realname)
    return FALSE;

  len = strlen (realname);

  if (((! notsame && len == ld_canon_sysroot_len)
       || (len >= ld_canon_sysroot_len
          && IS_DIR_SEPARATOR (realname[ld_canon_sysroot_len])
          && (realname[ld_canon_sysroot_len] = '\0') == '\0'))
      && FILENAME_CMP (ld_canon_sysroot, realname) == 0)
    result = TRUE;
  else
    result = FALSE;

  if (realname)
    free (realname);

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void ldfile_add_arch ( const char *  in_name)

Definition at line 511 of file ldfile.c.

{
  char *name = xstrdup (in_name);
  search_arch_type *new = xmalloc (sizeof (search_arch_type));

  ldfile_output_machine_name = in_name;

  new->name = name;
  new->next = NULL;
  while (*name)
    {
      *name = TOLOWER (*name);
      name++;
    }
  *search_arch_tail_ptr = new;
  search_arch_tail_ptr = &new->next;

}

Here is the call graph for this function:

Here is the caller graph for this function:

void ldfile_add_library_path ( const char *  name,
bfd_boolean  cmdline 
)

Definition at line 101 of file ldfile.c.

{
  search_dirs_type *new;

  if (!cmdline && config.only_cmd_line_lib_dirs)
    return;

  new = xmalloc (sizeof (search_dirs_type));
  new->next = NULL;
  new->cmdline = cmdline;
  *search_tail_ptr = new;
  search_tail_ptr = &new->next;

  /* If a directory is marked as honoring sysroot, prepend the sysroot path
     now.  */
  if (name[0] == '=')
    {
      new->name = concat (ld_sysroot, name + 1, NULL);
      new->sysrooted = TRUE;
    }
  else
    {
      new->name = xstrdup (name);
      new->sysrooted = is_sysrooted_pathname (name, FALSE);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static FILE* ldfile_find_command_file ( const char *  name,
const char *  extend 
) [static]

Definition at line 466 of file ldfile.c.

{
  search_dirs_type *search;
  FILE *result;
  char buffer[1000];

  /* First try raw name.  */
  result = try_open (name, "");
  if (result == NULL)
    {
      /* Try now prefixes.  */
      for (search = search_head; search != NULL; search = search->next)
       {
         sprintf (buffer, "%s%s%s", search->name, slash, name);

         result = try_open (buffer, extend);
         if (result)
           break;
       }
    }

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void ldfile_open_command_file ( const char *  name)

Definition at line 491 of file ldfile.c.

{
  FILE *ldlex_input_stack;
  ldlex_input_stack = ldfile_find_command_file (name, "");

  if (ldlex_input_stack == NULL)
    {
      bfd_set_error (bfd_error_system_call);
      einfo (_("%P%F: cannot open linker script file %s: %E\n"), name);
    }

  lex_push_file (ldlex_input_stack, name);

  ldfile_input_filename = name;
  lineno = 1;

  saved_script_handle = ldlex_input_stack;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 374 of file ldfile.c.

{
  if (entry->the_bfd != NULL)
    return;

  if (! entry->search_dirs_flag)
    {
      if (ldfile_try_open_bfd (entry->filename, entry))
       return;
      if (strcmp (entry->filename, entry->local_sym_name) != 0)
       einfo (_("%F%P: %s (%s): No such file: %E\n"),
              entry->filename, entry->local_sym_name);
      else
       einfo (_("%F%P: %s: No such file: %E\n"), entry->local_sym_name);
    }
  else
    {
      search_arch_type *arch;
      bfd_boolean found = FALSE;

      /* Try to open <filename><suffix> or lib<filename><suffix>.a */
      for (arch = search_arch_head; arch != NULL; arch = arch->next)
       {
         found = ldfile_open_file_search (arch->name, entry, "lib", ".a");
         if (found)
           break;
#ifdef VMS
         found = ldfile_open_file_search (arch->name, entry, ":lib", ".a");
         if (found)
           break;
#endif
         found = ldemul_find_potential_libraries (arch->name, entry);
         if (found)
           break;
       }

      /* If we have found the file, we don't need to search directories
        again.  */
      if (found)
       entry->search_dirs_flag = FALSE;
      else if (entry->sysrooted
              && ld_sysroot
              && IS_ABSOLUTE_PATH (entry->local_sym_name))
       einfo (_("%F%P: cannot find %s inside %s\n"),
              entry->local_sym_name, ld_sysroot);
      else
       einfo (_("%F%P: cannot find %s\n"), entry->local_sym_name);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

bfd_boolean ldfile_open_file_search ( const char *  arch,
lang_input_statement_type entry,
const char *  lib,
const char *  suffix 
)

Definition at line 298 of file ldfile.c.

{
  search_dirs_type *search;

  /* If this is not an archive, try to open it in the current
     directory first.  */
  if (! entry->is_archive)
    {
      if (entry->sysrooted && IS_ABSOLUTE_PATH (entry->filename))
       {
         char *name = concat (ld_sysroot, entry->filename,
                            (const char *) NULL);
         if (ldfile_try_open_bfd (name, entry))
           {
             entry->filename = name;
             return TRUE;
           }
         free (name);
       }
      else if (ldfile_try_open_bfd (entry->filename, entry))
       {
         entry->sysrooted = IS_ABSOLUTE_PATH (entry->filename)
           && is_sysrooted_pathname (entry->filename, TRUE);
         return TRUE;
       }

      if (IS_ABSOLUTE_PATH (entry->filename))
       return FALSE;
    }

  for (search = search_head; search != NULL; search = search->next)
    {
      char *string;

      if (entry->dynamic && ! link_info.relocatable)
       {
         if (ldemul_open_dynamic_archive (arch, search, entry))
           {
             entry->sysrooted = search->sysrooted;
             return TRUE;
           }
       }

      string = xmalloc (strlen (search->name)
                     + strlen (slash)
                     + strlen (lib)
                     + strlen (entry->filename)
                     + strlen (arch)
                     + strlen (suffix)
                     + 1);

      if (entry->is_archive)
       sprintf (string, "%s%s%s%s%s%s", search->name, slash,
               lib, entry->filename, arch, suffix);
      else
       sprintf (string, "%s%s%s", search->name, slash, entry->filename);

      if (ldfile_try_open_bfd (string, entry))
       {
         entry->filename = string;
         entry->sysrooted = search->sysrooted;
         return TRUE;
       }

      free (string);
    }

  return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void ldfile_set_output_arch ( const char *  string,
enum bfd_architecture  defarch 
)

Definition at line 533 of file ldfile.c.

{
  const bfd_arch_info_type *arch = bfd_scan_arch (string);

  if (arch)
    {
      ldfile_output_architecture = arch->arch;
      ldfile_output_machine = arch->mach;
      ldfile_output_machine_name = arch->printable_name;
    }
  else if (defarch != bfd_arch_unknown)
    ldfile_output_architecture = defarch;
  else
    einfo (_("%P%F: cannot represent machine `%s'\n"), string);
}

Here is the call graph for this function:

Definition at line 131 of file ldfile.c.

{
  entry->the_bfd = bfd_openr (attempt, entry->target);

  if (trace_file_tries)
    {
      if (entry->the_bfd == NULL)
       info_msg (_("attempt to open %s failed\n"), attempt);
      else
       info_msg (_("attempt to open %s succeeded\n"), attempt);
    }

  if (entry->the_bfd == NULL)
    {
      if (bfd_get_error () == bfd_error_invalid_target)
       einfo (_("%F%P: invalid BFD target `%s'\n"), entry->target);
      return FALSE;
    }

  /* If we are searching for this file, see if the architecture is
     compatible with the output file.  If it isn't, keep searching.
     If we can't open the file as an object file, stop the search
     here.  If we are statically linking, ensure that we don't link
     a dynamic object.  */

  if (entry->search_dirs_flag || !entry->dynamic)
    {
      bfd *check;

      if (bfd_check_format (entry->the_bfd, bfd_archive))
       check = bfd_openr_next_archived_file (entry->the_bfd, NULL);
      else
       check = entry->the_bfd;

      if (check != NULL)
       {
         if (! bfd_check_format (check, bfd_object))
           {
             if (check == entry->the_bfd
                && entry->search_dirs_flag
                && bfd_get_error () == bfd_error_file_not_recognized
                && ! ldemul_unrecognized_file (entry))
              {
                int token, skip = 0;
                char *arg, *arg1, *arg2, *arg3;
                extern FILE *yyin;

                /* Try to interpret the file as a linker script.  */
                ldfile_open_command_file (attempt);

                ldfile_assumed_script = TRUE;
                parser_input = input_selected;
                ldlex_both ();
                token = INPUT_SCRIPT;
                while (token != 0)
                  {
                    switch (token)
                     {
                     case OUTPUT_FORMAT:
                       if ((token = yylex ()) != '(')
                         continue;
                       if ((token = yylex ()) != NAME)
                         continue;
                       arg1 = yylval.name;
                       arg2 = NULL;
                       arg3 = NULL;
                       token = yylex ();
                       if (token == ',')
                         {
                           if ((token = yylex ()) != NAME)
                            {
                              free (arg1);
                              continue;
                            }
                           arg2 = yylval.name;
                           if ((token = yylex ()) != ','
                              || (token = yylex ()) != NAME)
                            {
                              free (arg1);
                              free (arg2);
                              continue;
                            }
                           arg3 = yylval.name;
                           token = yylex ();
                         }
                       if (token == ')')
                         {
                           switch (command_line.endian)
                            {
                            default:
                            case ENDIAN_UNSET:
                              arg = arg1; break;
                            case ENDIAN_BIG:
                              arg = arg2 ? arg2 : arg1; break;
                            case ENDIAN_LITTLE:
                              arg = arg3 ? arg3 : arg1; break;
                            }
                           if (strcmp (arg, lang_get_output_target ()) != 0)
                            skip = 1;
                         }
                       free (arg1);
                       if (arg2) free (arg2);
                       if (arg3) free (arg3);
                       break;
                     case NAME:
                     case LNAME:
                     case VERS_IDENTIFIER:
                     case VERS_TAG:
                       free (yylval.name);
                       break;
                     case INT:
                       if (yylval.bigint.str)
                         free (yylval.bigint.str);
                       break;
                     }
                    token = yylex ();
                  }
                ldlex_popstate ();
                ldfile_assumed_script = FALSE;
                fclose (yyin);
                yyin = NULL;
                if (skip)
                  {
                    einfo (_("%P: skipping incompatible %s when searching for %s\n"),
                          attempt, entry->local_sym_name);
                    bfd_close (entry->the_bfd);
                    entry->the_bfd = NULL;
                    return FALSE;
                  }
              }
             return TRUE;
           }

         if (!entry->dynamic && (entry->the_bfd->flags & DYNAMIC) != 0)
           {
             einfo (_("%F%P: attempted static link of dynamic object `%s'\n"),
                   attempt);
             bfd_close (entry->the_bfd);
             entry->the_bfd = NULL;
             return FALSE;
           }

         if (entry->search_dirs_flag
             && !bfd_arch_get_compatible (check, output_bfd,
                                      command_line.accept_unknown_input_arch)
             /* XCOFF archives can have 32 and 64 bit objects.  */
             && ! (bfd_get_flavour (check) == bfd_target_xcoff_flavour
                  && bfd_get_flavour (output_bfd) == bfd_target_xcoff_flavour
                  && bfd_check_format (entry->the_bfd, bfd_archive)))
           {
             einfo (_("%P: skipping incompatible %s when searching for %s\n"),
                   attempt, entry->local_sym_name);
             bfd_close (entry->the_bfd);
             entry->the_bfd = NULL;
             return FALSE;
           }
       }
    }

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static FILE* try_open ( const char *  name,
const char *  exten 
) [static]

Definition at line 427 of file ldfile.c.

{
  FILE *result;
  char buff[1000];

  result = fopen (name, "r");

  if (trace_file_tries)
    {
      if (result == NULL)
       info_msg (_("cannot find script file %s\n"), name);
      else
       info_msg (_("opened script file %s\n"), name);
    }

  if (result != NULL)
    return result;

  if (*exten)
    {
      sprintf (buff, "%s%s", name, exten);
      result = fopen (buff, "r");

      if (trace_file_tries)
       {
         if (result == NULL)
           info_msg (_("cannot find script file %s\n"), buff);
         else
           info_msg (_("opened script file %s\n"), buff);
       }
    }

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 41 of file ldfile.c.

Definition at line 40 of file ldfile.c.

Definition at line 43 of file ldfile.c.

Definition at line 42 of file ldfile.c.

Definition at line 64 of file ldfile.c.

Definition at line 65 of file ldfile.c.

Definition at line 63 of file ldfile.c.