From Craig Silverstein: implement -z max-page-size and -z

common-page-size.
This commit is contained in:
Ian Lance Taylor 2008-02-26 22:10:32 +00:00
parent 45aa233bdc
commit cd72c29180
7 changed files with 117 additions and 19 deletions

View File

@ -366,8 +366,8 @@ const Target::Target_info Target_i386::i386_info =
true, // is_default_stack_executable
"/usr/lib/libc.so.1", // dynamic_linker
0x08048000, // default_text_segment_address
0x1000, // abi_pagesize
0x1000 // common_pagesize
0x1000, // abi_pagesize (overridable by -z max-page-size)
0x1000 // common_pagesize (overridable by -z common-page-size)
};
// Get the GOT section, creating it if necessary.

View File

@ -109,8 +109,13 @@ struct options::One_z_option
// The name of the option.
const char* name;
// The member function in General_options called to record it.
void (General_options::*set)(bool);
// The member function in General_options called to record an option
// which does not take an argument.
void (General_options::*set_noarg)(bool);
// The member function in General_options called to record an option
// which does take an argument.
void (General_options::*set_arg)(const char*);
};
// We have a separate table for --debug options.
@ -593,7 +598,9 @@ options::Command_line_options::options[] =
GENERAL_ARG('z', NULL,
N_("Subcommands as follows:\n\
-z execstack Mark output as requiring executable stack\n\
-z noexecstack Mark output as not requiring executable stack"),
-z noexecstack Mark output as not requiring executable stack\n\
-z max-page-size=SIZE Set maximum page size to SIZE\n\
-z common-page-size=SIZE Set common page size to SIZE"),
N_("-z SUBCOMMAND"), ONE_DASH,
&General_options::handle_z_option),
@ -618,8 +625,10 @@ const int options::Command_line_options::options_size =
const options::One_z_option
options::Command_line_options::z_options[] =
{
{ "execstack", &General_options::set_execstack },
{ "noexecstack", &General_options::set_noexecstack },
{ "execstack", &General_options::set_execstack, NULL },
{ "noexecstack", &General_options::set_noexecstack, NULL },
{ "max-page-size", NULL, &General_options::set_max_page_size },
{ "common-page-size", NULL, &General_options::set_common_page_size }
};
const int options::Command_line_options::z_options_size =
@ -670,6 +679,8 @@ General_options::General_options(Script_options* script_options)
thread_count_middle_(0),
thread_count_final_(0),
execstack_(EXECSTACK_FROM_INPUT),
max_page_size_(0),
common_page_size_(0),
debug_(0),
script_options_(script_options)
{
@ -731,21 +742,42 @@ General_options::default_target() const
void
General_options::handle_z_option(const char* arg)
{
// ARG may be a word, like "noexec", or it may be an option in its
// own right, like "max-page-size=SIZE".
const char* argarg = strchr(arg, '='); // the argument to the -z argument
int arglen;
if (argarg)
{
arglen = argarg - arg;
argarg++;
}
else
arglen = strlen(arg);
const int z_options_size = options::Command_line_options::z_options_size;
const gold::options::One_z_option* z_options =
gold::options::Command_line_options::z_options;
for (int i = 0; i < z_options_size; ++i)
{
if (strcmp(arg, z_options[i].name) == 0)
if (memcmp(arg, z_options[i].name, arglen) == 0
&& z_options[i].name[arglen] == '\0')
{
(this->*(z_options[i].set))(true);
return;
}
if (z_options[i].set_noarg && argarg)
gold::gold_fatal(_("-z subcommand does not take an argument: %s\n"),
z_options[i].name);
else if (z_options[i].set_arg && !argarg)
gold::gold_fatal(_("-z subcommand requires an argument: %s\n"),
z_options[i].name);
else if (z_options[i].set_arg)
(this->*(z_options[i].set_arg))(argarg);
else
(this->*(z_options[i].set_noarg))(true);
return;
}
}
fprintf(stderr, _("%s: unrecognized -z subcommand: %s\n"),
program_name, arg);
::exit(EXIT_FAILURE);
gold::gold_fatal(_("%s: unrecognized -z subcommand: %s\n"),
program_name, arg);
}
// Handle the --debug option.

