1*fae548d3Szrj // attributes.h -- object attributes for gold   -*- C++ -*-
2*fae548d3Szrj 
3*fae548d3Szrj // Copyright (C) 2009-2020 Free Software Foundation, Inc.
4*fae548d3Szrj // Written by Doug Kwan <dougkwan@google.com>.
5*fae548d3Szrj // This file contains code adapted from BFD.
6*fae548d3Szrj 
7*fae548d3Szrj // This file is part of gold.
8*fae548d3Szrj 
9*fae548d3Szrj // This program is free software; you can redistribute it and/or modify
10*fae548d3Szrj // it under the terms of the GNU General Public License as published by
11*fae548d3Szrj // the Free Software Foundation; either version 3 of the License, or
12*fae548d3Szrj // (at your option) any later version.
13*fae548d3Szrj 
14*fae548d3Szrj // This program is distributed in the hope that it will be useful,
15*fae548d3Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
16*fae548d3Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17*fae548d3Szrj // GNU General Public License for more details.
18*fae548d3Szrj 
19*fae548d3Szrj // You should have received a copy of the GNU General Public License
20*fae548d3Szrj // along with this program; if not, write to the Free Software
21*fae548d3Szrj // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22*fae548d3Szrj // MA 02110-1301, USA.
23*fae548d3Szrj 
24*fae548d3Szrj // Handle object attributes.
25*fae548d3Szrj 
26*fae548d3Szrj #ifndef GOLD_ATTRIBUTES_H
27*fae548d3Szrj #define GOLD_ATTRIBUTES_H
28*fae548d3Szrj 
29*fae548d3Szrj #include <map>
30*fae548d3Szrj 
31*fae548d3Szrj #include "parameters.h"
32*fae548d3Szrj #include "target.h"
33*fae548d3Szrj #include "output.h"
34*fae548d3Szrj #include "reduced_debug_output.h"
35*fae548d3Szrj 
36*fae548d3Szrj namespace gold
37*fae548d3Szrj {
38*fae548d3Szrj 
39*fae548d3Szrj // Object attribute values.  The attribute tag is not stored in this object.
40*fae548d3Szrj 
41*fae548d3Szrj class Object_attribute
42*fae548d3Szrj {
43*fae548d3Szrj  public:
44*fae548d3Szrj   // The value of an object attribute.  The type indicates whether the
45*fae548d3Szrj   // attribute holds and integer, a string, or both.  It can also indicate that
46*fae548d3Szrj   // there can be no default (i.e. all values must be written to file, even
47*fae548d3Szrj   // zero).
48*fae548d3Szrj   enum
49*fae548d3Szrj   {
50*fae548d3Szrj     ATTR_TYPE_FLAG_INT_VAL = (1 << 0),
51*fae548d3Szrj     ATTR_TYPE_FLAG_STR_VAL = (1 << 1),
52*fae548d3Szrj     ATTR_TYPE_FLAG_NO_DEFAULT = (1 << 2)
53*fae548d3Szrj   };
54*fae548d3Szrj 
55*fae548d3Szrj   // Object attributes may either be defined by the processor ABI, index
56*fae548d3Szrj   // OBJ_ATTR_PROC in the *_obj_attributes arrays, or be GNU-specific
57*fae548d3Szrj   // (and possibly also processor-specific), index OBJ_ATTR_GNU.
58*fae548d3Szrj   enum
59*fae548d3Szrj   {
60*fae548d3Szrj     OBJ_ATTR_PROC,
61*fae548d3Szrj     OBJ_ATTR_GNU,
62*fae548d3Szrj     OBJ_ATTR_FIRST = OBJ_ATTR_PROC,
63*fae548d3Szrj     OBJ_ATTR_LAST = OBJ_ATTR_GNU
64*fae548d3Szrj   };
65*fae548d3Szrj 
66*fae548d3Szrj   // The following object attribute tags are taken as generic, for all
67*fae548d3Szrj   // targets and for "gnu" where there is no target standard.
68*fae548d3Szrj   enum
69*fae548d3Szrj   {
70*fae548d3Szrj     Tag_NULL = 0,
71*fae548d3Szrj     Tag_File = 1,
72*fae548d3Szrj     Tag_Section = 2,
73*fae548d3Szrj     Tag_Symbol = 3,
74*fae548d3Szrj     Tag_compatibility = 32
75*fae548d3Szrj   };
76*fae548d3Szrj 
Object_attribute()77*fae548d3Szrj   Object_attribute()
78*fae548d3Szrj    : type_(0), int_value_(0), string_value_()
79*fae548d3Szrj   { }
80*fae548d3Szrj 
81*fae548d3Szrj   // Copying constructor.  We need to implement this to copy the string value.
Object_attribute(const Object_attribute & oa)82*fae548d3Szrj   Object_attribute(const Object_attribute& oa)
83*fae548d3Szrj    : type_(oa.type_), int_value_(oa.int_value_), string_value_(oa.string_value_)
84*fae548d3Szrj   { }
85*fae548d3Szrj 
~Object_attribute()86*fae548d3Szrj   ~Object_attribute()
87*fae548d3Szrj   { }
88*fae548d3Szrj 
89*fae548d3Szrj   // Assignment operator.  We need to implement this to copy the string value.
90*fae548d3Szrj   Object_attribute&
91*fae548d3Szrj   operator=(const Object_attribute& source)
92*fae548d3Szrj   {
93*fae548d3Szrj     this->type_ = source.type_;
94*fae548d3Szrj     this->int_value_ = source.int_value_;
95*fae548d3Szrj     this->string_value_ = source.string_value_;
96*fae548d3Szrj     return *this;
97*fae548d3Szrj   }
98*fae548d3Szrj 
99*fae548d3Szrj   // Return attribute type.
100*fae548d3Szrj   int
type()101*fae548d3Szrj   type() const
102*fae548d3Szrj   { return this->type_; }
103*fae548d3Szrj 
104*fae548d3Szrj   // Set attribute type.
105*fae548d3Szrj   void
set_type(int type)106*fae548d3Szrj   set_type(int type)
107*fae548d3Szrj   { this->type_ = type; }
108*fae548d3Szrj 
109*fae548d3Szrj   // Return integer value.
110*fae548d3Szrj   unsigned int
int_value()111*fae548d3Szrj   int_value() const
112*fae548d3Szrj   { return this->int_value_; }
113*fae548d3Szrj 
114*fae548d3Szrj   // Set integer value.
115*fae548d3Szrj   void
set_int_value(unsigned int i)116*fae548d3Szrj   set_int_value(unsigned int i)
117*fae548d3Szrj   { this->int_value_ = i; }
118*fae548d3Szrj 
119*fae548d3Szrj   // Return string value.
120*fae548d3Szrj   const std::string&
string_value()121*fae548d3Szrj   string_value() const
122*fae548d3Szrj   { return this->string_value_; }
123*fae548d3Szrj 
124*fae548d3Szrj   // Set string value.
125*fae548d3Szrj   void
set_string_value(const std::string & s)126*fae548d3Szrj   set_string_value(const std::string& s)
127*fae548d3Szrj   { this->string_value_ = s; }
128*fae548d3Szrj 
129*fae548d3Szrj   void
set_string_value(const char * s)130*fae548d3Szrj   set_string_value(const char* s)
131*fae548d3Szrj   { this->string_value_ = s; }
132*fae548d3Szrj 
133*fae548d3Szrj   // Whether attribute type has integer value.
134*fae548d3Szrj   static bool
attribute_type_has_int_value(int type)135*fae548d3Szrj   attribute_type_has_int_value(int type)
136*fae548d3Szrj   { return (type & ATTR_TYPE_FLAG_INT_VAL) != 0; }
137*fae548d3Szrj 
138*fae548d3Szrj   // Whether attribute type has string value.
139*fae548d3Szrj   static bool
attribute_type_has_string_value(int type)140*fae548d3Szrj   attribute_type_has_string_value(int type)
141*fae548d3Szrj   { return (type & ATTR_TYPE_FLAG_STR_VAL) != 0; }
142*fae548d3Szrj 
143*fae548d3Szrj   // Whether attribute type has no default value.
144*fae548d3Szrj   static bool
attribute_type_has_no_default(int type)145*fae548d3Szrj   attribute_type_has_no_default(int type)
146*fae548d3Szrj   { return (type & ATTR_TYPE_FLAG_NO_DEFAULT) != 0; }
147*fae548d3Szrj 
148*fae548d3Szrj   // Whether this has default value (0/"").
149*fae548d3Szrj   bool
150*fae548d3Szrj   is_default_attribute() const;
151*fae548d3Szrj 
152*fae548d3Szrj   // Return ULEB128 encoded size of tag and attribute.
153*fae548d3Szrj   size_t
154*fae548d3Szrj   size(int tag) const;
155*fae548d3Szrj 
156*fae548d3Szrj   // Whether this matches another object attribute in merging.
157*fae548d3Szrj   bool
158*fae548d3Szrj   matches(const Object_attribute& oa) const;
159*fae548d3Szrj 
160*fae548d3Szrj   // Write to attribute with tag to BUFFER.
161*fae548d3Szrj   void
162*fae548d3Szrj   write(int tag, std::vector<unsigned char>* buffer) const;
163*fae548d3Szrj 
164*fae548d3Szrj   // Determine what arguments an attribute tag takes.
165*fae548d3Szrj   static int
arg_type(int vendor,int tag)166*fae548d3Szrj   arg_type(int vendor, int tag)
167*fae548d3Szrj   {
168*fae548d3Szrj     switch (vendor)
169*fae548d3Szrj       {
170*fae548d3Szrj       case OBJ_ATTR_PROC:
171*fae548d3Szrj 	return parameters->target().attribute_arg_type(tag);
172*fae548d3Szrj       case OBJ_ATTR_GNU:
173*fae548d3Szrj 	return Object_attribute::gnu_arg_type(tag);
174*fae548d3Szrj       default:
175*fae548d3Szrj 	gold_unreachable();
176*fae548d3Szrj      }
177*fae548d3Szrj   }
178*fae548d3Szrj 
179*fae548d3Szrj  private:
180*fae548d3Szrj   // Determine whether a GNU object attribute tag takes an integer, a
181*fae548d3Szrj   // string or both.  */
182*fae548d3Szrj   static int
gnu_arg_type(int tag)183*fae548d3Szrj   gnu_arg_type(int tag)
184*fae548d3Szrj   {
185*fae548d3Szrj     // Except for Tag_compatibility, for GNU attributes we follow the
186*fae548d3Szrj     // same rule ARM ones > 32 follow: odd-numbered tags take strings
187*fae548d3Szrj     // and even-numbered tags take integers.  In addition, tag & 2 is
188*fae548d3Szrj     // nonzero for architecture-independent tags and zero for
189*fae548d3Szrj     // architecture-dependent ones.
190*fae548d3Szrj     if (tag == Object_attribute::Tag_compatibility)
191*fae548d3Szrj       return ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL;
192*fae548d3Szrj     else
193*fae548d3Szrj       return (tag & 1) != 0 ? ATTR_TYPE_FLAG_STR_VAL : ATTR_TYPE_FLAG_INT_VAL;
194*fae548d3Szrj   }
195*fae548d3Szrj 
196*fae548d3Szrj   // Attribute type.
197*fae548d3Szrj   int type_;
198*fae548d3Szrj   // Integer value.
199*fae548d3Szrj   int int_value_;
200*fae548d3Szrj   // String value.
201*fae548d3Szrj   std::string string_value_;
202*fae548d3Szrj };
203*fae548d3Szrj 
204*fae548d3Szrj // This class contains attributes of a particular vendor.
205*fae548d3Szrj 
206*fae548d3Szrj class Vendor_object_attributes
207*fae548d3Szrj {
208*fae548d3Szrj  public:
209*fae548d3Szrj   // The maximum number of known object attributes for any target.
210*fae548d3Szrj   static const int NUM_KNOWN_ATTRIBUTES = 71;
211*fae548d3Szrj 
Vendor_object_attributes(int vendor)212*fae548d3Szrj   Vendor_object_attributes(int vendor)
213*fae548d3Szrj     : vendor_(vendor), other_attributes_()
214*fae548d3Szrj   { }
215*fae548d3Szrj 
216*fae548d3Szrj   // Copying constructor.
217*fae548d3Szrj   Vendor_object_attributes(const Vendor_object_attributes&);
218*fae548d3Szrj 
~Vendor_object_attributes()219*fae548d3Szrj   ~Vendor_object_attributes()
220*fae548d3Szrj   {
221*fae548d3Szrj     for (Other_attributes::iterator p = this->other_attributes_.begin();
222*fae548d3Szrj 	 p != this->other_attributes_.end();
223*fae548d3Szrj 	 ++p)
224*fae548d3Szrj       delete p->second;
225*fae548d3Szrj   }
226*fae548d3Szrj 
227*fae548d3Szrj   // Size of this in number of bytes.
228*fae548d3Szrj   size_t
229*fae548d3Szrj   size() const;
230*fae548d3Szrj 
231*fae548d3Szrj   // Name of this written vendor subsection.
232*fae548d3Szrj   const char*
name()233*fae548d3Szrj   name() const
234*fae548d3Szrj   {
235*fae548d3Szrj     return (this->vendor_ == Object_attribute::OBJ_ATTR_PROC
236*fae548d3Szrj 	    ? parameters->target().attributes_vendor()
237*fae548d3Szrj 	    : "gnu");
238*fae548d3Szrj   }
239*fae548d3Szrj 
240*fae548d3Szrj   // Return an array of known attributes.
241*fae548d3Szrj   Object_attribute*
known_attributes()242*fae548d3Szrj   known_attributes()
243*fae548d3Szrj   { return &this->known_attributes_[0]; }
244*fae548d3Szrj 
245*fae548d3Szrj   const Object_attribute*
known_attributes()246*fae548d3Szrj   known_attributes() const
247*fae548d3Szrj   { return &this->known_attributes_[0]; }
248*fae548d3Szrj 
249*fae548d3Szrj   typedef std::map<int, Object_attribute*> Other_attributes;
250*fae548d3Szrj 
251*fae548d3Szrj   // Return attributes other than the known ones.
252*fae548d3Szrj   Other_attributes*
other_attributes()253*fae548d3Szrj   other_attributes()
254*fae548d3Szrj   { return &this->other_attributes_; }
255*fae548d3Szrj 
256*fae548d3Szrj   const Other_attributes*
other_attributes()257*fae548d3Szrj   other_attributes() const
258*fae548d3Szrj   { return &this->other_attributes_; }
259*fae548d3Szrj 
260*fae548d3Szrj   // Return a new attribute associated with TAG.
261*fae548d3Szrj   Object_attribute*
262*fae548d3Szrj   new_attribute(int tag);
263*fae548d3Szrj 
264*fae548d3Szrj   // Get an attribute
265*fae548d3Szrj   Object_attribute*
266*fae548d3Szrj   get_attribute(int tag);
267*fae548d3Szrj 
268*fae548d3Szrj   const Object_attribute*
269*fae548d3Szrj   get_attribute(int tag) const;
270*fae548d3Szrj 
271*fae548d3Szrj   // Write to BUFFER.
272*fae548d3Szrj   void
273*fae548d3Szrj   write(std::vector<unsigned char>* buffer) const;
274*fae548d3Szrj 
275*fae548d3Szrj  private:
276*fae548d3Szrj   // Vendor of the object attributes.
277*fae548d3Szrj   int vendor_;
278*fae548d3Szrj   // Attributes with known tags.  There are store in an array for fast
279*fae548d3Szrj   // access.
280*fae548d3Szrj   Object_attribute known_attributes_[NUM_KNOWN_ATTRIBUTES];
281*fae548d3Szrj   // Attributes with known tags.  There are stored in a sorted container.
282*fae548d3Szrj   Other_attributes other_attributes_;
283*fae548d3Szrj };
284*fae548d3Szrj 
285*fae548d3Szrj // This class contains contents of an attributes section.
286*fae548d3Szrj 
287*fae548d3Szrj class Attributes_section_data
288*fae548d3Szrj {
289*fae548d3Szrj  public:
290*fae548d3Szrj   // Construct an Attributes_section_data object by parsing section contents
291*fae548d3Szrj   // in VIEW of SIZE.
292*fae548d3Szrj   Attributes_section_data(const unsigned char* view, section_size_type size);
293*fae548d3Szrj 
294*fae548d3Szrj   // Copying constructor.
Attributes_section_data(const Attributes_section_data & asd)295*fae548d3Szrj   Attributes_section_data(const Attributes_section_data& asd)
296*fae548d3Szrj   {
297*fae548d3Szrj     for (int vendor = Object_attribute::OBJ_ATTR_FIRST;
298*fae548d3Szrj 	 vendor <= Object_attribute::OBJ_ATTR_LAST;
299*fae548d3Szrj 	 ++vendor)
300*fae548d3Szrj       this->vendor_object_attributes_[vendor] =
301*fae548d3Szrj 	new Vendor_object_attributes(*asd.vendor_object_attributes_[vendor]);
302*fae548d3Szrj   }
303*fae548d3Szrj 
~Attributes_section_data()304*fae548d3Szrj   ~Attributes_section_data()
305*fae548d3Szrj   {
306*fae548d3Szrj     for (int vendor = Object_attribute::OBJ_ATTR_FIRST;
307*fae548d3Szrj 	 vendor <= Object_attribute::OBJ_ATTR_LAST;
308*fae548d3Szrj 	 ++vendor)
309*fae548d3Szrj       delete this->vendor_object_attributes_[vendor];
310*fae548d3Szrj   }
311*fae548d3Szrj 
312*fae548d3Szrj   // Return the size of this as number of bytes.
313*fae548d3Szrj   size_t
314*fae548d3Szrj   size() const;
315*fae548d3Szrj 
316*fae548d3Szrj   // Return an array of known attributes.
317*fae548d3Szrj   Object_attribute*
known_attributes(int vendor)318*fae548d3Szrj   known_attributes(int vendor)
319*fae548d3Szrj   {
320*fae548d3Szrj     gold_assert(vendor >= OBJ_ATTR_FIRST && vendor <= OBJ_ATTR_LAST);
321*fae548d3Szrj     return this->vendor_object_attributes_[vendor]->known_attributes();
322*fae548d3Szrj   }
323*fae548d3Szrj 
324*fae548d3Szrj   const Object_attribute*
known_attributes(int vendor)325*fae548d3Szrj   known_attributes(int vendor) const
326*fae548d3Szrj   {
327*fae548d3Szrj     gold_assert(vendor >= OBJ_ATTR_FIRST && vendor <= OBJ_ATTR_LAST);
328*fae548d3Szrj     return this->vendor_object_attributes_[vendor]->known_attributes();
329*fae548d3Szrj   }
330*fae548d3Szrj 
331*fae548d3Szrj   // Return the other attributes.
332*fae548d3Szrj   Vendor_object_attributes::Other_attributes*
other_attributes(int vendor)333*fae548d3Szrj   other_attributes(int vendor)
334*fae548d3Szrj   {
335*fae548d3Szrj     gold_assert(vendor >= OBJ_ATTR_FIRST && vendor <= OBJ_ATTR_LAST);
336*fae548d3Szrj     return this->vendor_object_attributes_[vendor]->other_attributes();
337*fae548d3Szrj   }
338*fae548d3Szrj 
339*fae548d3Szrj   // Return the other attributes.
340*fae548d3Szrj   const Vendor_object_attributes::Other_attributes*
other_attributes(int vendor)341*fae548d3Szrj   other_attributes(int vendor) const
342*fae548d3Szrj   {
343*fae548d3Szrj     gold_assert(vendor >= OBJ_ATTR_FIRST && vendor <= OBJ_ATTR_LAST);
344*fae548d3Szrj     return this->vendor_object_attributes_[vendor]->other_attributes();
345*fae548d3Szrj   }
346*fae548d3Szrj 
347*fae548d3Szrj   // Return an attribute.
348*fae548d3Szrj   Object_attribute*
get_attribute(int vendor,int tag)349*fae548d3Szrj   get_attribute(int vendor, int tag)
350*fae548d3Szrj   {
351*fae548d3Szrj     gold_assert(vendor >= OBJ_ATTR_FIRST && vendor <= OBJ_ATTR_LAST);
352*fae548d3Szrj     return this->vendor_object_attributes_[vendor]->get_attribute(tag);
353*fae548d3Szrj   }
354*fae548d3Szrj 
355*fae548d3Szrj   const Object_attribute*
get_attribute(int vendor,int tag)356*fae548d3Szrj   get_attribute(int vendor, int tag) const
357*fae548d3Szrj   {
358*fae548d3Szrj     gold_assert(vendor >= OBJ_ATTR_FIRST && vendor <= OBJ_ATTR_LAST);
359*fae548d3Szrj     return this->vendor_object_attributes_[vendor]->get_attribute(tag);
360*fae548d3Szrj   }
361*fae548d3Szrj 
362*fae548d3Szrj   // Merge target-independent attributes from another Attributes_section_data
363*fae548d3Szrj   // of an object called NAME.
364*fae548d3Szrj   void
365*fae548d3Szrj   merge(const char* name, const Attributes_section_data* pasd);
366*fae548d3Szrj 
367*fae548d3Szrj   // Write to byte stream in an unsigned char vector.
368*fae548d3Szrj   void
369*fae548d3Szrj   write(std::vector<unsigned char>*) const;
370*fae548d3Szrj 
371*fae548d3Szrj  private:
372*fae548d3Szrj   // For convenience.
373*fae548d3Szrj   static const int OBJ_ATTR_FIRST = Object_attribute::OBJ_ATTR_FIRST;
374*fae548d3Szrj   static const int OBJ_ATTR_LAST = Object_attribute::OBJ_ATTR_LAST;
375*fae548d3Szrj 
376*fae548d3Szrj   // Vendor object attributes.
377*fae548d3Szrj   Vendor_object_attributes* vendor_object_attributes_[OBJ_ATTR_LAST+1];
378*fae548d3Szrj };
379*fae548d3Szrj 
380*fae548d3Szrj // This class is used for writing out an Attribute_section_data.
381*fae548d3Szrj 
382*fae548d3Szrj class Output_attributes_section_data : public Output_section_data
383*fae548d3Szrj {
384*fae548d3Szrj  public:
Output_attributes_section_data(const Attributes_section_data & asd)385*fae548d3Szrj   Output_attributes_section_data(const Attributes_section_data& asd)
386*fae548d3Szrj     : Output_section_data(1), attributes_section_data_(asd)
387*fae548d3Szrj   { }
388*fae548d3Szrj 
389*fae548d3Szrj  protected:
390*fae548d3Szrj   // Write to a map file.
391*fae548d3Szrj   void
do_print_to_mapfile(Mapfile * mapfile)392*fae548d3Szrj   do_print_to_mapfile(Mapfile* mapfile) const
393*fae548d3Szrj   { mapfile->print_output_data(this, _("** attributes")); }
394*fae548d3Szrj 
395*fae548d3Szrj   // Write the data to the output file.
396*fae548d3Szrj   void
397*fae548d3Szrj   do_write(Output_file*);
398*fae548d3Szrj 
399*fae548d3Szrj   // Set final data size.
400*fae548d3Szrj   void
set_final_data_size()401*fae548d3Szrj   set_final_data_size()
402*fae548d3Szrj   { this->set_data_size(attributes_section_data_.size()); }
403*fae548d3Szrj 
404*fae548d3Szrj  private:
405*fae548d3Szrj   // Attributes_section_data corresponding to this.
406*fae548d3Szrj   const Attributes_section_data& attributes_section_data_;
407*fae548d3Szrj };
408*fae548d3Szrj 
409*fae548d3Szrj } // End namespace gold.
410*fae548d3Szrj 
411*fae548d3Szrj #endif	// !defined(GOLD_ATTRIBUTES_H)
412