[GOLD][PATCH] Support NOLOAD section type in scripts.
Doug Kwan (關振德)
dougkwan@google.com
Fri Apr 9 09:09:00 GMT 2010
Hi Ian,
This patch add support for NOLOAD section type in scripts, which
is used in the ARM compressed Linux kernel. The other section types
(COPY, DSECT, INFO and OVERLAY) are recognized but not supported yet.
-Doug
2010-04-09 Doug Kwan <dougkwan@google.com>
* layout.cc (Layout::choose_output_section): Handle script section
types.
(Layout::make_output_section_for_script): Add section type parameter.
Handle script section types.
* layout.h (Layout::make_output_section_for_script): Add section
type parameter.
* output.cc (Output_section::Output_section): Initialize data member
is_noload_.
(Output_section::do_reset_address_and_file_offset): Do not set address
to 0 if section is a NOLOAD section.
* output.h (Output_section::is_noload): New method.
(Output_section::set_is_noload): Ditto.
(Output_section::is_noload_): New data member.
* script-c.h (Script_section_type): New enum type.
(struct Parser_output_section_header): Add new file section_type.
* script-sections.cc (Sections_element::output_section_name): Add
parameter for returning script section type.
(Output_section_definition::output_section_name): Ditto.
(Output_section_definition::section_type)P; New method.
(Output_section_definiton::script_section_type_name): Ditto.
(Output_section_definition::script_section_type_): New data member.
(Output_section_definition::Output_section_definition): Initialize
data member Output_section_definition::script_section_type_.
(Output_section_definition::create_sections): Pass script section type
to Layout::make_output_section_for_script.
(Output_section_definition::output_section_name): Return script
section type to caller.
(Output_section_definition::set_section_address): Do not advance
dot value and load address if section type is NOLOAD. Set address
of NOLOAD sections regardless of section flags.
(Output_section_definition::print): Print section type if it is
not SCRIPT_SECTION_TYPE_NONE.
(Output_section_definition::section_type): New method.
(Output_section_definition::script_section_type_name): Ditto.
(Script_sections::output_section_name): Add new parameter
PSECTION_TYPE for returning script section type. Pass it to
section elements. Handle discard sections.
(Sort_output_sections::operator()): Handle NOLOAD sections.
* script-sections.h (Script_sections::Section_type): New enum type.
(Script_sections::output_section_name): Add a new parameter for
returning script section type.
* script.cc (script_keyword_parsecodes): Add keywords COPY, DSECT,
INFO and NOLOAD.
* yyscript.y (union): Add new field SECTION_TYPE.
(COPY, DSECT, INFO, NOLOAD): New tokens.
(opt_address_and_section_type): Change type to output_section_header.
(section_type): New non-terminal
(section_header): Handle section type.
(opt_address_and_section_type): Return section type value.
-------------- next part --------------
Index: gold/layout.cc
===================================================================
RCS file: /cvs/src/src/gold/layout.cc,v
retrieving revision 1.167
diff -u -u -p -r1.167 layout.cc
--- gold/layout.cc 1 Mar 2010 21:43:49 -0000 1.167
+++ gold/layout.cc 9 Apr 2010 09:07:31 -0000
@@ -502,13 +502,27 @@ Layout::choose_output_section(const Relo
Script_sections* ss = this->script_options_->script_sections();
const char* file_name = relobj == NULL ? NULL : relobj->name().c_str();
Output_section** output_section_slot;
- name = ss->output_section_name(file_name, name, &output_section_slot);
+ Script_sections::Section_type script_section_type;
+ name = ss->output_section_name(file_name, name, &output_section_slot,
+ &script_section_type);
if (name == NULL)
{
// The SECTIONS clause says to discard this input section.
return NULL;
}
+ // We can only handle script section types ST_NONE and ST_NOLOAD.
+ switch (script_section_type)
+ {
+ case Script_sections::ST_NONE:
+ break;
+ case Script_sections::ST_NOLOAD:
+ flags &= elfcpp::SHF_ALLOC;
+ break;
+ default:
+ gold_unreachable();
+ }
+
// If this is an orphan section--one not mentioned in the linker
// script--then OUTPUT_SECTION_SLOT will be NULL, and we do the
// default processing below.
@@ -533,6 +547,25 @@ Layout::choose_output_section(const Relo
is_dynamic_linker_section, is_relro,
is_last_relro, is_first_non_relro);
os->set_found_in_sections_clause();
+
+ // Special handling for NOLOAD sections.
+ if (script_section_type == Script_sections::ST_NOLOAD)
+ {
+ os->set_is_noload();
+
+ // The constructor of Output_section sets addresses of non-ALLOC
+ // sections to 0 by default. We don't want that for NOLOAD
+ // sections even if they have no SHF_ALLOC flag.
+ if ((os->flags() & elfcpp::SHF_ALLOC) == 0
+ && os->is_address_valid())
+ {
+ gold_assert(os->address() == 0
+ && !os->is_offset_valid()
+ && !os->is_data_size_valid());
+ os->reset_address_and_file_offset();
+ }
+ }
+
*output_section_slot = os;
return os;
}
@@ -1157,13 +1190,20 @@ Layout::attach_allocated_section_to_segm
// Make an output section for a script.
Output_section*
-Layout::make_output_section_for_script(const char* name)
+Layout::make_output_section_for_script(
+ const char* name,
+ Script_sections::Section_type section_type)
{
name = this->namepool_.add(name, false, NULL);
+ elfcpp::Elf_Xword sh_flags = elfcpp::SHF_ALLOC;
+ if (section_type == Script_sections::ST_NOLOAD)
+ sh_flags = 0;
Output_section* os = this->make_output_section(name, elfcpp::SHT_PROGBITS,
- elfcpp::SHF_ALLOC, false,
+ sh_flags, false,
false, false, false, false);
os->set_found_in_sections_clause();
+ if (section_type == Script_sections::ST_NOLOAD)
+ os->set_is_noload();
return os;
}
Index: gold/layout.h
===================================================================
RCS file: /cvs/src/src/gold/layout.h,v
retrieving revision 1.79
diff -u -u -p -r1.79 layout.h
--- gold/layout.h 9 Feb 2010 20:29:44 -0000 1.79
+++ gold/layout.h 9 Apr 2010 09:07:31 -0000
@@ -600,7 +600,8 @@ class Layout
// Make a section for a linker script to hold data.
Output_section*
- make_output_section_for_script(const char* name);
+ make_output_section_for_script(const char* name,
+ Script_sections::Section_type section_type);
// Make a segment. This is used by the linker script code.
Output_segment*
Index: gold/output.cc
===================================================================
RCS file: /cvs/src/src/gold/output.cc,v
retrieving revision 1.123
diff -u -u -p -r1.123 output.cc
--- gold/output.cc 9 Apr 2010 00:04:30 -0000 1.123
+++ gold/output.cc 9 Apr 2010 09:07:31 -0000
@@ -1911,6 +1911,7 @@ Output_section::Output_section(const cha
generate_code_fills_at_write_(false),
is_entsize_zero_(false),
section_offsets_need_adjustment_(false),
+ is_noload_(false),
tls_offset_(0),
checkpoint_(NULL),
merge_section_map_(),
@@ -2588,8 +2589,9 @@ Output_section::do_reset_address_and_fil
{
// An unallocated section has no address. Forcing this means that
// we don't need special treatment for symbols defined in debug
- // sections. We do the same in the constructor.
- if ((this->flags_ & elfcpp::SHF_ALLOC) == 0)
+ // sections. We do the same in the constructor. This does not
+ // apply to NOLOAD sections though.
+ if (((this->flags_ & elfcpp::SHF_ALLOC) == 0) && !this->is_noload_)
this->set_address(0);
for (Input_section_list::iterator p = this->input_sections_.begin();
Index: gold/output.h
===================================================================
RCS file: /cvs/src/src/gold/output.h,v
retrieving revision 1.102
diff -u -u -p -r1.102 output.h
--- gold/output.h 1 Mar 2010 21:43:50 -0000 1.102
+++ gold/output.h 9 Apr 2010 09:07:31 -0000
@@ -2894,6 +2894,16 @@ class Output_section : public Output_dat
void
adjust_section_offsets();
+ // Whether this is a NOLOAD section.
+ bool
+ is_noload() const
+ { return this->is_noload_; }
+
+ // Set NOLOAD flag.
+ void
+ set_is_noload()
+ { this->is_noload_ = true; }
+
// Print merge statistics to stderr.
void
print_merge_stats();
@@ -3659,6 +3669,8 @@ class Output_section : public Output_dat
bool is_entsize_zero_ : 1;
// Whether section offsets need adjustment due to relaxation.
bool section_offsets_need_adjustment_ : 1;
+ // Whether this is a NOLOAD section.
+ bool is_noload_ : 1;
// For SHT_TLS sections, the offset of this section relative to the base
// of the TLS segment.
uint64_t tls_offset_;
Index: gold/script-c.h
===================================================================
RCS file: /cvs/src/src/gold/script-c.h,v
retrieving revision 1.16
diff -u -u -p -r1.16 script-c.h
--- gold/script-c.h 16 Oct 2009 18:56:07 -0000 1.16
+++ gold/script-c.h 9 Apr 2010 09:07:31 -0000
@@ -61,6 +61,18 @@ typedef Expression* Expression_ptr;
typedef void* Expression_ptr;
#endif
+/* Script_section type. */
+enum Script_section_type
+{
+ /* No section type. */
+ SCRIPT_SECTION_TYPE_NONE,
+ SCRIPT_SECTION_TYPE_NOLOAD,
+ SCRIPT_SECTION_TYPE_DSECT,
+ SCRIPT_SECTION_TYPE_COPY,
+ SCRIPT_SECTION_TYPE_INFO,
+ SCRIPT_SECTION_TYPE_OVERLAY
+};
+
/* A constraint for whether to use a particular output section
definition. */
@@ -83,6 +95,8 @@ struct Parser_output_section_header
{
/* The address. This may be NULL. */
Expression_ptr address;
+ /* Section type. May be NULL string. */
+ enum Script_section_type section_type;
/* The load address, from the AT specifier. This may be NULL. */
Expression_ptr load_address;
/* The alignment, from the ALIGN specifier. This may be NULL. */
Index: gold/script-sections.cc
===================================================================
RCS file: /cvs/src/src/gold/script-sections.cc,v
retrieving revision 1.31
diff -u -u -p -r1.31 script-sections.cc
--- gold/script-sections.cc 23 Mar 2010 21:06:10 -0000 1.31
+++ gold/script-sections.cc 9 Apr 2010 09:07:31 -0000
@@ -356,7 +356,8 @@ class Sections_element
// section name. This only real implementation is in
// Output_section_definition.
virtual const char*
- output_section_name(const char*, const char*, Output_section***)
+ output_section_name(const char*, const char*, Output_section***,
+ Script_sections::Section_type*)
{ return NULL; }
// Initialize OSP with an output section.
@@ -1617,7 +1618,7 @@ class Output_section_definition : public
// section name.
const char*
output_section_name(const char* file_name, const char* section_name,
- Output_section***);
+ Output_section***, Script_sections::Section_type*);
// Initialize OSP with an output section.
void
@@ -1665,7 +1666,14 @@ class Output_section_definition : public
void
print(FILE*) const;
+ // Return the output section type if specified or Script_sections::ST_NONE.
+ Script_sections::Section_type
+ section_type() const;
+
private:
+ static const char*
+ script_section_type_name(Script_section_type);
+
typedef std::vector<Output_section_element*> Output_section_elements;
// The output section name.
@@ -1698,6 +1706,8 @@ class Output_section_definition : public
uint64_t evaluated_addralign_;
// The output section is relro.
bool is_relro_;
+ // The output section type if specified.
+ enum Script_section_type script_section_type_;
};
// Constructor.
@@ -1719,7 +1729,8 @@ Output_section_definition::Output_sectio
evaluated_address_(0),
evaluated_load_address_(0),
evaluated_addralign_(0),
- is_relro_(false)
+ is_relro_(false),
+ script_section_type_(header->section_type)
{
}
@@ -1815,7 +1826,8 @@ Output_section_definition::create_sectio
if ((*p)->needs_output_section())
{
const char* name = this->name_.c_str();
- this->output_section_ = layout->make_output_section_for_script(name);
+ this->output_section_ =
+ layout->make_output_section_for_script(name, this->section_type());
return;
}
}
@@ -1873,9 +1885,11 @@ Output_section_definition::finalize_symb
// Return the output section name to use for an input section name.
const char*
-Output_section_definition::output_section_name(const char* file_name,
- const char* section_name,
- Output_section*** slot)
+Output_section_definition::output_section_name(
+ const char* file_name,
+ const char* section_name,
+ Output_section*** slot,
+ Script_sections::Section_type *psection_type)
{
// Ask each element whether it matches NAME.
for (Output_section_elements::const_iterator p = this->elements_.begin();
@@ -1887,6 +1901,7 @@ Output_section_definition::output_sectio
// We found a match for NAME, which means that it should go
// into this output section.
*slot = &this->output_section_;
+ *psection_type = this->section_type();
return this->name_.c_str();
}
}
@@ -1906,6 +1921,9 @@ Output_section_definition::set_section_a
uint64_t* load_address)
{
uint64_t address;
+ uint64_t old_dot_value = *dot_value;
+ uint64_t old_load_address = *load_address;
+
if (this->address_ == NULL)
address = *dot_value;
else
@@ -1941,10 +1959,11 @@ Output_section_definition::set_section_a
*dot_value = address;
- // The address of non-SHF_ALLOC sections is forced to zero,
- // regardless of what the linker script wants.
+ // Except for NOLOAD sections, the address of non-SHF_ALLOC sections is
+ // forced to zero, regardless of what the linker script wants.
if (this->output_section_ != NULL
- && (this->output_section_->flags() & elfcpp::SHF_ALLOC) != 0)
+ && ((this->output_section_->flags() & elfcpp::SHF_ALLOC) != 0
+ || this->output_section_->is_noload()))
this->output_section_->set_address(address);
this->evaluated_address_ = address;
@@ -2029,6 +2048,13 @@ Output_section_definition::set_section_a
this->output_section_->set_is_relro();
else
this->output_section_->clear_is_relro();
+
+ // If this is a NOLOAD section, key dot and load address unchanged.
+ if (this->output_section_->is_noload())
+ {
+ *dot_value = old_dot_value;
+ *load_address = old_load_address;
+ }
}
}
@@ -2186,6 +2212,10 @@ Output_section_definition::print(FILE* f
fprintf(f, " ");
}
+ if (this->script_section_type_ != SCRIPT_SECTION_TYPE_NONE)
+ fprintf(f, "(%s) ",
+ this->script_section_type_name(this->script_section_type_));
+
fprintf(f, ": ");
if (this->load_address_ != NULL)
@@ -2235,6 +2265,52 @@ Output_section_definition::print(FILE* f
fprintf(f, "\n");
}
+Script_sections::Section_type
+Output_section_definition::section_type() const
+{
+ switch (this->script_section_type_)
+ {
+ case SCRIPT_SECTION_TYPE_NONE:
+ return Script_sections::ST_NONE;
+ case SCRIPT_SECTION_TYPE_NOLOAD:
+ return Script_sections::ST_NOLOAD;
+ case SCRIPT_SECTION_TYPE_COPY:
+ case SCRIPT_SECTION_TYPE_DSECT:
+ case SCRIPT_SECTION_TYPE_INFO:
+ case SCRIPT_SECTION_TYPE_OVERLAY:
+ // There are not really support so we treat them as ST_NONE. The
+ // parse should have issued errors for them already.
+ return Script_sections::ST_NONE;
+ default:
+ gold_unreachable();
+ }
+}
+
+// Return the name of a script section type.
+
+const char*
+Output_section_definition::script_section_type_name (
+ Script_section_type script_section_type)
+{
+ switch (script_section_type)
+ {
+ case SCRIPT_SECTION_TYPE_NONE:
+ return "NONE";
+ case SCRIPT_SECTION_TYPE_NOLOAD:
+ return "NOLOAD";
+ case SCRIPT_SECTION_TYPE_DSECT:
+ return "DSECT";
+ case SCRIPT_SECTION_TYPE_COPY:
+ return "COPY";
+ case SCRIPT_SECTION_TYPE_INFO:
+ return "INFO";
+ case SCRIPT_SECTION_TYPE_OVERLAY:
+ return "OVERLAY";
+ default:
+ gold_unreachable();
+ }
+}
+
// An output section created to hold orphaned input sections. These
// do not actually appear in linker scripts. However, for convenience
// when setting the output section addresses, we put a marker to these
@@ -2724,16 +2800,19 @@ Script_sections::finalize_symbols(Symbol
// and section name.
const char*
-Script_sections::output_section_name(const char* file_name,
- const char* section_name,
- Output_section*** output_section_slot)
+Script_sections::output_section_name(
+ const char* file_name,
+ const char* section_name,
+ Output_section*** output_section_slot,
+ Script_sections::Section_type *psection_type)
{
for (Sections_elements::const_iterator p = this->sections_elements_->begin();
p != this->sections_elements_->end();
++p)
{
const char* ret = (*p)->output_section_name(file_name, section_name,
- output_section_slot);
+ output_section_slot,
+ psection_type);
if (ret != NULL)
{
@@ -2742,6 +2821,7 @@ Script_sections::output_section_name(con
if (strcmp(ret, "/DISCARD/") == 0)
{
*output_section_slot = NULL;
+ *psection_type = Script_sections::ST_NONE;
return NULL;
}
return ret;
@@ -2752,6 +2832,7 @@ Script_sections::output_section_name(con
// gets the name of the input section.
*output_section_slot = NULL;
+ *psection_type = Script_sections::ST_NONE;
return section_name;
}
@@ -2967,6 +3048,12 @@ Sort_output_sections::operator()(const O
if (os1->type() == elfcpp::SHT_NOBITS && os2->type() == elfcpp::SHT_PROGBITS)
return false;
+ // Sort non-NOLOAD before NOLOAD.
+ if (os1->is_noload() && !os2->is_noload())
+ return true;
+ if (!os1->is_noload() && os2->is_noload())
+ return true;
+
// Otherwise we don't care.
return false;
}
Index: gold/script-sections.h
===================================================================
RCS file: /cvs/src/src/gold/script-sections.h,v
retrieving revision 1.10
diff -u -u -p -r1.10 script-sections.h
--- gold/script-sections.h 16 Oct 2009 18:56:07 -0000 1.10
+++ gold/script-sections.h 9 Apr 2010 09:07:31 -0000
@@ -52,6 +52,20 @@ class Script_sections
typedef std::list<Sections_element*> Sections_elements;
public:
+
+ // Logical script section types. We map section types returned by the
+ // parser into these since some section types have the same semantics.
+ enum Section_type
+ {
+ // No section type specified.
+ ST_NONE,
+ // Section is NOLOAD. We allocate space in the output but section
+ // is not loaded in runtime.
+ ST_NOLOAD,
+ // No space is allocated to section.
+ ST_NOALLOC
+ };
+
Script_sections();
// Start a SECTIONS clause.
@@ -147,9 +161,13 @@ class Script_sections
// 3) If the input section is not mapped by the SECTIONS clause,
// this returns SECTION_NAME, and sets *OUTPUT_SECTION_SLOT to
// NULL.
+ // PSCRIPT_SECTION_TYPE points to a location for returning the section
+ // type specified in script. This can be SCRIPT_SECTION_TYPE_NONE if
+ // no type is specified.
const char*
output_section_name(const char* file_name, const char* section_name,
- Output_section*** output_section_slot);
+ Output_section*** output_section_slot,
+ Section_type* pscript_section_type);
// Place a marker for an orphan output section into the SECTIONS
// clause.
Index: gold/script.cc
===================================================================
RCS file: /cvs/src/src/gold/script.cc,v
retrieving revision 1.69
diff -u -u -p -r1.69 script.cc
--- gold/script.cc 22 Mar 2010 14:18:24 -0000 1.69
+++ gold/script.cc 9 Apr 2010 09:07:31 -0000
@@ -1646,11 +1646,13 @@ script_keyword_parsecodes[] =
{ "BYTE", BYTE },
{ "CONSTANT", CONSTANT },
{ "CONSTRUCTORS", CONSTRUCTORS },
+ { "COPY", COPY },
{ "CREATE_OBJECT_SYMBOLS", CREATE_OBJECT_SYMBOLS },
{ "DATA_SEGMENT_ALIGN", DATA_SEGMENT_ALIGN },
{ "DATA_SEGMENT_END", DATA_SEGMENT_END },
{ "DATA_SEGMENT_RELRO_END", DATA_SEGMENT_RELRO_END },
{ "DEFINED", DEFINED },
+ { "DSECT", DSECT },
{ "ENTRY", ENTRY },
{ "EXCLUDE_FILE", EXCLUDE_FILE },
{ "EXTERN", EXTERN },
@@ -1660,6 +1662,7 @@ script_keyword_parsecodes[] =
{ "GROUP", GROUP },
{ "HLL", HLL },
{ "INCLUDE", INCLUDE },
+ { "INFO", INFO },
{ "INHIBIT_COMMON_ALLOCATION", INHIBIT_COMMON_ALLOCATION },
{ "INPUT", INPUT },
{ "KEEP", KEEP },
@@ -1673,6 +1676,7 @@ script_keyword_parsecodes[] =
{ "NEXT", NEXT },
{ "NOCROSSREFS", NOCROSSREFS },
{ "NOFLOAT", NOFLOAT },
+ { "NOLOAD", NOLOAD },
{ "ONLY_IF_RO", ONLY_IF_RO },
{ "ONLY_IF_RW", ONLY_IF_RW },
{ "OPTION", OPTION },
Index: gold/yyscript.y
===================================================================
RCS file: /cvs/src/src/gold/yyscript.y,v
retrieving revision 1.22
diff -u -u -p -r1.22 yyscript.y
--- gold/yyscript.y 16 Oct 2009 18:56:07 -0000 1.22
+++ gold/yyscript.y 9 Apr 2010 09:07:31 -0000
@@ -77,6 +77,7 @@
struct Version_dependency_list* deplist;
struct Version_expression_list* versyms;
struct Version_tree* versnode;
+ enum Script_section_type section_type;
}
/* Operators, including a precedence table for expressions. */
@@ -121,11 +122,13 @@
%token BYTE
%token CONSTANT
%token CONSTRUCTORS
+%token COPY
%token CREATE_OBJECT_SYMBOLS
%token DATA_SEGMENT_ALIGN
%token DATA_SEGMENT_END
%token DATA_SEGMENT_RELRO_END
%token DEFINED
+%token DSECT
%token ENTRY
%token EXCLUDE_FILE
%token EXTERN
@@ -137,6 +140,7 @@
%token HLL
%token INCLUDE
%token INHIBIT_COMMON_ALLOCATION
+%token INFO
%token INPUT
%token KEEP
%token LENGTH /* LENGTH, l, len */
@@ -150,6 +154,7 @@
%token NEXT
%token NOCROSSREFS
%token NOFLOAT
+%token NOLOAD
%token ONLY_IF_RO
%token ONLY_IF_RW
%token ORIGIN /* ORIGIN, o, org */
@@ -197,9 +202,10 @@
/* Non-terminal types, where needed. */
-%type <expr> parse_exp exp opt_address_and_section_type
+%type <expr> parse_exp exp
%type <expr> opt_at opt_align opt_subalign opt_fill
-%type <output_section_header> section_header
+%type <output_section_header> section_header opt_address_and_section_type
+%type <section_type> section_type
%type <output_section_trailer> section_trailer
%type <constraint> opt_constraint
%type <string_list> opt_phdr
@@ -343,7 +349,8 @@ section_header:
{ script_pop_lex_mode(closure); }
opt_constraint
{
- $$.address = $2;
+ $$.address = $2.address;
+ $$.section_type = $2.section_type;
$$.load_address = $3;
$$.align = $4;
$$.subalign = $5;
@@ -356,18 +363,61 @@ section_header:
'(' in section_header. */
opt_address_and_section_type:
- ':'
- { $$ = NULL; }
+ ':'
+ {
+ $$.address = NULL;
+ $$.section_type = SCRIPT_SECTION_TYPE_NONE;
+ }
| '(' ')' ':'
- { $$ = NULL; }
+ {
+ $$.address = NULL;
+ $$.section_type = SCRIPT_SECTION_TYPE_NONE;
+ }
| exp ':'
- { $$ = $1; }
+ {
+ $$.address = $1;
+ $$.section_type = SCRIPT_SECTION_TYPE_NONE;
+ }
| exp '(' ')' ':'
- { $$ = $1; }
- | exp '(' string ')' ':'
{
- yyerror(closure, "section types are not supported");
- $$ = $1;
+ $$.address = $1;
+ $$.section_type = SCRIPT_SECTION_TYPE_NONE;
+ }
+ | '(' section_type ')' ':'
+ {
+ $$.address = NULL;
+ $$.section_type = $2;
+ }
+ | exp '(' section_type ')' ':'
+ {
+ $$.address = $1;
+ $$.section_type = $3;
+ }
+ ;
+
+/* We only support NOLOAD. */
+section_type:
+ NOLOAD
+ { $$ = SCRIPT_SECTION_TYPE_NOLOAD; }
+ | DSECT
+ {
+ yyerror(closure, "DSECT section type is unsupported");
+ $$ = SCRIPT_SECTION_TYPE_DSECT;
+ }
+ | COPY
+ {
+ yyerror(closure, "COPY section type is unsupported");
+ $$ = SCRIPT_SECTION_TYPE_COPY;
+ }
+ | INFO
+ {
+ yyerror(closure, "INFO section type is unsupported");
+ $$ = SCRIPT_SECTION_TYPE_INFO;
+ }
+ | OVERLAY
+ {
+ yyerror(closure, "OVERLAY section type is unsupported");
+ $$ = SCRIPT_SECTION_TYPE_OVERLAY;
}
;
More information about the Binutils
mailing list