View File

@ -319,6 +319,16 @@ class General_options
is_stack_executable() const
{ return this->execstack_ == EXECSTACK_YES; }
// -z max-page-size
uint64_t
max_page_size() const
{ return this->max_page_size_; }
// -z common-page-size
uint64_t
common_page_size() const
{ return this->common_page_size_; }
// --debug
unsigned int
debug() const
@ -576,6 +586,24 @@ class General_options
set_noexecstack(bool)
{ this->execstack_ = EXECSTACK_NO; }
void
set_max_page_size(const char* arg)
{
char* endptr;
this->max_page_size_ = strtoull(arg, &endptr, 0);
if (*endptr != '\0' || this->max_page_size_ == 0)
gold_fatal(_("invalid max-page-size: %s"), arg);
}
void
set_common_page_size(const char* arg)
{
char* endptr;
this->common_page_size_ = strtoull(arg, &endptr, 0);
if (*endptr != '\0' || this->common_page_size_ == 0)
gold_fatal(_("invalid common-page-size: %s"), arg);
}
void
set_debug(unsigned int flags)
{ this->debug_ = flags; }
@ -622,6 +650,8 @@ class General_options
int thread_count_middle_;
int thread_count_final_;
Execstack execstack_;
uint64_t max_page_size_;
uint64_t common_page_size_;
unsigned int debug_;
// Some options can also be set from linker scripts. Those are
// stored here.

View File

@ -38,7 +38,8 @@ Parameters::Parameters(Errors* errors)
symbolic_(false), demangle_(false), detect_odr_violations_(false),
optimization_level_(0), export_dynamic_(false), debug_(0),
is_doing_static_link_valid_(false), doing_static_link_(false),
is_target_valid_(false), target_(NULL)
is_target_valid_(false), target_(NULL), size_(0), is_big_endian_(false),
max_page_size_(0), common_page_size_(0)
{
}
@ -74,6 +75,9 @@ Parameters::set_from_options(const General_options* options)
else
this->strip_ = STRIP_NONE;
this->max_page_size_ = options->max_page_size();
this->common_page_size_ = options->common_page_size();
this->options_valid_ = true;
}

View File

@ -230,6 +230,22 @@ class Parameters
return this->is_big_endian_;
}
// The maximum page size
uint64_t
max_page_size() const
{
gold_assert(this->is_target_valid_);
return this->max_page_size_;
}
// The common page size
uint64_t
common_page_size() const
{
gold_assert(this->is_target_valid_);
return this->common_page_size_;
}
// Set values recorded from options.
void
set_from_options(const General_options*);
@ -313,6 +329,9 @@ class Parameters
int size_;
// Whether the output file is big endian.
bool is_big_endian_;
// The maximum page size and common page size
int max_page_size_;
int common_page_size_;
};
// This is a global variable.

View File

@ -34,6 +34,7 @@
#define GOLD_TARGET_H
#include "elfcpp.h"
#include "parameters.h"
namespace gold
{
@ -103,12 +104,24 @@ class Target
// Return the ABI specified page size.
uint64_t
abi_pagesize() const
{ return this->pti_->abi_pagesize; }
{
if (parameters->max_page_size() > 0)
return parameters->max_page_size();
else
return this->pti_->abi_pagesize;
}
// Return the common page size used on actual systems.
uint64_t
common_pagesize() const
{ return this->pti_->common_pagesize; }
{
if (parameters->common_page_size() > 0)
return std::min(parameters->common_page_size(),
this->abi_pagesize());
else
return std::min(this->pti_->common_pagesize,
this->abi_pagesize());
}
// If we see some object files with .note.GNU-stack sections, and
// some objects files without them, this returns whether we should

View File

@ -360,8 +360,8 @@ const Target::Target_info Target_x86_64::x86_64_info =
true, // is_default_stack_executable
"/lib/ld64.so.1", // program interpreter
0x400000, // default_text_segment_address
0x1000, // abi_pagesize
0x1000 // common_pagesize
0x1000, // abi_pagesize (overridable by -z max-page-size)
0x1000 // common_pagesize (overridable by -z common-page-size)
};
// Get the GOT section, creating it if necessary.