From Craig Silverstein: implement -z max-page-size and -z
common-page-size.
This commit is contained in:
parent
45aa233bdc
commit
cd72c29180
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue