--- /dev/null
+// arm-reloc-property.cc -- ARM relocation property.
+
+// Copyright 2010 Free Software Foundation, Inc.
+// Written by Doug Kwan <dougkwan@google.com>.
+
+// This file is part of gold.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+#include "gold.h"
+
+#include <cstring>
+#include <stack>
+#include <string>
+#include <vector>
+
+#include "elfcpp.h"
+#include "arm.h"
+#include "arm-reloc-property.h"
+
+namespace gold
+{
+
+// Arm_reloc_property::Tree_node methods.
+
+// Parse an S-expression S and build a tree and return the root node.
+// Caller is responsible for releasing tree after use.
+
+Arm_reloc_property::Tree_node*
+Arm_reloc_property::Tree_node::make_tree(const std::string& s)
+{
+ std::stack<size_t> size_stack;
+ Tree_node_vector node_stack;
+
+ // strtok needs a non-const string pointer.
+ char* buffer = new char[s.size() + 1];
+ memcpy(buffer, s.data(), s.size());
+ buffer[s.size()] = '\0';
+ char* token = strtok(buffer, " ");
+
+ while (token != NULL)
+ {
+ if (strcmp(token, "(") == 0)
+ // Remember the node stack position for start of a new internal node.
+ size_stack.push(node_stack.size());
+ else if (strcmp(token, ")") == 0)
+ {
+ // Pop all tree nodes after the previous '(' and use them as
+ // children to build a new internal node. Push internal node back.
+ size_t current_size = node_stack.size();
+ size_t prev_size = size_stack.top();
+ size_stack.pop();
+ Tree_node* node =
+ new Tree_node(node_stack.begin() + prev_size,
+ node_stack.begin() + current_size);
+ node_stack.resize(prev_size);
+ node_stack.push_back(node);
+ }
+ else
+ // Just push a leaf node to node_stack.
+ node_stack.push_back(new Tree_node(token));
+
+ token = strtok(NULL, " ");
+ }
+
+ delete[] buffer;
+
+ // At this point, size_stack should be empty and node_stack should only
+ // contain the root node.
+ gold_assert(size_stack.empty() && node_stack.size() == 1);
+ return node_stack[0];
+}
+
+// Arm_reloc_property methods.
+
+// Constructor.
+
+Arm_reloc_property::Arm_reloc_property(
+ unsigned int code,
+ const char* name,
+ Reloc_type rtype,
+ bool is_deprecated,
+ Reloc_class rclass,
+ const std::string& operation,
+ bool is_implemented,
+ int group_index,
+ bool checks_overflow)
+ : code_(code), name_(name), reloc_type_(rtype), reloc_class_(rclass),
+ group_index_(group_index), size_(0), align_(1),
+ relative_address_base_(RAB_NONE), is_deprecated_(is_deprecated),
+ is_implemented_(is_implemented), checks_overflow_(checks_overflow),
+ uses_got_entry_(false), uses_got_origin_(false), uses_plt_entry_(false),
+ uses_thumb_bit_(false), uses_symbol_base_(false), uses_addend_(false)
+{
+ // Set size and alignment of static and dynamic relocations.
+ if (rtype == RT_STATIC)
+ {
+ switch (rclass)
+ {
+ case RC_DATA:
+ // Except for R_ARM_ABS16 and R_ARM_ABS8, all static data relocations
+ // have size 4. All static data relocations have alignment of 1.
+ if (code == elfcpp::R_ARM_ABS8)
+ this->size_ = 1;
+ else if (code == elfcpp::R_ARM_ABS16)
+ this->size_ = 2;
+ else
+ this->size_ = 4;
+ this->align_ = 1;
+ break;
+ case RC_MISC:
+ // R_ARM_V4BX should be treated as an ARM relocation. For all
+ // others, just use defaults.
+ if (code != elfcpp::R_ARM_V4BX)
+ break;
+ // Fall through.
+ case RC_ARM:
+ this->size_ = 4;
+ this->align_ = 4;
+ break;
+ case RC_THM16:
+ this->size_ = 2;
+ this->align_ = 2;
+ break;
+ case RC_THM32:
+ this->size_ = 4;
+ this->align_ = 2;
+ break;
+ default:
+ gold_unreachable();
+ }
+ }
+ else if (rtype == RT_DYNAMIC)
+ {
+ // With the exception of R_ARM_COPY, all dynamic relocations requires
+ // that the place being relocated is a word-aligned 32-bit object.
+ if (code != elfcpp::R_ARM_COPY)
+ {
+ this->size_ = 4;
+ this->align_ = 4;
+ }
+ }
+
+ // If no relocation operation is specified, we are done.
+ if (operation == "NONE")
+ return;
+
+ // Extract information from relocation operation.
+ Tree_node* root_node = Tree_node::make_tree(operation);
+ Tree_node* node = root_node;
+
+ // Check for an expression of the form XXX - YYY.
+ if (!node->is_leaf()
+ && node->child(0)->is_leaf()
+ && node->child(0)->name() == "-")
+ {
+ struct RAB_table_entry
+ {
+ Relative_address_base rab;
+ const char* name;
+ };
+
+ static const RAB_table_entry rab_table[] =
+ {
+ { RAB_B_S, "( B S )" },
+ { RAB_DELTA_B_S, "( DELTA_B ( S ) )" },
+ { RAB_GOT_ORG, "GOT_ORG" },
+ { RAB_P, "P" },
+ { RAB_Pa, "Pa" },
+ { RAB_TLS, "TLS" },
+ { RAB_tp, "tp" }
+ };
+
+ static size_t rab_table_size = sizeof(rab_table) / sizeof(rab_table[0]);
+ const std::string rhs(node->child(2)->s_expression());
+ for (size_t i = 0; i < rab_table_size; ++i)
+ if (rhs == rab_table[i].name)
+ {
+ this->relative_address_base_ = rab_table[i].rab;
+ break;
+ }
+
+ gold_assert(this->relative_address_base_ != RAB_NONE);
+ if (this->relative_address_base_ == RAB_B_S)
+ this->uses_symbol_base_ = true;
+ node = node->child(1);
+ }
+
+ // Check for an expression of the form XXX | T.
+ if (!node->is_leaf()
+ && node->child(0)->is_leaf()
+ && node->child(0)->name() == "|")
+ {
+ gold_assert(node->number_of_children() == 3
+ && node->child(2)->is_leaf()
+ && node->child(2)->name() == "T");
+ this->uses_thumb_bit_ = true;
+ node = node->child(1);
+ }
+
+ // Check for an expression of the form XXX + A.
+ if (!node->is_leaf()
+ && node->child(0)->is_leaf()
+ && node->child(0)->name() == "+")
+ {
+ gold_assert(node->number_of_children() == 3
+ && node->child(2)->is_leaf()
+ && node->child(2)->name() == "A");
+ this->uses_addend_ = true;
+ node = node->child(1);
+ }
+
+ // Check for an expression of the form XXX(S).
+ if (!node->is_leaf() && node->child(0)->is_leaf())
+ {
+ gold_assert(node->number_of_children() == 2
+ && node->child(1)->is_leaf()
+ && node->child(1)->name() == "S");
+ const std::string func(node->child(0)->name());
+ if (func == "B")
+ this->uses_symbol_base_ = true;
+ else if (func == "GOT")
+ this->uses_got_entry_ = true;
+ else if (func == "PLT")
+ this->uses_plt_entry_ = true;
+ else if (func == "Module" || func == "DELTA_B")
+ // These are used in dynamic relocations.
+ ;
+ else
+ gold_unreachable();
+ node = node->child(1);
+ }
+
+ gold_assert(node->is_leaf() && node->name() == "S");
+
+ delete root_node;
+}
+
+// Arm_reloc_property_table methods.
+
+// Constructor. This processing informations in arm-reloc.def to
+// initialize the table.
+
+Arm_reloc_property_table::Arm_reloc_property_table()
+{
+ // These appers in arm-reloc.def. Do not rename them.
+ Parse_expression A("A"), GOT_ORG("GOT_ORG"), NONE("NONE"), P("P"),
+ Pa("Pa"), S("S"), T("T"), TLS("TLS"), tp("tp");
+ const bool Y(true), N(false);
+
+ for (unsigned int i = 0; i < Property_table_size; ++i)
+ this->table_[i] = NULL;
+
+#undef RD
+#define RD(name, type, deprecated, class, operation, is_implemented, \
+ group_index, checks_oveflow) \
+ do \
+ { \
+ unsigned int code = elfcpp::R_ARM_##name; \
+ gold_assert(code < Property_table_size); \
+ this->table_[code] = \
+ new Arm_reloc_property(elfcpp::R_ARM_##name, "R_ARM_" #name, \
+ Arm_reloc_property::RT_##type, deprecated, \
+ Arm_reloc_property::RC_##class, \
+ (operation).s_expression(), is_implemented, \
+ group_index, checks_oveflow); \
+ } \
+ while(0);
+
+#include "arm-reloc.def"
+#undef RD
+}
+
+} // End namespace gold.
--- /dev/null
+// arm-reloc-property.h -- ARM relocation properties -*- C++ -*-
+
+// Copyright 2010 Free Software Foundation, Inc.
+// Written by Doug Kwan <dougkwan@google.com>.
+
+// This file is part of gold.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+#ifndef GOLD_ARM_RELOC_PROPERTY_H
+#define GOLD_ARM_RELOC_PROPERTY_H
+
+namespace gold
+{
+// The Arm_reloc_property class is to store information about a paticular
+// relocation code.
+
+class Arm_reloc_property
+{
+ public:
+ // Types of relocation codes.
+ enum Reloc_type {
+ RT_NONE, // No relocation type.
+ RT_STATIC, // Relocations processed by static linkers.
+ RT_DYNAMIC, // Relocations processed by dynamic linkers.
+ RT_PRIVATE, // Private relocations, not supported by gold.
+ RT_OBSOLETE // Obsolete relocations that should not be used.
+ };
+
+ // Classes of relocation codes.
+ enum Reloc_class {
+ RC_NONE, // No relocation class.
+ RC_DATA, // Data relocation.
+ RC_ARM, // ARM instruction relocation.
+ RC_THM16, // 16-bit THUMB instruction relocation.
+ RC_THM32, // 32-bit THUMB instruction relocation.
+ RC_MISC // Miscellaneous class.
+ };
+
+ // Types of bases of relative addressing relocation codes.
+ enum Relative_address_base {
+ RAB_NONE, // Relocation is not relative addressing
+ RAB_B_S, // Address origin of output segment of defining symbol.
+ RAB_DELTA_B_S, // Change of address origin.
+ RAB_GOT_ORG, // Origin of GOT.
+ RAB_P, // Address of the place being relocated.
+ RAB_Pa, // Adjusted address (P & 0xfffffffc).
+ RAB_TLS, // Thread local storage.
+ RAB_tp // Thread pointer.
+ };
+
+ // Relocation code represented by this.
+ unsigned int
+ code() const
+ { return this->code_; }
+
+ // Name of the relocation code.
+ const std::string&
+ name() const
+ { return this->name_; }
+
+ // Type of relocation code.
+ Reloc_type
+ reloc_type() const
+ { return this->reloc_type_; }
+
+ // Whether this code is deprecated.
+ bool
+ is_deprecated() const
+ { return this->is_deprecated_; }
+
+ // Class of relocation code.
+ Reloc_class
+ reloc_class() const
+ { return this->reloc_class_; }
+
+ // Whether this code is implemented in gold.
+ bool
+ is_implemented() const
+ { return this->is_implemented_; }
+
+ // If code is a group relocation code, return the group number, otherwise -1.
+ int
+ group_index() const
+ { return this->group_index_; }
+
+ // Whether relocation checks for overflow.
+ bool
+ checks_overflow() const
+ { return this->checks_overflow_; }
+
+ // Return size of relocation.
+ size_t
+ size() const
+ { return this->size_; }
+
+ // Return alignment of relocation.
+ size_t
+ align() const
+ { return this->align_; }
+
+ // Whether relocation use a GOT entry.
+ bool
+ uses_got_entry() const
+ { return this->uses_got_entry_; }
+
+ // Whether relocation use a GOT origin.
+ bool
+ uses_got_origin() const
+ { return this->uses_got_origin_; }
+
+ // Whether relocation uses the Thumb-bit in a symbol address.
+ bool
+ uses_thumb_bit() const
+ { return this->uses_thumb_bit_; }
+
+ // Whether relocation uses the symbol base.
+ bool
+ uses_symbol_base() const
+ { return this->uses_symbol_base_; }
+
+ // Return the type of relative address base or RAB_NONE if this
+ // is not a relative addressing relocation.
+ Relative_address_base
+ relative_address_base() const
+ { return this->relative_address_base_; }
+
+ protected:
+ // These are protected. We only allow Arm_reloc_property_table to
+ // manage Arm_reloc_property.
+ Arm_reloc_property(unsigned int code, const char* name, Reloc_type rtype,
+ bool is_deprecated, Reloc_class rclass,
+ const std::string& operation, bool is_implemented,
+ int group_index, bool checks_overflow);
+
+ friend class Arm_reloc_property_table;
+
+ private:
+ // Copying is not allowed.
+ Arm_reloc_property(const Arm_reloc_property&);
+ Arm_reloc_property& operator=(const Arm_reloc_property&);
+
+ // The Tree_node class is used to represent parsed relocation operations.
+ // We look at Trees to extract information about relocation operations.
+ class Tree_node
+ {
+ public:
+ typedef std::vector<Tree_node*> Tree_node_vector;
+
+ // Construct a leaf node.
+ Tree_node(const char* name)
+ : is_leaf_(true), name_(name), children_()
+ { }
+
+ // Construct an internal node. A node owns all its children and is
+ // responsible for releasing them at its own destruction.
+ Tree_node(Tree_node_vector::const_iterator begin,
+ Tree_node_vector::const_iterator end)
+ : is_leaf_(false), name_(), children_()
+ {
+ for (Tree_node_vector::const_iterator p = begin; p != end; ++p)
+ this->children_.push_back(*p);
+ }
+
+ ~Tree_node()
+ {
+ for(size_t i = 0; i <this->children_.size(); ++i)
+ delete this->children_[i];
+ }
+
+ // Whether this is a leaf node.
+ bool
+ is_leaf() const
+ { return this->is_leaf_; }
+
+ // Return name of this. This is only valid for a leaf node.
+ const std::string&
+ name() const
+ {
+ gold_assert(this->is_leaf_);
+ return this->name_;
+ }
+
+ // Return the number of children. This is only valid for a non-leaf node.
+ size_t
+ number_of_children() const
+ {
+ gold_assert(!this->is_leaf_);
+ return this->children_.size();
+ }
+
+ // Return the i-th child of this. This is only valid for a non-leaf node.
+ Tree_node*
+ child(size_t i) const
+ {
+ gold_assert(!this->is_leaf_ && i < this->children_.size());
+ return this->children_[i];
+ }
+
+ // Parse an S-expression string and build a tree and return the root node.
+ // Caller is responsible for releasing tree after use.
+ static Tree_node*
+ make_tree(const std::string&);
+
+ // Convert a tree back to an S-expression string.
+ std::string
+ s_expression() const
+ {
+ if (this->is_leaf_)
+ return this->name_;
+
+ // Concatenate S-expressions of children. Enclose them with
+ // a pair of parentheses and use space as token delimiters.
+ std::string s("(");
+ for(size_t i = 0; i <this->children_.size(); ++i)
+ s = s + " " + this->children_[i]->s_expression();
+ return s + " )";
+ }
+
+ private:
+ // Whether this is a leaf node.
+ bool is_leaf_;
+ // Name of this if this is a leaf node.
+ std::string name_;
+ // Children of this if this a non-leaf node.
+ Tree_node_vector children_;
+ };
+
+ // Relocation code.
+ unsigned int code_;
+ // Relocation name.
+ std::string name_;
+ // Type of relocation.
+ Reloc_type reloc_type_;
+ // Class of relocation.
+ Reloc_class reloc_class_;
+ // Group index (0, 1, or 2) if this is a group relocation or -1 otherwise.
+ int group_index_;
+ // Size of relocation.
+ size_t size_;
+ // Alignment of relocation.
+ size_t align_;
+ // Relative address base.
+ Relative_address_base relative_address_base_;
+ // Whether this is deprecated.
+ bool is_deprecated_ : 1;
+ // Whether this is implemented in gold.
+ bool is_implemented_ : 1;
+ // Whether this checks overflow.
+ bool checks_overflow_ : 1;
+ // Whether this uses a GOT entry.
+ bool uses_got_entry_ : 1;
+ // Whether this uses a GOT origin.
+ bool uses_got_origin_ : 1;
+ // Whether this uses a PLT entry.
+ bool uses_plt_entry_ : 1;
+ // Whether this uses the THUMB bit in symbol address.
+ bool uses_thumb_bit_ : 1;
+ // Whether this uses the symbol base.
+ bool uses_symbol_base_ : 1;
+ // Whether this uses an addend.
+ bool uses_addend_ : 1;
+};
+
+// Arm_reloc_property_table. This table is used for looking up propeties
+// of relocationt types. The table entries are initialized using information
+// from arm-reloc.def.
+
+class Arm_reloc_property_table
+{
+ public:
+ Arm_reloc_property_table();
+
+ // Return an Arm_reloc_property object for CODE if it is a valid relocation
+ // code or NULL otherwise.
+ const Arm_reloc_property*
+ get_reloc_property(unsigned int code) const
+ {
+ gold_assert(code < Property_table_size);
+ return this->table_[code];
+ }
+
+ private:
+ // Copying is not allowed.
+ Arm_reloc_property_table(const Arm_reloc_property_table&);
+ Arm_reloc_property_table& operator=(const Arm_reloc_property_table&);
+
+ // The Parse_expression class is used to convert relocation operations in
+ // arm-reloc.def into S-expression strings, which are parsed again to
+ // build actual expression trees. We do not build the expression trees
+ // directly because the parser for operations in arm-reloc.def is simpler
+ // this way. Coversion from S-expressions to trees is simple.
+ class Parse_expression
+ {
+ public:
+ // Construction a Parse_expression with an S-expression string.
+ Parse_expression(const std::string& s_expression)
+ : s_expression_(s_expression)
+ { }
+
+ // Value of this expression as an S-expression string.
+ const std::string&
+ s_expression() const
+ { return this->s_expression_; }
+
+ // We want to overload operators used in relocation operations so
+ // that we can execute operations in arm-reloc.def to generate
+ // S-expressions directly.
+#define DEF_OPERATOR_OVERLOAD(op) \
+ Parse_expression \
+ operator op (const Parse_expression& e) \
+ { \
+ return Parse_expression("( " #op " " + this->s_expression_ + " " + \
+ e.s_expression_ + " )"); \
+ }
+
+ // Operator appearing in relocation operations in arm-reloc.def.
+ DEF_OPERATOR_OVERLOAD(+)
+ DEF_OPERATOR_OVERLOAD(-)
+ DEF_OPERATOR_OVERLOAD(|)
+
+ private:
+ // This represented as an S-expression string.
+ std::string s_expression_;
+ };
+
+#define DEF_RELOC_FUNC(name) \
+ static Parse_expression \
+ (name)(const Parse_expression& arg) \
+ { return Parse_expression("( " #name " " + arg.s_expression() + " )"); }
+
+ // Functions appearing in relocation operations in arm-reloc.def.
+ DEF_RELOC_FUNC(B)
+ DEF_RELOC_FUNC(DELTA_B)
+ DEF_RELOC_FUNC(GOT)
+ DEF_RELOC_FUNC(Module)
+ DEF_RELOC_FUNC(PLT)
+
+ static const unsigned int Property_table_size = 256;
+
+ // The property table.
+ Arm_reloc_property* table_[Property_table_size];
+};
+
+} // End namespace gold.
+
+#endif // !defined(GOLD_ARM_RELOC_PROPERTY_H)
--- /dev/null
+// arm-reloc.def -- ARM relocation definitions.
+
+// Copyright 2010 Free Software Foundation, Inc.
+// Written by Doug Kwan <dougkwan@google.com>.
+
+// This file is part of gold.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+// The information here is based on the official ARM document "ELF for ARM
+// Architecture" (Document number ARM IHI 0044C). The first five columns of
+// the table below are derived from Table 4-8 in the ARM ELF document. Each
+// relocation from Table 4-8 corresponds to one relocation definition in the
+// table below. A relocation defintion has the following information:
+//
+// Name: This is the name of the relocation without the "R_ARM_" prefix.
+//
+// Type: Relocation type. There are four.
+// - STATIC for static relocations processed by a static linker.
+// - DYNAMIC for dynamic relocations processed by a dynamic linker.
+// - PRIVATE for R_ARM_PRIVATE_<n> private relocation type.
+// - OBSOLETE for old relocation types no longer used.
+// We do not use DEPRECATED as a distinct type since we still have to
+// handle deprecated relocations so we one of the types above.
+//
+// Deprecated: Whether this is a deprecated relocation type. The linker
+// is expected to handle these though they should not be generated by fully
+// conforming tool-chains.
+//
+// Operation: An expression specifying how the linker should performace a
+// relocation. If there is no operation or the operation cannot be
+// specified, it is "NONE".
+//
+// Implemented: Whether this is implemented by the gold.
+//
+// Group_index: For a group relocation type, it is one of 0, 1 or 2. For
+// a non-group relocation type, it is -1.
+//
+// Overflow: Whether gold should check for overflow. This is "No" by default
+// for relocation types DYNAMIC, PRIVATE and OBSOLETE.
+//
+// Overflow-----------------------------------------------------------------+
+// Group index----------------------------------------------------------+ |
+// Implemented-------------------------------------------------------+ | |
+// Operation-------------------------------+ | | |
+// Class----------------------------+ | | | |
+// Deprecated--------------------+ | | | | |
+// Type----------------+ | | | | | |
+// Name | | | | | | |
+// | | | | | | | |
+RD(NONE , STATIC , N, MISC , NONE , Y, -1, N)
+RD(PC24 , STATIC , Y, ARM , ((S + A) | T) - P , Y, -1, Y)
+RD(ABS32 , STATIC , N, DATA , (S + A) | T , Y, -1, N)
+RD(REL32 , STATIC , N, DATA , ((S + A) | T) - P , Y, -1, N)
+RD(LDR_PC_G0 , STATIC , N, ARM , S + A - P , Y, 0, Y)
+RD(ABS16 , STATIC , N, DATA , S + A , Y, -1, Y)
+RD(ABS12 , STATIC , N, ARM , S + A , Y, -1, Y)
+RD(THM_ABS5 , STATIC , N, THM16, S + A , Y, -1, Y)
+RD(ABS8 , STATIC , N, DATA , S + A , Y, -1, Y)
+RD(SBREL32 , STATIC , N, DATA , ((S + A) | T) - B(S) , N, -1, N)
+RD(THM_CALL , STATIC , N, THM32, ((S + A) | T) - P , Y, -1, Y)
+RD(THM_PC8 , STATIC , N, THM16, S + A - Pa , Y, -1, Y)
+RD(BREL_ADJ , DYNAMIC , N, DATA , DELTA_B(S) + A , Y, -1, N)
+RD(TLS_DESC , DYNAMIC , N, DATA , NONE , Y, -1, N)
+RD(THM_SWI8 , OBSOLETE, N, NONE , NONE , N, -1, N)
+RD(XPC25 , OBSOLETE, N, NONE , NONE , N, -1, N)
+RD(THM_XPC22 , OBSOLETE, N, NONE , NONE , N, -1, N)
+RD(TLS_DTPMOD32 , DYNAMIC , N, DATA , Module(S) , Y, -1, N)
+RD(TLS_DTPOFF32 , DYNAMIC , N, DATA , S + A - TLS , Y, -1, N)
+RD(TLS_TPOFF32 , DYNAMIC , N, DATA , S + A - tp , Y, -1, N)
+RD(COPY , DYNAMIC , N, MISC , NONE , Y, -1, N)
+RD(GLOB_DAT , DYNAMIC , N, DATA , (S + A) | T , Y, -1, N)
+RD(JUMP_SLOT , DYNAMIC , N, DATA , (S + A) | T , Y, -1, N)
+RD(RELATIVE , DYNAMIC , N, DATA , B(S) + A , Y, -1, N)
+RD(GOTOFF32 , STATIC , N, DATA , ((S + A) | T) - GOT_ORG, Y, -1, N)
+RD(BASE_PREL , STATIC , N, DATA , B(S) + A - P , Y, -1, N)
+RD(GOT_BREL , STATIC , N, DATA , GOT(S) + A - GOT_ORG , Y, -1, N)
+RD(PLT32 , STATIC , Y, ARM , ((S + A) | T) - P , Y, -1, Y)
+RD(CALL , STATIC , N, ARM , ((S + A) | T) - P , Y, -1, Y)
+RD(JUMP24 , STATIC , N, ARM , ((S + A) | T) - P , Y, -1, Y)
+RD(THM_JUMP24 , STATIC , N, THM32, ((S + A) | T) - P , Y, -1, Y)
+RD(BASE_ABS , STATIC , N, DATA , B(S) + A , Y, -1, N)
+RD(ALU_PCREL_7_0 , OBSOLETE, N, NONE , NONE , N, -1, N)
+RD(ALU_PCREL_15_8 , OBSOLETE, N, NONE , NONE , N, -1, N)
+RD(ALU_PCREL_23_15 , OBSOLETE, N, NONE , NONE , N, -1, N)
+RD(LDR_SBREL_11_0_NC , STATIC , Y, ARM , S + A - B(S) , N, -1, N)
+RD(ALU_SBREL_19_12_NC, STATIC , Y, ARM , S + A - B(S) , N, -1, N)
+RD(ALU_SBREL_27_20_CK, STATIC , Y, ARM , S + A - B(S) , N, -1, Y)
+RD(TARGET1 , STATIC , N, MISC , NONE , Y, -1, N)
+RD(SBREL31 , STATIC , Y, DATA , ((S + A) | T) - B(S) , N, -1, N)
+RD(V4BX , STATIC , N, MISC , NONE , Y, -1, N)
+RD(TARGET2 , STATIC , N, MISC , NONE , Y, -1, N)
+RD(PREL31 , STATIC , N, DATA , ((S + A) | T) - P , Y, -1, Y)
+RD(MOVW_ABS_NC , STATIC , N, ARM , (S + A) | T , Y, -1, N)
+RD(MOVT_ABS , STATIC , N, ARM , S + A , Y, -1, Y)
+RD(MOVW_PREL_NC , STATIC , N, ARM , ((S + A) | T) - P , Y, -1, N)
+RD(MOVT_PREL , STATIC , N, ARM , (S + A) - P , Y, -1, Y)
+RD(THM_MOVW_ABS_NC , STATIC , N, THM32, (S + A) | T , Y, -1, N)
+RD(THM_MOVT_ABS , STATIC , N, THM32, S + A , Y, -1, Y)
+RD(THM_MOVW_PREL_NC , STATIC , N, THM32, ((S + A) | T) - P , Y, -1, N)
+RD(THM_MOVT_PREL , STATIC , N, THM32, S + A - P , Y, -1, Y)
+RD(THM_JUMP19 , STATIC , N, THM32, ((S + A) | T) - P , Y, -1, Y)
+RD(THM_JUMP6 , STATIC , N, THM16, S + A - P , Y, -1, Y)
+RD(THM_ALU_PREL_11_0 , STATIC , N, THM32, ((S + A) | T) - Pa , Y, -1, Y)
+RD(THM_PC12 , STATIC , N, THM32, S + A - Pa , Y, -1, Y)
+RD(ABS32_NOI , STATIC , N, DATA , S + A , Y, -1, N)
+RD(REL32_NOI , STATIC , N, DATA , S + A - P , N, -1, N)
+RD(ALU_PC_G0_NC , STATIC , N, ARM , ((S + A) | T) - P , Y, 0, N)
+RD(ALU_PC_G0 , STATIC , N, ARM , ((S + A) | T) - P , Y, 0, Y)
+RD(ALU_PC_G1_NC , STATIC , N, ARM , ((S + A) | T) - P , Y, 1, N)
+RD(ALU_PC_G1 , STATIC , N, ARM , ((S + A) | T) - P , Y, 1, Y)
+RD(ALU_PC_G2 , STATIC , N, ARM , ((S + A) | T) - P , Y, 2, Y)
+RD(LDR_PC_G1 , STATIC , N, ARM , S + A - P , Y, 1, Y)
+RD(LDR_PC_G2 , STATIC , N, ARM , S + A - P , Y, 2, Y)
+RD(LDRS_PC_G0 , STATIC , N, ARM , S + A - P , Y, 0, Y)
+RD(LDRS_PC_G1 , STATIC , N, ARM , S + A - P , Y, 1, Y)
+RD(LDRS_PC_G2 , STATIC , N, ARM , S + A - P , Y, 2, Y)
+RD(LDC_PC_G0 , STATIC , N, ARM , S + A - P , Y, 0, Y)
+RD(LDC_PC_G1 , STATIC , N, ARM , S + A - P , Y, 1, Y)
+RD(LDC_PC_G2 , STATIC , N, ARM , S + A - P , Y, 2, Y)
+RD(ALU_SB_G0_NC , STATIC , N, ARM , ((S + A) | T) - B(S) , Y, 0, N)
+RD(ALU_SB_G0 , STATIC , N, ARM , ((S + A) | T) - B(S) , Y, 0, Y)
+RD(ALU_SB_G1_NC , STATIC , N, ARM , ((S + A) | T) - B(S) , Y, 1, N)
+RD(ALU_SB_G1 , STATIC , N, ARM , ((S + A) | T) - B(S) , Y, 1, Y)
+RD(ALU_SB_G2 , STATIC , N, ARM , ((S + A) | T) - B(S) , Y, 2, Y)
+RD(LDR_SB_G0 , STATIC , N, ARM , S + A - B(S) , Y, 0, Y)
+RD(LDR_SB_G1 , STATIC , N, ARM , S + A - B(S) , Y, 1, Y)
+RD(LDR_SB_G2 , STATIC , N, ARM , S + A - B(S) , Y, 2, Y)
+RD(LDRS_SB_G0 , STATIC , N, ARM , S + A - B(S) , Y, 0, Y)
+RD(LDRS_SB_G1 , STATIC , N, ARM , S + A - B(S) , Y, 1, Y)
+RD(LDRS_SB_G2 , STATIC , N, ARM , S + A - B(S) , Y, 2, Y)
+RD(LDC_SB_G0 , STATIC , N, ARM , S + A - B(S) , Y, 0, Y)
+RD(LDC_SB_G1 , STATIC , N, ARM , S + A - B(S) , Y, 1, Y)
+RD(LDC_SB_G2 , STATIC , N, ARM , S + A - B(S) , Y, 2, Y)
+RD(MOVW_BREL_NC , STATIC , N, ARM , ((S + A) | T) - B(S) , Y, -1, N)
+RD(MOVT_BREL , STATIC , N, ARM , S + A - B(S) , Y, -1, Y)
+RD(MOVW_BREL , STATIC , N, ARM , ((S + A) | T) - B(S) , Y, -1, Y)
+RD(THM_MOVW_BREL_NC , STATIC , N, THM32, ((S + A) | T) - B(S) , Y, -1, N)
+RD(THM_MOVT_BREL , STATIC , N, THM32, S + A - B(S) , Y, -1, Y)
+RD(THM_MOVW_BREL , STATIC , N, THM32, ((S + A) | T) - B(S) , Y, -1, Y)
+RD(TLS_GOTDESC , STATIC , N, DATA , NONE , Y, -1, N)
+RD(TLS_CALL , STATIC , N, ARM , NONE , N, -1, Y)
+RD(TLS_DESCSEQ , STATIC , N, ARM , NONE , N, -1, Y)
+RD(THM_TLS_CALL , STATIC , N, THM32, NONE , N, -1, Y)
+RD(PLT32_ABS , STATIC , N, DATA , PLT(S) + A , N, -1, N)
+RD(GOT_ABS , STATIC , N, DATA , GOT(S) + A , N, -1, N)
+RD(GOT_PREL , STATIC , N, DATA , GOT(S) + A - P , N, -1, N)
+RD(GOT_BREL12 , STATIC , N, ARM , GOT(S) + A - GOT_ORG , N, -1, Y)
+RD(GOTOFF12 , STATIC , N, ARM , S + A - GOT_ORG , N, -1, Y)
+RD(GOTRELAX , STATIC , N, MISC , NONE , N, -1, N)
+RD(GNU_VTENTRY , STATIC , Y, DATA , NONE , Y, -1, N)
+RD(GNU_VTINHERIT , STATIC , Y, DATA , NONE , Y, -1, N)
+RD(THM_JUMP11 , STATIC , N, THM16, S + A - P , Y, -1, Y)
+RD(THM_JUMP8 , STATIC , N, THM16, S + A - P , Y, -1, Y)
+RD(TLS_GD32 , STATIC , N, DATA , GOT(S) + A - P , N, -1, N)
+RD(TLS_LDM32 , STATIC , N, DATA , GOT(S) + A - P , N, -1, N)
+RD(TLS_LDO32 , STATIC , N, DATA , S + A - TLS , N, -1, N)
+RD(TLS_IE32 , STATIC , N, DATA , GOT(S) + A - P , N, -1, N)
+RD(TLS_LE32 , STATIC , N, DATA , S + A - tp , N, -1, N)
+RD(TLS_LDO12 , STATIC , N, ARM , S + A - TLS , N, -1, Y)
+RD(TLS_LE12 , STATIC , N, ARM , S + A - tp , N, -1, Y)
+RD(TLS_IE12GP , STATIC , N, ARM , GOT(S) + A - GOT_ORG , N, -1, Y)
+RD(PRIVATE_0 , PRIVATE , N, NONE , NONE , N, -1, N)
+RD(PRIVATE_1 , PRIVATE , N, NONE , NONE , N, -1, N)
+RD(PRIVATE_2 , PRIVATE , N, NONE , NONE , N, -1, N)
+RD(PRIVATE_3 , PRIVATE , N, NONE , NONE , N, -1, N)
+RD(PRIVATE_4 , PRIVATE , N, NONE , NONE , N, -1, N)
+RD(PRIVATE_5 , PRIVATE , N, NONE , NONE , N, -1, N)
+RD(PRIVATE_6 , PRIVATE , N, NONE , NONE , N, -1, N)
+RD(PRIVATE_7 , PRIVATE , N, NONE , NONE , N, -1, N)
+RD(PRIVATE_8 , PRIVATE , N, NONE , NONE , N, -1, N)
+RD(PRIVATE_9 , PRIVATE , N, NONE , NONE , N, -1, N)
+RD(PRIVATE_10 , PRIVATE , N, NONE , NONE , N, -1, N)
+RD(PRIVATE_11 , PRIVATE , N, NONE , NONE , N, -1, N)
+RD(PRIVATE_12 , PRIVATE , N, NONE , NONE , N, -1, N)
+RD(PRIVATE_13 , PRIVATE , N, NONE , NONE , N, -1, N)
+RD(PRIVATE_14 , PRIVATE , N, NONE , NONE , N, -1, N)
+RD(PRIVATE_15 , PRIVATE , N, NONE , NONE , N, -1, N)
+RD(ME_TOO , OBSOLETE, N, NONE , NONE , N, -1, N)
+RD(THM_TLS_DESCSEQ16 , STATIC , N, THM16, NONE , N, -1, Y)
+RD(THM_TLS_DESCSEQ32 , STATIC , N, THM32, NONE , N, -1, Y)