common-page-size.
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.
// 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.
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),
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 =
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)
{
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.
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
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; }
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.
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)
{
}
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;
}
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*);
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.
#define GOLD_TARGET_H
#include "elfcpp.h"
+#include "parameters.h"
namespace gold
{
// 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
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.