~ubuntu-branches/ubuntu/precise/binutils/precise-updates

« back to all changes in this revision

Viewing changes to gas/config/obj-macho.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2011-08-11 22:51:48 UTC
  • mfrom: (1.7.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20110811225148-y61bcrw1ukl0z2k2
Tags: 2.21.53.20110810-0ubuntu1
Snapshot, taken from the trunk 20110810.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
#define OBJ_HEADER "obj-macho.h"
22
22
 
23
23
#include "as.h"
 
24
#include "subsegs.h"
 
25
#include "symbols.h"
 
26
#include "write.h"
24
27
#include "mach-o.h"
 
28
#include "mach-o/loader.h"
25
29
 
26
30
static void
27
31
obj_mach_o_weak (int ignore ATTRIBUTE_UNUSED)
49
53
  demand_empty_rest_of_line ();
50
54
}
51
55
 
 
56
/* Parse:
 
57
   .section segname,sectname[,type[,attribute[,sizeof_stub]]]
 
58
*/
 
59
 
 
60
static void
 
61
obj_mach_o_section (int ignore ATTRIBUTE_UNUSED)
 
62
{
 
63
  char *p;
 
64
  char *segname;
 
65
  char *sectname;
 
66
  char c;
 
67
  int sectype = BFD_MACH_O_S_REGULAR;
 
68
  unsigned int secattr = 0;
 
69
  offsetT sizeof_stub = 0;
 
70
  const char *name;
 
71
  flagword oldflags, flags;
 
72
  asection *sec;
 
73
 
 
74
  /* Parse segment name.  */
 
75
  if (!is_name_beginner (*input_line_pointer))
 
76
    {
 
77
      as_bad (_("missing segment name"));
 
78
      ignore_rest_of_line ();
 
79
      return;
 
80
    }
 
81
  p = input_line_pointer;
 
82
  c = get_symbol_end ();
 
83
  segname = alloca (input_line_pointer - p + 1);
 
84
  strcpy (segname, p);
 
85
  *input_line_pointer = c;
 
86
 
 
87
  if (*input_line_pointer != ',')
 
88
    {
 
89
      as_bad (_("missing comma after segment name"));
 
90
      ignore_rest_of_line ();
 
91
      return;
 
92
    }
 
93
  input_line_pointer++;
 
94
 
 
95
  /* Parse section name.  */
 
96
  if (!is_name_beginner (*input_line_pointer))
 
97
    {
 
98
      as_bad (_("missing section name"));
 
99
      ignore_rest_of_line ();
 
100
      return;
 
101
    }
 
102
  p = input_line_pointer;
 
103
  c = get_symbol_end ();
 
104
  sectname = alloca (input_line_pointer - p + 1);
 
105
  strcpy (sectname, p);
 
106
  *input_line_pointer = c;
 
107
 
 
108
  /* Parse type.  */
 
109
  if (*input_line_pointer == ',')
 
110
    {
 
111
      input_line_pointer++;
 
112
      if (!is_name_beginner (*input_line_pointer))
 
113
        {
 
114
          as_bad (_("missing section type name"));
 
115
          ignore_rest_of_line ();
 
116
          return;
 
117
        }
 
118
      p = input_line_pointer;
 
119
      c = get_symbol_end ();
 
120
 
 
121
      sectype = bfd_mach_o_get_section_type_from_name (p);
 
122
      if (sectype == -1)
 
123
        {
 
124
          as_bad (_("unknown or invalid section type '%s'"), p);
 
125
          sectype = BFD_MACH_O_S_REGULAR;
 
126
        }
 
127
      *input_line_pointer = c;
 
128
 
 
129
      /* Parse attributes.  */
 
130
      if (*input_line_pointer == ',')
 
131
        {
 
132
          do
 
133
            {
 
134
              int attr;
 
135
 
 
136
              input_line_pointer++;
 
137
 
 
138
              if (!is_name_beginner (*input_line_pointer))
 
139
                {
 
140
                  as_bad (_("missing section attribute identifier"));
 
141
                  ignore_rest_of_line ();
 
142
                  break;
 
143
                }
 
144
              p = input_line_pointer;
 
145
              c = get_symbol_end ();
 
146
 
 
147
              attr = bfd_mach_o_get_section_attribute_from_name (p);
 
148
              if (attr == -1)
 
149
                as_bad (_("unknown or invalid section attribute '%s'"), p);
 
150
              else
 
151
                secattr |= attr;
 
152
 
 
153
              *input_line_pointer = c;
 
154
            }
 
155
          while (*input_line_pointer == '+');
 
156
 
 
157
          /* Parse sizeof_stub.  */
 
158
          if (*input_line_pointer == ',')
 
159
            {
 
160
              if (sectype != BFD_MACH_O_S_SYMBOL_STUBS)
 
161
                as_bad (_("unexpected sizeof_stub expression"));
 
162
 
 
163
              sizeof_stub = get_absolute_expression ();
 
164
            }
 
165
          else if (sectype == BFD_MACH_O_S_SYMBOL_STUBS)
 
166
            as_bad (_("missing sizeof_stub expression"));
 
167
        }
 
168
    }
 
169
  demand_empty_rest_of_line ();
 
170
 
 
171
  bfd_mach_o_normalize_section_name (segname, sectname, &name, &flags);
 
172
  if (name == NULL)
 
173
    {
 
174
      /* There is no normal BFD section name for this section.  Create one.
 
175
         The name created doesn't really matter as it will never be written
 
176
         on disk.  */
 
177
      size_t seglen = strlen (segname);
 
178
      size_t sectlen = strlen (sectname);
 
179
      char *n;
 
180
 
 
181
      n = xmalloc (seglen + 1 + sectlen + 1);
 
182
      memcpy (n, segname, seglen);
 
183
      n[seglen] = '.';
 
184
      memcpy (n + seglen + 1, sectname, sectlen);
 
185
      n[seglen + 1 + sectlen] = 0;
 
186
      name = n;
 
187
    }
 
188
 
 
189
#ifdef md_flush_pending_output
 
190
  md_flush_pending_output ();
 
191
#endif
 
192
 
 
193
  /* Sub-segments don't exists as is on Mach-O.  */
 
194
  sec = subseg_new (name, 0);
 
195
 
 
196
  oldflags = bfd_get_section_flags (stdoutput, sec);
 
197
  if (oldflags == SEC_NO_FLAGS)
 
198
    {
 
199
      bfd_mach_o_section *msect;
 
200
 
 
201
      if (! bfd_set_section_flags (stdoutput, sec, flags))
 
202
        as_warn (_("error setting flags for \"%s\": %s"),
 
203
                 bfd_section_name (stdoutput, sec),
 
204
                 bfd_errmsg (bfd_get_error ()));
 
205
      msect = bfd_mach_o_get_mach_o_section (sec);
 
206
      strncpy (msect->segname, segname, sizeof (msect->segname));
 
207
      msect->segname[16] = 0;
 
208
      strncpy (msect->sectname, sectname, sizeof (msect->sectname));
 
209
      msect->sectname[16] = 0;
 
210
      msect->flags = secattr | sectype;
 
211
      msect->reserved2 = sizeof_stub;
 
212
    }
 
213
  else if (flags != SEC_NO_FLAGS)
 
214
    {
 
215
      if (flags != oldflags)
 
216
        as_warn (_("Ignoring changed section attributes for %s"), name);
 
217
    }
 
218
}
 
219
 
 
220
struct known_section
 
221
{
 
222
  const char *name;
 
223
  unsigned int flags;
 
224
};
 
225
 
 
226
static const struct known_section known_sections[] =
 
227
  {
 
228
    /* 0 */ { NULL, 0},
 
229
    /* 1 */ { ".cstring", BFD_MACH_O_S_CSTRING_LITERALS }
 
230
  };
 
231
 
 
232
static void
 
233
obj_mach_o_known_section (int sect_index)
 
234
{
 
235
  const struct known_section *sect = &known_sections[sect_index];
 
236
  asection *old_sec;
 
237
  segT sec;
 
238
 
 
239
#ifdef md_flush_pending_output
 
240
  md_flush_pending_output ();
 
241
#endif
 
242
 
 
243
  old_sec = bfd_get_section_by_name (stdoutput, sect->name);
 
244
  if (old_sec)
 
245
    {
 
246
      /* Section already present.  */
 
247
      sec = old_sec;
 
248
      subseg_set (sec, 0);
 
249
    }
 
250
  else
 
251
    {
 
252
      bfd_mach_o_section *msect;
 
253
 
 
254
      sec = subseg_force_new (sect->name, 0);
 
255
 
 
256
      /* Set default flags.  */
 
257
      msect = bfd_mach_o_get_mach_o_section (sec);
 
258
      msect->flags = sect->flags;
 
259
    }
 
260
}
 
261
 
 
262
/* Called from read.c:s_comm after we've parsed .comm symbol, size.
 
263
   Parse a possible alignment value.  */
 
264
 
 
265
static symbolS *
 
266
obj_mach_o_common_parse (int ignore ATTRIBUTE_UNUSED,
 
267
                         symbolS *symbolP, addressT size)
 
268
{
 
269
  addressT align = 0;
 
270
 
 
271
  if (*input_line_pointer == ',')
 
272
    {
 
273
      align = parse_align (0);
 
274
      if (align == (addressT) -1)
 
275
        return NULL;
 
276
    }
 
277
 
 
278
  S_SET_VALUE (symbolP, size);
 
279
  S_SET_EXTERNAL (symbolP);
 
280
  S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
 
281
 
 
282
  symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
 
283
 
 
284
  return symbolP;
 
285
}
 
286
 
 
287
static void
 
288
obj_mach_o_comm (int ignore ATTRIBUTE_UNUSED)
 
289
{
 
290
  s_comm_internal (ignore, obj_mach_o_common_parse);
 
291
}
 
292
 
 
293
static void
 
294
obj_mach_o_subsections_via_symbols (int arg ATTRIBUTE_UNUSED)
 
295
{
 
296
  /* Currently ignore it.  */
 
297
  demand_empty_rest_of_line ();
 
298
}
 
299
 
52
300
const pseudo_typeS mach_o_pseudo_table[] =
53
301
{
54
 
  {"weak", obj_mach_o_weak, 0},
 
302
  { "weak", obj_mach_o_weak, 0},
 
303
  { "section", obj_mach_o_section, 0},
 
304
  { "cstring", obj_mach_o_known_section, 1},
 
305
  { "lcomm", s_lcomm, 1 },
 
306
  { "comm", obj_mach_o_comm, 0 },
 
307
  { "subsections_via_symbols", obj_mach_o_subsections_via_symbols, 0 },
55
308
 
56
309
  {NULL, NULL, 0}
57
310
};