Line 1... |
Line 1... |
// script.cc -- handle linker scripts for gold.
|
// script.cc -- handle linker scripts for gold.
|
|
|
// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
|
// Written by Ian Lance Taylor <iant@google.com>.
|
// Written by Ian Lance Taylor <iant@google.com>.
|
|
|
// This file is part of gold.
|
// This file is part of gold.
|
|
|
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
Line 144... |
Line 144... |
gold_assert(this->classification_ == TOKEN_OPERATOR);
|
gold_assert(this->classification_ == TOKEN_OPERATOR);
|
return this->opcode_;
|
return this->opcode_;
|
}
|
}
|
|
|
uint64_t
|
uint64_t
|
integer_value() const
|
integer_value() const;
|
{
|
|
gold_assert(this->classification_ == TOKEN_INTEGER);
|
|
// Null terminate.
|
|
std::string s(this->value_, this->value_length_);
|
|
return strtoull(s.c_str(), NULL, 0);
|
|
}
|
|
|
|
private:
|
private:
|
// The token classification.
|
// The token classification.
|
Classification classification_;
|
Classification classification_;
|
// The token value, for TOKEN_STRING or TOKEN_QUOTED_STRING or
|
// The token value, for TOKEN_STRING or TOKEN_QUOTED_STRING or
|
Line 169... |
Line 163... |
// The character position within the line where this token started
|
// The character position within the line where this token started
|
// (one based).
|
// (one based).
|
int charpos_;
|
int charpos_;
|
};
|
};
|
|
|
|
// Return the value of a TOKEN_INTEGER.
|
|
|
|
uint64_t
|
|
Token::integer_value() const
|
|
{
|
|
gold_assert(this->classification_ == TOKEN_INTEGER);
|
|
|
|
size_t len = this->value_length_;
|
|
|
|
uint64_t multiplier = 1;
|
|
char last = this->value_[len - 1];
|
|
if (last == 'm' || last == 'M')
|
|
{
|
|
multiplier = 1024 * 1024;
|
|
--len;
|
|
}
|
|
else if (last == 'k' || last == 'K')
|
|
{
|
|
multiplier = 1024;
|
|
--len;
|
|
}
|
|
|
|
char *end;
|
|
uint64_t ret = strtoull(this->value_, &end, 0);
|
|
gold_assert(static_cast<size_t>(end - this->value_) == len);
|
|
|
|
return ret * multiplier;
|
|
}
|
|
|
// This class handles lexing a file into a sequence of tokens.
|
// This class handles lexing a file into a sequence of tokens.
|
|
|
class Lex
|
class Lex
|
{
|
{
|
public:
|
public:
|
Line 472... |
Line 495... |
}
|
}
|
|
|
// For a number we accept 0x followed by hex digits, or any sequence
|
// For a number we accept 0x followed by hex digits, or any sequence
|
// of digits. The old linker accepts leading '$' for hex, and
|
// of digits. The old linker accepts leading '$' for hex, and
|
// trailing HXBOD. Those are for MRI compatibility and we don't
|
// trailing HXBOD. Those are for MRI compatibility and we don't
|
// accept them. The old linker also accepts trailing MK for mega or
|
// accept them.
|
// kilo. FIXME: Those are mentioned in the documentation, and we
|
|
// should accept them.
|
|
|
|
// Return whether C1 C2 C3 can start a hex number.
|
// Return whether C1 C2 C3 can start a hex number.
|
|
|
inline bool
|
inline bool
|
Lex::can_start_hex(char c1, char c2, char c3)
|
Lex::can_start_hex(char c1, char c2, char c3)
|
Line 701... |
Line 722... |
const char* start,
|
const char* start,
|
const char* match,
|
const char* match,
|
const char** pp)
|
const char** pp)
|
{
|
{
|
const char* new_match = NULL;
|
const char* new_match = NULL;
|
while ((new_match = (this->*can_continue_fn)(match)))
|
while ((new_match = (this->*can_continue_fn)(match)) != NULL)
|
match = new_match;
|
match = new_match;
|
|
|
|
// A special case: integers may be followed by a single M or K,
|
|
// case-insensitive.
|
|
if (classification == Token::TOKEN_INTEGER
|
|
&& (*match == 'm' || *match == 'M' || *match == 'k' || *match == 'K'))
|
|
++match;
|
|
|
*pp = match;
|
*pp = match;
|
return this->make_token(classification, start, match - start, start);
|
return this->make_token(classification, start, match - start, start);
|
}
|
}
|
|
|
// Build a token from a quoted string.
|
// Build a token from a quoted string.
|
Line 2802... |
Line 2830... |
const char* default_name, size_t default_length,
|
const char* default_name, size_t default_length,
|
const char*, size_t, const char*, size_t)
|
const char*, size_t, const char*, size_t)
|
{
|
{
|
Parser_closure* closure = static_cast<Parser_closure*>(closurev);
|
Parser_closure* closure = static_cast<Parser_closure*>(closurev);
|
std::string name(default_name, default_length);
|
std::string name(default_name, default_length);
|
Target* target = select_target_by_name(name.c_str());
|
Target* target = select_target_by_bfd_name(name.c_str());
|
if (target == NULL || !parameters->is_compatible_target(target))
|
if (target == NULL || !parameters->is_compatible_target(target))
|
{
|
{
|
if (closure->skip_on_incompatible_target())
|
if (closure->skip_on_incompatible_target())
|
{
|
{
|
closure->set_found_incompatible_target();
|
closure->set_found_incompatible_target();
|