OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gas/] [config/] [obj-macho.c] - Blame information for rev 160

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 16 khays
/* Mach-O object file format
2
   Copyright 2009 Free Software Foundation, Inc.
3
 
4
   This file is part of GAS, the GNU Assembler.
5
 
6
   GAS is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as
8
   published by the Free Software Foundation; either version 3,
9
   or (at your option) any later version.
10
 
11
   GAS is distributed in the hope that it will be useful, but
12
   WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
14
   the GNU General Public License for more details.
15
 
16
   You should have received a copy of the GNU General Public License
17
   along with GAS; see the file COPYING.  If not, write to the Free
18
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19
   02110-1301, USA.  */
20
 
21
#define OBJ_HEADER "obj-macho.h"
22
 
23
#include "as.h"
24 160 khays
#include "subsegs.h"
25
#include "symbols.h"
26
#include "write.h"
27 16 khays
#include "mach-o.h"
28 160 khays
#include "mach-o/loader.h"
29 16 khays
 
30
static void
31
obj_mach_o_weak (int ignore ATTRIBUTE_UNUSED)
32
{
33
  char *name;
34
  int c;
35
  symbolS *symbolP;
36
 
37
  do
38
    {
39
      /* Get symbol name.  */
40
      name = input_line_pointer;
41
      c = get_symbol_end ();
42
      symbolP = symbol_find_or_make (name);
43
      S_SET_WEAK (symbolP);
44
      *input_line_pointer = c;
45
      SKIP_WHITESPACE ();
46
 
47
      if (c != ',')
48
        break;
49
      input_line_pointer++;
50
      SKIP_WHITESPACE ();
51
    }
52
  while (*input_line_pointer != '\n');
53
  demand_empty_rest_of_line ();
54
}
55
 
56 160 khays
/* 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
 
300 16 khays
const pseudo_typeS mach_o_pseudo_table[] =
301
{
302 160 khays
  { "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 },
308 16 khays
 
309
  {NULL, NULL, 0}
310
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.