#include <vector>
#include <cstdio>
#include <cstdlib>
+#include "filenames.h"
#include "options.h"
#include "fileread.h"
#include "workqueue.h"
#include "readsyms.h"
+#include "parameters.h"
#include "yyscript.h"
#include "script.h"
#include "script-c.h"
void
Lex::read_file(std::string* contents)
{
+ off_t filesize = this->input_file_->file().filesize();
contents->clear();
+ contents->reserve(filesize);
+
off_t off = 0;
- off_t got;
unsigned char buf[BUFSIZ];
- do
+ while (off < filesize)
{
- this->input_file_->file().read(off, sizeof buf, buf, &got);
- contents->append(reinterpret_cast<char*>(&buf[0]), got);
- off += got;
+ off_t get = BUFSIZ;
+ if (get > filesize - off)
+ get = filesize - off;
+ this->input_file_->file().read(off, get, buf);
+ contents->append(reinterpret_cast<char*>(&buf[0]), get);
+ off += get;
}
- while (got == sizeof buf);
}
// Return whether C can be the start of a name, if the next character
public:
Parser_closure(const char* filename,
const Position_dependent_options& posdep_options,
- bool in_group,
+ bool in_group, bool is_in_sysroot,
const Lex::Token_sequence* tokens)
: filename_(filename), posdep_options_(posdep_options),
- in_group_(in_group), tokens_(tokens),
+ in_group_(in_group), is_in_sysroot_(is_in_sysroot), tokens_(tokens),
next_token_index_(0), inputs_(NULL)
{ }
in_group() const
{ return this->in_group_; }
+ // Return whether this script was found using a directory in the
+ // sysroot.
+ bool
+ is_in_sysroot() const
+ { return this->is_in_sysroot_; }
+
// Whether we are at the end of the token list.
bool
at_eof() const
Position_dependent_options posdep_options_;
// Whether we are currently in a --start-group/--end-group.
bool in_group_;
+ // Whether the script was found in a sysrooted directory.
+ bool is_in_sysroot_;
// The tokens to be returned by the lexer.
const Lex::Token_sequence* tokens_;
Parser_closure closure(input_file->filename().c_str(),
input_argument->file().options(),
input_group != NULL,
+ input_file->is_in_sysroot(),
&lex.tokens());
if (yyparse(&closure) != 0)
script_add_file(void* closurev, const char* name)
{
Parser_closure* closure = static_cast<Parser_closure*>(closurev);
- std::string absname;
- if (name[0] == '/')
+
+ // If this is an absolute path, and we found the script in the
+ // sysroot, then we want to prepend the sysroot to the file name.
+ // For example, this is how we handle a cross link to the x86_64
+ // libc.so, which refers to /lib/libc.so.6.
+ std::string name_string;
+ const char* extra_search_path = ".";
+ std::string script_directory;
+ if (IS_ABSOLUTE_PATH (name))
{
- absname = name;
+ if (closure->is_in_sysroot())
+ {
+ const std::string& sysroot(parameters->sysroot());
+ gold_assert(!sysroot.empty());
+ name_string = sysroot + name;
+ name = name_string.c_str();
+ }
}
else
{
- // Prepend `dirname closure->filename()` to make the path absolute.
- char *slash = strrchr(closure->filename(), '/');
- absname.assign(closure->filename(),
- slash ? slash - closure->filename() + 1 : 0);
- absname += name;
+ // In addition to checking the normal library search path, we
+ // also want to check in the script-directory.
+ const char *slash = strrchr(closure->filename(), '/');
+ if (slash != NULL)
+ {
+ script_directory.assign(closure->filename(),
+ slash - closure->filename() + 1);
+ extra_search_path = script_directory.c_str();
+ }
}
- Input_file_argument file(absname.c_str(), false, closure->position_dependent_options());
+
+ Input_file_argument file(name, false, extra_search_path,
+ closure->position_dependent_options());
closure->inputs()->add_file(file);
}