1*fae548d3Szrj // attributes.cc -- object attributes for gold
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 #include "gold.h"
25*fae548d3Szrj 
26*fae548d3Szrj #include <limits>
27*fae548d3Szrj 
28*fae548d3Szrj #include "attributes.h"
29*fae548d3Szrj #include "elfcpp.h"
30*fae548d3Szrj #include "target.h"
31*fae548d3Szrj #include "parameters.h"
32*fae548d3Szrj #include "int_encoding.h"
33*fae548d3Szrj 
34*fae548d3Szrj namespace gold
35*fae548d3Szrj {
36*fae548d3Szrj 
37*fae548d3Szrj // Object_attribute methods.
38*fae548d3Szrj 
39*fae548d3Szrj // Return size of attribute encode in ULEB128.
40*fae548d3Szrj 
41*fae548d3Szrj size_t
size(int tag) const42*fae548d3Szrj Object_attribute::size(int tag) const
43*fae548d3Szrj {
44*fae548d3Szrj   // Attributes with default values are not written out.
45*fae548d3Szrj   if (this->is_default_attribute())
46*fae548d3Szrj     return 0;
47*fae548d3Szrj 
48*fae548d3Szrj   size_t size = get_length_as_unsigned_LEB_128(tag);
49*fae548d3Szrj   if (Object_attribute::attribute_type_has_int_value(this->type_))
50*fae548d3Szrj     size += get_length_as_unsigned_LEB_128(this->int_value_);
51*fae548d3Szrj   if (Object_attribute::attribute_type_has_string_value(this->type_))
52*fae548d3Szrj     size += this->string_value_.size() + 1;
53*fae548d3Szrj   return size;
54*fae548d3Szrj }
55*fae548d3Szrj 
56*fae548d3Szrj // Whether this has the default value (0/"").
57*fae548d3Szrj 
58*fae548d3Szrj bool
is_default_attribute() const59*fae548d3Szrj Object_attribute::is_default_attribute() const
60*fae548d3Szrj {
61*fae548d3Szrj   if (Object_attribute::attribute_type_has_int_value(this->type_)
62*fae548d3Szrj       && this->int_value_ != 0)
63*fae548d3Szrj     return false;
64*fae548d3Szrj   if (Object_attribute::attribute_type_has_string_value(this->type_)
65*fae548d3Szrj       && !this->string_value_.empty())
66*fae548d3Szrj     return false;
67*fae548d3Szrj   if (Object_attribute::attribute_type_has_no_default(this->type_))
68*fae548d3Szrj     return false;
69*fae548d3Szrj 
70*fae548d3Szrj   return true;
71*fae548d3Szrj }
72*fae548d3Szrj 
73*fae548d3Szrj // Whether this matches another Object_attribute OA in merging.
74*fae548d3Szrj // Two Object_attributes match if they have the same values.
75*fae548d3Szrj 
76*fae548d3Szrj bool
matches(const Object_attribute & oa) const77*fae548d3Szrj Object_attribute::matches(const Object_attribute& oa) const
78*fae548d3Szrj {
79*fae548d3Szrj   return ((this->int_value_ != oa.int_value_)
80*fae548d3Szrj 	  && (this->string_value_ == oa.string_value_));
81*fae548d3Szrj }
82*fae548d3Szrj 
83*fae548d3Szrj // Write this with TAG to a BUFFER.
84*fae548d3Szrj 
85*fae548d3Szrj void
write(int tag,std::vector<unsigned char> * buffer) const86*fae548d3Szrj Object_attribute::write(
87*fae548d3Szrj     int tag,
88*fae548d3Szrj     std::vector<unsigned char>* buffer) const
89*fae548d3Szrj {
90*fae548d3Szrj   // No need to write default attributes.
91*fae548d3Szrj   if (this->is_default_attribute())
92*fae548d3Szrj     return;
93*fae548d3Szrj 
94*fae548d3Szrj   // Write tag.
95*fae548d3Szrj   write_unsigned_LEB_128(buffer, convert_types<uint64_t, int>(tag));
96*fae548d3Szrj 
97*fae548d3Szrj   // Write integer value.
98*fae548d3Szrj   if (Object_attribute::attribute_type_has_int_value(this->type_))
99*fae548d3Szrj     write_unsigned_LEB_128(buffer,
100*fae548d3Szrj 			   convert_types<uint64_t, int>(this->int_value_));
101*fae548d3Szrj 
102*fae548d3Szrj   // Write string value.
103*fae548d3Szrj   if (Object_attribute::attribute_type_has_string_value(this->type_))
104*fae548d3Szrj     {
105*fae548d3Szrj       const unsigned char* start =
106*fae548d3Szrj 	reinterpret_cast<const unsigned char*>(this->string_value_.c_str());
107*fae548d3Szrj       const unsigned char* end = start + this->string_value_.size() + 1;
108*fae548d3Szrj       buffer->insert(buffer->end(), start, end);
109*fae548d3Szrj     }
110*fae548d3Szrj }
111*fae548d3Szrj 
112*fae548d3Szrj // Vendor_object_attributes methods.
113*fae548d3Szrj 
114*fae548d3Szrj // Copying constructor.
115*fae548d3Szrj 
Vendor_object_attributes(const Vendor_object_attributes & voa)116*fae548d3Szrj Vendor_object_attributes::Vendor_object_attributes(
117*fae548d3Szrj     const Vendor_object_attributes& voa)
118*fae548d3Szrj {
119*fae548d3Szrj   this->vendor_ = voa.vendor_;
120*fae548d3Szrj 
121*fae548d3Szrj   for (int i = 0; i < NUM_KNOWN_ATTRIBUTES; ++i)
122*fae548d3Szrj     this->known_attributes_[i] = voa.known_attributes_[i];
123*fae548d3Szrj 
124*fae548d3Szrj   // We do not handle attribute deletion.  So this must be empty.
125*fae548d3Szrj   gold_assert(this->other_attributes_.empty());
126*fae548d3Szrj 
127*fae548d3Szrj   for (Other_attributes::const_iterator p = voa.other_attributes_.begin();
128*fae548d3Szrj        p != voa.other_attributes_.end();
129*fae548d3Szrj        ++p)
130*fae548d3Szrj     this->other_attributes_[p->first] = new Object_attribute(*(p->second));
131*fae548d3Szrj }
132*fae548d3Szrj 
133*fae548d3Szrj // Size of this in number of bytes.
134*fae548d3Szrj 
135*fae548d3Szrj size_t
size() const136*fae548d3Szrj Vendor_object_attributes::size() const
137*fae548d3Szrj {
138*fae548d3Szrj   if (this->name() == NULL)
139*fae548d3Szrj     return 0;
140*fae548d3Szrj 
141*fae548d3Szrj   size_t data_size = 0;
142*fae548d3Szrj   for (int i = 4; i < NUM_KNOWN_ATTRIBUTES; ++i)
143*fae548d3Szrj     data_size += this->known_attributes_[i].size(i);
144*fae548d3Szrj 
145*fae548d3Szrj   for (Other_attributes::const_iterator p = this->other_attributes_.begin();
146*fae548d3Szrj        p != this->other_attributes_.end();
147*fae548d3Szrj        ++p)
148*fae548d3Szrj     data_size += p->second->size(p->first);
149*fae548d3Szrj 
150*fae548d3Szrj   // <size> <vendor_name> NUL 0x1 <size>
151*fae548d3Szrj   return ((data_size != 0
152*fae548d3Szrj 	   || this->vendor_ == Object_attribute::OBJ_ATTR_PROC)
153*fae548d3Szrj 	  ? data_size + strlen(this->name()) + 2 + 2 * 4
154*fae548d3Szrj 	  : 0);
155*fae548d3Szrj }
156*fae548d3Szrj 
157*fae548d3Szrj // Return a new attribute associated with TAG.
158*fae548d3Szrj 
159*fae548d3Szrj Object_attribute*
new_attribute(int tag)160*fae548d3Szrj Vendor_object_attributes::new_attribute(int tag)
161*fae548d3Szrj {
162*fae548d3Szrj   int type = Object_attribute::arg_type(this->vendor_, tag);
163*fae548d3Szrj 
164*fae548d3Szrj   if (tag < NUM_KNOWN_ATTRIBUTES)
165*fae548d3Szrj     {
166*fae548d3Szrj       this->known_attributes_[tag].set_type(type);
167*fae548d3Szrj       return &this->known_attributes_[tag];
168*fae548d3Szrj     }
169*fae548d3Szrj   else
170*fae548d3Szrj     {
171*fae548d3Szrj       Object_attribute* attr = new Object_attribute();
172*fae548d3Szrj 
173*fae548d3Szrj       // This should be the first time we insert this.
174*fae548d3Szrj       std::pair<Other_attributes::iterator, bool> ins =
175*fae548d3Szrj 	this->other_attributes_.insert(std::make_pair(tag, attr));
176*fae548d3Szrj       gold_assert(ins.second);
177*fae548d3Szrj 
178*fae548d3Szrj       attr->set_type(type);
179*fae548d3Szrj       return attr;
180*fae548d3Szrj     }
181*fae548d3Szrj }
182*fae548d3Szrj 
183*fae548d3Szrj // Return an attribute associated with TAG.
184*fae548d3Szrj 
185*fae548d3Szrj Object_attribute*
get_attribute(int tag)186*fae548d3Szrj Vendor_object_attributes::get_attribute(int tag)
187*fae548d3Szrj {
188*fae548d3Szrj   if (tag < NUM_KNOWN_ATTRIBUTES)
189*fae548d3Szrj     return &this->known_attributes_[tag];
190*fae548d3Szrj   else
191*fae548d3Szrj     {
192*fae548d3Szrj       Other_attributes::iterator p =
193*fae548d3Szrj 	this->other_attributes_.find(tag);
194*fae548d3Szrj       return p != this->other_attributes_.end() ? p->second : NULL;
195*fae548d3Szrj     }
196*fae548d3Szrj }
197*fae548d3Szrj 
198*fae548d3Szrj const Object_attribute*
get_attribute(int tag) const199*fae548d3Szrj Vendor_object_attributes::get_attribute(int tag) const
200*fae548d3Szrj {
201*fae548d3Szrj   if (tag < NUM_KNOWN_ATTRIBUTES)
202*fae548d3Szrj     return &this->known_attributes_[tag];
203*fae548d3Szrj   else
204*fae548d3Szrj     {
205*fae548d3Szrj       Other_attributes::const_iterator p =
206*fae548d3Szrj 	this->other_attributes_.find(tag);
207*fae548d3Szrj       return p != this->other_attributes_.end() ? p->second : NULL;
208*fae548d3Szrj     }
209*fae548d3Szrj }
210*fae548d3Szrj 
211*fae548d3Szrj // Write attributes to BUFFER.
212*fae548d3Szrj 
213*fae548d3Szrj void
write(std::vector<unsigned char> * buffer) const214*fae548d3Szrj Vendor_object_attributes::write(std::vector<unsigned char>* buffer) const
215*fae548d3Szrj {
216*fae548d3Szrj   // Write subsection size.
217*fae548d3Szrj   size_t voa_size = this->size();
218*fae548d3Szrj   uint32_t voa_size_as_u32 = convert_types<uint32_t, size_t>(voa_size);
219*fae548d3Szrj   insert_into_vector<32>(buffer, voa_size_as_u32);
220*fae548d3Szrj 
221*fae548d3Szrj   // Write vendor name.
222*fae548d3Szrj   const unsigned char* vendor_start =
223*fae548d3Szrj     reinterpret_cast<const unsigned char*>(this->name());
224*fae548d3Szrj   size_t vendor_length = strlen(this->name()) + 1;
225*fae548d3Szrj   const unsigned char* vendor_end = vendor_start + vendor_length;
226*fae548d3Szrj   buffer->insert(buffer->end(), vendor_start, vendor_end);
227*fae548d3Szrj 
228*fae548d3Szrj   // Write file tag.
229*fae548d3Szrj   buffer->push_back(Object_attribute::Tag_File);
230*fae548d3Szrj 
231*fae548d3Szrj   // Write attributes size.
232*fae548d3Szrj   uint32_t attributes_size_as_u32 =
233*fae548d3Szrj     convert_types<uint32_t, size_t>(voa_size - 4 - vendor_length);
234*fae548d3Szrj   insert_into_vector<32>(buffer, attributes_size_as_u32);
235*fae548d3Szrj 
236*fae548d3Szrj   // Write known attributes, skipping any defaults.
237*fae548d3Szrj   for (int i = 4; i < NUM_KNOWN_ATTRIBUTES; ++i)
238*fae548d3Szrj     {
239*fae548d3Szrj       // A target may write known attributes in a special order.
240*fae548d3Szrj       // Call target hook to remap tags.  Attributes_order is the identity
241*fae548d3Szrj       // function if no re-ordering is required.
242*fae548d3Szrj       int tag = parameters->target().attributes_order(i);
243*fae548d3Szrj       this->known_attributes_[tag].write(tag, buffer);
244*fae548d3Szrj     }
245*fae548d3Szrj 
246*fae548d3Szrj   // Write other attributes.
247*fae548d3Szrj   for (Other_attributes::const_iterator q = this->other_attributes_.begin();
248*fae548d3Szrj        q != this->other_attributes_.end();
249*fae548d3Szrj        ++q)
250*fae548d3Szrj     q->second->write(q->first, buffer);
251*fae548d3Szrj }
252*fae548d3Szrj 
253*fae548d3Szrj // Attributes_section_data methods.
254*fae548d3Szrj 
255*fae548d3Szrj // Compute encoded size of this.
256*fae548d3Szrj 
257*fae548d3Szrj size_t
size() const258*fae548d3Szrj Attributes_section_data::size() const
259*fae548d3Szrj {
260*fae548d3Szrj   size_t data_size = 0;
261*fae548d3Szrj   for(int vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; ++vendor)
262*fae548d3Szrj     data_size += this->vendor_object_attributes_[vendor]->size();
263*fae548d3Szrj 
264*fae548d3Szrj   // 'A' <sections for each vendor>
265*fae548d3Szrj   return data_size != 0 ? data_size + 1 : 0;
266*fae548d3Szrj }
267*fae548d3Szrj 
268*fae548d3Szrj // Construct an Attributes_section_data object by parsing section contents
269*fae548d3Szrj // specified by VIEW and SIZE.
270*fae548d3Szrj 
Attributes_section_data(const unsigned char * view,section_size_type size)271*fae548d3Szrj Attributes_section_data::Attributes_section_data(
272*fae548d3Szrj     const unsigned char* view,
273*fae548d3Szrj     section_size_type size)
274*fae548d3Szrj {
275*fae548d3Szrj   for (int vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; ++vendor)
276*fae548d3Szrj     this->vendor_object_attributes_[vendor] =
277*fae548d3Szrj       new Vendor_object_attributes(vendor);
278*fae548d3Szrj 
279*fae548d3Szrj   const unsigned char* p = view;
280*fae548d3Szrj   p = view;
281*fae548d3Szrj   if (size > 0 && p != NULL && *(p++) == 'A')
282*fae548d3Szrj     {
283*fae548d3Szrj       size--;
284*fae548d3Szrj       while (size > 0)
285*fae548d3Szrj 	{
286*fae548d3Szrj 	  // Size of vendor attributes section.
287*fae548d3Szrj 	  section_size_type section_size =
288*fae548d3Szrj 	    convert_to_section_size_type(read_from_pointer<32>(&p));
289*fae548d3Szrj 
290*fae548d3Szrj 	  if (section_size > size)
291*fae548d3Szrj 	    section_size = size;
292*fae548d3Szrj 	  size -= section_size;
293*fae548d3Szrj 
294*fae548d3Szrj 	  const char* section_name = reinterpret_cast<const char*>(p);
295*fae548d3Szrj 	  section_size_type section_name_size = strlen(section_name) + 1;
296*fae548d3Szrj 	  section_size -= section_name_size + 4;
297*fae548d3Szrj 
298*fae548d3Szrj 	  int vendor;
299*fae548d3Szrj 	  const char* std_section = parameters->target().attributes_vendor();
300*fae548d3Szrj 	  if (std_section != NULL && strcmp(section_name, std_section) == 0)
301*fae548d3Szrj 	    vendor = Object_attribute::OBJ_ATTR_PROC;
302*fae548d3Szrj 	  else if (strcmp(section_name, "gnu") == 0)
303*fae548d3Szrj 	    vendor = Object_attribute::OBJ_ATTR_GNU;
304*fae548d3Szrj 	  else
305*fae548d3Szrj 	    {
306*fae548d3Szrj 	      // Other vendor section.  Ignore it.
307*fae548d3Szrj 	      p += section_name_size + section_size;
308*fae548d3Szrj 	      continue;
309*fae548d3Szrj 	    }
310*fae548d3Szrj 	  p += section_name_size;
311*fae548d3Szrj 
312*fae548d3Szrj 	  while (section_size > 0)
313*fae548d3Szrj 	    {
314*fae548d3Szrj 	      const unsigned char* subsection_start = p;
315*fae548d3Szrj 
316*fae548d3Szrj 	      // Read vendor subsection index and size.
317*fae548d3Szrj 	      size_t uleb128_len;
318*fae548d3Szrj 	      uint64_t val = read_unsigned_LEB_128(p, &uleb128_len);
319*fae548d3Szrj 	      p += uleb128_len;
320*fae548d3Szrj 
321*fae548d3Szrj 	      int tag = convert_types<int, uint64_t>(val);
322*fae548d3Szrj 	      section_size_type subsection_size =
323*fae548d3Szrj 		convert_to_section_size_type(read_from_pointer<32>(&p));
324*fae548d3Szrj 	      section_size -= subsection_size;
325*fae548d3Szrj 	      subsection_size -= (p - subsection_start);
326*fae548d3Szrj 
327*fae548d3Szrj 	      const unsigned char* end = p + subsection_size;
328*fae548d3Szrj 	      switch (tag)
329*fae548d3Szrj 		{
330*fae548d3Szrj 		case Object_attribute::Tag_File:
331*fae548d3Szrj 		  while (p < end)
332*fae548d3Szrj 		    {
333*fae548d3Szrj 		      val = read_unsigned_LEB_128(p, &uleb128_len);
334*fae548d3Szrj 		      p += uleb128_len;
335*fae548d3Szrj 		      tag = convert_types<int, uint64_t>(val);
336*fae548d3Szrj 		      Vendor_object_attributes* pvoa =
337*fae548d3Szrj 			this->vendor_object_attributes_[vendor];
338*fae548d3Szrj 		      Object_attribute* attr = pvoa->new_attribute(tag);
339*fae548d3Szrj 		      const char* string_arg;
340*fae548d3Szrj 		      unsigned int int_arg;
341*fae548d3Szrj 
342*fae548d3Szrj 		      int type = Object_attribute::arg_type(vendor, tag);
343*fae548d3Szrj 		      switch (type
344*fae548d3Szrj 			      & (Object_attribute::ATTR_TYPE_FLAG_INT_VAL
345*fae548d3Szrj 				 | Object_attribute::ATTR_TYPE_FLAG_STR_VAL))
346*fae548d3Szrj 			{
347*fae548d3Szrj 			case (Object_attribute::ATTR_TYPE_FLAG_INT_VAL
348*fae548d3Szrj 			      | Object_attribute::ATTR_TYPE_FLAG_STR_VAL):
349*fae548d3Szrj 			  val = read_unsigned_LEB_128(p, &uleb128_len);
350*fae548d3Szrj 			  p += uleb128_len;
351*fae548d3Szrj 			  int_arg = convert_types<unsigned int, uint64_t>(val);
352*fae548d3Szrj 			  string_arg = reinterpret_cast<const char *>(p);
353*fae548d3Szrj 			  attr->set_int_value(int_arg);
354*fae548d3Szrj 			  p += strlen(string_arg) + 1;
355*fae548d3Szrj 			  break;
356*fae548d3Szrj 			case Object_attribute::ATTR_TYPE_FLAG_STR_VAL:
357*fae548d3Szrj 			  string_arg = reinterpret_cast<const char *>(p);
358*fae548d3Szrj 			  attr->set_string_value(string_arg);
359*fae548d3Szrj 			  p += strlen(string_arg) + 1;
360*fae548d3Szrj 			  break;
361*fae548d3Szrj 			case Object_attribute::ATTR_TYPE_FLAG_INT_VAL:
362*fae548d3Szrj 			  val = read_unsigned_LEB_128(p, &uleb128_len);
363*fae548d3Szrj 			  p += uleb128_len;
364*fae548d3Szrj 			  int_arg = convert_types<unsigned int, uint64_t>(val);
365*fae548d3Szrj 			  attr->set_int_value(int_arg);
366*fae548d3Szrj 			  break;
367*fae548d3Szrj 			default:
368*fae548d3Szrj 			  gold_unreachable();
369*fae548d3Szrj 			}
370*fae548d3Szrj 		    }
371*fae548d3Szrj 		  break;
372*fae548d3Szrj 		case Object_attribute::Tag_Section:
373*fae548d3Szrj 		case Object_attribute::Tag_Symbol:
374*fae548d3Szrj 		  // Don't have anywhere convenient to attach these.
375*fae548d3Szrj 		  // Fall through for now.
376*fae548d3Szrj 		default:
377*fae548d3Szrj 		  // Ignore things we don't know about.
378*fae548d3Szrj 		  p += subsection_size;
379*fae548d3Szrj 		  subsection_size = 0;
380*fae548d3Szrj 		  break;
381*fae548d3Szrj 		}
382*fae548d3Szrj 	    }
383*fae548d3Szrj 	}
384*fae548d3Szrj     }
385*fae548d3Szrj }
386*fae548d3Szrj 
387*fae548d3Szrj // Merge target-independent attributes from another Attribute_section_data
388*fae548d3Szrj // ASD from an object called NAME into this.
389*fae548d3Szrj 
390*fae548d3Szrj void
merge(const char * name,const Attributes_section_data * pasd)391*fae548d3Szrj Attributes_section_data::merge(
392*fae548d3Szrj     const char* name,
393*fae548d3Szrj     const Attributes_section_data* pasd)
394*fae548d3Szrj {
395*fae548d3Szrj   // The only common attribute is currently Tag_compatibility,
396*fae548d3Szrj   // accepted in both processor and "gnu" sections.
397*fae548d3Szrj   for (int vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; ++vendor)
398*fae548d3Szrj     {
399*fae548d3Szrj       // Handle Tag_compatibility.  The tags are only compatible if the flags
400*fae548d3Szrj       // are identical and, if the flags are '1', the strings are identical.
401*fae548d3Szrj       // If the flags are non-zero, then we can only use the string "gnu".
402*fae548d3Szrj       const Object_attribute* in_attr =
403*fae548d3Szrj 	&pasd->known_attributes(vendor)[Object_attribute::Tag_compatibility];
404*fae548d3Szrj       Object_attribute* out_attr =
405*fae548d3Szrj 	&this->known_attributes(vendor)[Object_attribute::Tag_compatibility];
406*fae548d3Szrj 
407*fae548d3Szrj       if (in_attr->int_value() > 0
408*fae548d3Szrj 	  && in_attr->string_value() != "gnu")
409*fae548d3Szrj 	{
410*fae548d3Szrj 	  gold_error(_("%s: must be processed by '%s' toolchain"),
411*fae548d3Szrj 		     name, in_attr->string_value().c_str());
412*fae548d3Szrj 	  return;
413*fae548d3Szrj 	}
414*fae548d3Szrj 
415*fae548d3Szrj       if (in_attr->int_value() != out_attr->int_value()
416*fae548d3Szrj 	  || in_attr->string_value() != out_attr->string_value())
417*fae548d3Szrj 	{
418*fae548d3Szrj 	  gold_error(_("%s: object tag '%d, %s' is "
419*fae548d3Szrj 		       "incompatible with tag '%d, %s'"),
420*fae548d3Szrj 		     name, in_attr->int_value(),
421*fae548d3Szrj 		     in_attr->string_value().c_str(),
422*fae548d3Szrj 		     out_attr->int_value(),
423*fae548d3Szrj 		     out_attr->string_value().c_str());
424*fae548d3Szrj 	}
425*fae548d3Szrj     }
426*fae548d3Szrj }
427*fae548d3Szrj 
428*fae548d3Szrj // Write to a buffer.
429*fae548d3Szrj 
430*fae548d3Szrj void
write(std::vector<unsigned char> * buffer) const431*fae548d3Szrj Attributes_section_data::write(std::vector<unsigned char>* buffer) const
432*fae548d3Szrj {
433*fae548d3Szrj   buffer->push_back('A');
434*fae548d3Szrj   for (int vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; ++vendor)
435*fae548d3Szrj     if (this->vendor_object_attributes_[vendor]->size() != 0)
436*fae548d3Szrj       this->vendor_object_attributes_[vendor]->write(buffer);
437*fae548d3Szrj }
438*fae548d3Szrj 
439*fae548d3Szrj // Methods for Output_attributes_section_data.
440*fae548d3Szrj 
441*fae548d3Szrj // Write attributes section data to file OF.
442*fae548d3Szrj 
443*fae548d3Szrj void
do_write(Output_file * of)444*fae548d3Szrj Output_attributes_section_data::do_write(Output_file* of)
445*fae548d3Szrj {
446*fae548d3Szrj   off_t offset = this->offset();
447*fae548d3Szrj   const section_size_type oview_size =
448*fae548d3Szrj     convert_to_section_size_type(this->data_size());
449*fae548d3Szrj   unsigned char* const oview = of->get_output_view(offset, oview_size);
450*fae548d3Szrj 
451*fae548d3Szrj   std::vector<unsigned char> buffer;
452*fae548d3Szrj   this->attributes_section_data_.write(&buffer);
453*fae548d3Szrj   gold_assert(convert_to_section_size_type(buffer.size()) == oview_size);
454*fae548d3Szrj   memcpy(oview, &buffer.front(), buffer.size());
455*fae548d3Szrj   of->write_output_view(this->offset(), oview_size, oview);
456*fae548d3Szrj }
457*fae548d3Szrj 
458*fae548d3Szrj } // End namespace gold.
459