diff options
author | Nick Clifton <nickc@redhat.com> | 2010-09-08 16:10:33 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2010-09-08 16:10:33 +0000 |
commit | 7f8cd8440375de26ebca766ab281c34522262b53 (patch) | |
tree | ada43984d6bc35a3487c093cb6b1c5b1a988527b /gold/script.cc | |
parent | ab3e2b4a1c329818752fe855215d81fe21f88a8b (diff) | |
download | gdb-7f8cd8440375de26ebca766ab281c34522262b53.zip gdb-7f8cd8440375de26ebca766ab281c34522262b53.tar.gz gdb-7f8cd8440375de26ebca766ab281c34522262b53.tar.bz2 |
* README: Remove claim that MEMORY is not supported.
* expression.cc (script_exp_function_origin)
(script_exp_function_length): Move from here to ...
* script.cc: ... here.
(script_set_section_region, script_add_memory)
(script_parse_memory_attr, script_include_directive): New
functions.
* script-sections.cc
(class Memory_region): New class.
(class Output_section_definition): Add set_memory_region,
set_section_vma, set_section_lma and get_section_name methods.
(class Script_Sections): Add add_memory_region,
find_memory_region, find_memory_region_origin,
find_memory_region_length and set_memory_region methods.
Have set_section_addresses method walk the list of set memory
regions.
Extend the print methos to display memory regions.
* script-sections.h: Add prototypes for new methods.
Add enum for MEMORY region attributes.
* yyscript.y: Add support for parsing MEMORY regions.
* script-c.h: Add prototypes for new functions.
* testsuite/Makefile.am: Add test of MEMORY region functionality.
* testsuite/Makefile.in: Regenerate.
* testsuite/memory_test.sh: New script.
* testsuite/memory_test.s: New assembler source file.
* testsuite/memory_test.t: New linker script.
Diffstat (limited to 'gold/script.cc')
-rw-r--r-- | gold/script.cc | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/gold/script.cc b/gold/script.cc index d5983f6..300b19b 100644 --- a/gold/script.cc +++ b/gold/script.cc @@ -3220,3 +3220,122 @@ script_saw_segment_start_expression(void* closurev) Script_sections* ss = closure->script_options()->script_sections(); ss->set_saw_segment_start_expression(true); } + +extern "C" void +script_set_section_region(void* closurev, const char* name, size_t namelen, + int set_vma) +{ + Parser_closure* closure = static_cast<Parser_closure*>(closurev); + if (!closure->script_options()->saw_sections_clause()) + { + gold_error(_("%s:%d:%d: MEMORY region '%.*s' referred to outside of " + "SECTIONS clause"), + closure->filename(), closure->lineno(), closure->charpos(), + namelen, name); + return; + } + + Script_sections* ss = closure->script_options()->script_sections(); + Memory_region* mr = ss->find_memory_region(name, namelen); + if (mr == NULL) + { + gold_error(_("%s:%d:%d: MEMORY region '%.*s' not declared"), + closure->filename(), closure->lineno(), closure->charpos(), + namelen, name); + return; + } + + ss->set_memory_region(mr, set_vma); +} + +extern "C" void +script_add_memory(void* closurev, const char* name, size_t namelen, + unsigned int attrs, Expression* origin, Expression* length) +{ + Parser_closure* closure = static_cast<Parser_closure*>(closurev); + Script_sections* ss = closure->script_options()->script_sections(); + ss->add_memory_region(name, namelen, attrs, origin, length); +} + +extern "C" unsigned int +script_parse_memory_attr(void* closurev, const char* attrs, size_t attrlen, + int invert) +{ + int attributes = 0; + + while (attrlen--) + switch (*attrs++) + { + case 'R': + case 'r': + attributes |= MEM_READABLE; break; + case 'W': + case 'w': + attributes |= MEM_READABLE | MEM_WRITEABLE; break; + case 'X': + case 'x': + attributes |= MEM_EXECUTABLE; break; + case 'A': + case 'a': + attributes |= MEM_ALLOCATABLE; break; + case 'I': + case 'i': + case 'L': + case 'l': + attributes |= MEM_INITIALIZED; break; + default: + yyerror(closurev, _("unknown MEMORY attribute")); + } + + if (invert) + attributes = (~ attributes) & MEM_ATTR_MASK; + + return attributes; +} + +extern "C" void +script_include_directive(void* closurev, const char*, size_t) +{ + // FIXME: Implement ? + yyerror (closurev, _("GOLD does not currently support INCLUDE directives")); +} + +// Functions for memory regions. + +extern "C" Expression* +script_exp_function_origin(void* closurev, const char* name, size_t namelen) +{ + Parser_closure* closure = static_cast<Parser_closure*>(closurev); + Script_sections* ss = closure->script_options()->script_sections(); + Expression* origin = ss->find_memory_region_origin(name, namelen); + + if (origin == NULL) + { + gold_error(_("undefined memory region '%s' referenced " + "in ORIGIN expression"), + name); + // Create a dummy expression to prevent crashes later on. + origin = script_exp_integer(0); + } + + return origin; +} + +extern "C" Expression* +script_exp_function_length(void* closurev, const char* name, size_t namelen) +{ + Parser_closure* closure = static_cast<Parser_closure*>(closurev); + Script_sections* ss = closure->script_options()->script_sections(); + Expression* length = ss->find_memory_region_length(name, namelen); + + if (length == NULL) + { + gold_error(_("undefined memory region '%s' referenced " + "in LENGTH expression"), + name); + // Create a dummy expression to prevent crashes later on. + length = script_exp_integer(0); + } + + return length; +} |