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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [bfd/] [vms-misc.c] - Blame information for rev 373

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

Line No. Rev Author Line
1 227 jeremybenn
/* vms-misc.c -- BFD back-end for VMS/VAX (openVMS/VAX) and
2
   EVAX (openVMS/Alpha) files.
3
   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4
   2007, 2008, 2009  Free Software Foundation, Inc.
5
 
6
   Miscellaneous functions.
7
 
8
   Written by Klaus K"ampf (kkaempf@rmi.de)
9
 
10
   This program is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 3 of the License, or
13
   (at your option) any later version.
14
 
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
 
20
   You should have received a copy of the GNU General Public License
21
   along with this program; if not, write to the Free Software
22
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23
   MA 02110-1301, USA.  */
24
 
25
#if __STDC__
26
#include <stdarg.h>
27
#endif
28
 
29
#include "sysdep.h"
30
#include "bfd.h"
31
#include "bfdlink.h"
32
#include "libbfd.h"
33
 
34
#include "vms.h"
35
 
36
#define MIN(a,b) ((a) < (b) ? (a) : (b))
37
 
38
static int hash_string PARAMS ((const char *));
39
static asymbol *new_symbol PARAMS ((bfd *, char *));
40
static void maybe_adjust_record_pointer_for_object PARAMS ((bfd *));
41
static int vms_get_remaining_object_record PARAMS ((bfd *, int ));
42
static int vms_get_remaining_image_record PARAMS ((bfd *, int ));
43
 
44
#if VMS_DEBUG
45
/* Debug functions.  */
46
 
47
/* Debug function for all vms extensions evaluates environment
48
   variable VMS_DEBUG for a numerical value on the first call all
49
   error levels below this value are printed:
50
 
51
   Levels:
52
   1    toplevel bfd calls (functions from the bfd vector)
53
   2    functions called by bfd calls
54
   ...
55
   9    almost everything
56
 
57
   Level is also indentation level. Indentation is performed
58
   if level > 0.  */
59
 
60
void
61
_bfd_vms_debug (int level, char *format, ...)
62
{
63
  static int min_level = -1;
64
  static FILE *output = NULL;
65
  char *eptr;
66
  va_list args;
67
  int abslvl = (level > 0) ? level : - level;
68
 
69
  if (min_level == -1)
70
    {
71
      if ((eptr = getenv ("VMS_DEBUG")) != NULL)
72
        {
73
          min_level = atoi (eptr);
74
          output = stderr;
75
        }
76
      else
77
        min_level = 0;
78
    }
79
  if (output == NULL)
80
    return;
81
  if (abslvl > min_level)
82
    return;
83
 
84
  while (--level>0)
85
    fprintf (output, " ");
86
  va_start (args, format);
87
  vfprintf (output, format, args);
88
  fflush (output);
89
  va_end (args);
90
}
91
 
92
/* A debug function
93
   hex dump 'size' bytes starting at 'ptr'.  */
94
 
95
void
96
_bfd_hexdump (int level,
97
              unsigned char *ptr,
98
              int size,
99
              int offset)
100
{
101
  unsigned char *lptr = ptr;
102
  int count = 0;
103
  long start = offset;
104
 
105
  while (size-- > 0)
106
    {
107
      if ((count%16) == 0)
108
        vms_debug (level, "%08lx:", start);
109
      vms_debug (-level, " %02x", *ptr++);
110
      count++;
111
      start++;
112
      if (size == 0)
113
        {
114
          while ((count%16) != 0)
115
            {
116
              vms_debug (-level, "   ");
117
              count++;
118
            }
119
        }
120
      if ((count%16) == 0)
121
        {
122
          vms_debug (-level, " ");
123
          while (lptr < ptr)
124
            {
125
              vms_debug (-level, "%c", (*lptr < 32)?'.':*lptr);
126
              lptr++;
127
            }
128
          vms_debug (-level, "\n");
129
        }
130
    }
131
  if ((count%16) != 0)
132
    vms_debug (-level, "\n");
133
}
134
#endif
135
 
136
/* Hash functions
137
 
138
   These are needed when reading an object file.  */
139
 
140
/* Allocate new vms_hash_entry
141
   keep the symbol name and a pointer to the bfd symbol in the table.  */
142
 
143
struct bfd_hash_entry *
144
_bfd_vms_hash_newfunc (struct bfd_hash_entry *entry,
145
                       struct bfd_hash_table *table,
146
                       const char *string)
147
{
148
  vms_symbol_entry *ret;
149
 
150
#if VMS_DEBUG
151
  vms_debug (5, "_bfd_vms_hash_newfunc (%p, %p, %s)\n", entry, table, string);
152
#endif
153
 
154
  if (entry == NULL)
155
    {
156
      ret = (vms_symbol_entry *)
157
              bfd_hash_allocate (table, sizeof (vms_symbol_entry));
158
      if (ret ==  NULL)
159
        {
160
          bfd_set_error (bfd_error_no_memory);
161
          return NULL;
162
        }
163
      entry = (struct bfd_hash_entry *) ret;
164
    }
165
 
166
  /* Call the allocation method of the base class.  */
167
  ret = (vms_symbol_entry *) bfd_hash_newfunc (entry, table, string);
168
#if VMS_DEBUG
169
  vms_debug (6, "_bfd_vms_hash_newfunc ret %p\n", ret);
170
#endif
171
 
172
  ret->symbol = NULL;
173
 
174
  return (struct bfd_hash_entry *)ret;
175
}
176
 
177
/* Object file input functions.  */
178
 
179
/* Return type and size from record header (buf) on Alpha.  */
180
 
181
void
182
_bfd_vms_get_header_values (bfd * abfd ATTRIBUTE_UNUSED,
183
                            unsigned char *buf,
184
                            int *type,
185
                            int *size)
186
{
187
  if (type)
188
    *type = bfd_getl16 (buf);
189
 
190
  if (size)
191
    *size = bfd_getl16 (buf+2);
192
 
193
#if VMS_DEBUG
194
  vms_debug (10, "_bfd_vms_get_header_values type %x, size %x\n",
195
             type ? *type : 0, size ? *size : 0);
196
#endif
197
}
198
 
199
/* Get next record from object file to vms_buf.
200
   Set PRIV(buf_size) and return it
201
 
202
   This is a little tricky since it should be portable.
203
 
204
   The openVMS object file has 'variable length' which means that
205
   read() returns data in chunks of (hopefully) correct and expected
206
   size.  The linker (and other tools on VMS) depend on that. Unix
207
   doesn't know about 'formatted' files, so reading and writing such
208
   an object file in a Unix environment is not trivial.
209
 
210
   With the tool 'file' (available on all VMS FTP sites), one
211
   can view and change the attributes of a file.  Changing from
212
   'variable length' to 'fixed length, 512 bytes' reveals the
213
   record size at the first 2 bytes of every record.  The same
214
   may happen during the transfer of object files from VMS to Unix,
215
   at least with UCX, the DEC implementation of TCP/IP.
216
 
217
   The VMS format repeats the size at bytes 2 & 3 of every record.
218
 
219
   On the first call (file_format == FF_UNKNOWN) we check if
220
   the first and the third byte pair (!) of the record match.
221
   If they do it's an object file in an Unix environment or with
222
   wrong attributes (FF_FOREIGN), else we should be in a VMS
223
   environment where read() returns the record size (FF_NATIVE).
224
 
225
   Reading is always done in 2 steps:
226
    1. first just the record header is read and the size extracted,
227
    2. then the read buffer is adjusted and the remaining bytes are
228
       read in.
229
 
230
   All file I/O is done on even file positions.  */
231
 
232
#define VMS_OBJECT_ADJUSTMENT  2
233
 
234
static void
235
maybe_adjust_record_pointer_for_object (bfd *abfd)
236
{
237
  /* Set the file format once for all on the first invocation.  */
238
  if (PRIV (file_format) == FF_UNKNOWN)
239
    {
240
      if (PRIV (vms_rec)[0] == PRIV (vms_rec)[4]
241
          && PRIV (vms_rec)[1] == PRIV (vms_rec)[5])
242
        PRIV (file_format) = FF_FOREIGN;
243
      else
244
        PRIV (file_format) = FF_NATIVE;
245
    }
246
 
247
  /* The adjustment is needed only in an Unix environment.  */
248
  if (PRIV (file_format) == FF_FOREIGN)
249
    PRIV (vms_rec) += VMS_OBJECT_ADJUSTMENT;
250
}
251
 
252
/* Get first record from file and return the file type.  */
253
 
254
int
255
_bfd_vms_get_first_record (bfd *abfd)
256
{
257
  unsigned int test_len;
258
 
259
#if VMS_DEBUG
260
  vms_debug (8, "_bfd_vms_get_first_record\n");
261
#endif
262
 
263
  if (PRIV (is_vax))
264
    test_len = 0;
265
  else
266
    /* Minimum is 6 bytes for objects (2 bytes size, 2 bytes record id,
267
       2 bytes size repeated) and 12 bytes for images (4 bytes major id,
268
       4 bytes minor id, 4 bytes length).  */
269
    test_len = 12;
270
 
271
  /* Size the main buffer.  */
272
  if (PRIV (buf_size) == 0)
273
    {
274
      /* On VAX there's no size information in the record, so
275
         start with OBJ_S_C_MAXRECSIZ.  */
276
      bfd_size_type amt = (test_len ? test_len : OBJ_S_C_MAXRECSIZ);
277
      PRIV (vms_buf) = (unsigned char *) bfd_malloc (amt);
278
      PRIV (buf_size) = amt;
279
    }
280
 
281
  /* Initialize the record pointer.  */
282
  PRIV (vms_rec) = PRIV (vms_buf);
283
 
284
  /* We only support modules on VAX.  */
285
  if (PRIV (is_vax))
286
    {
287
      if (vms_get_remaining_object_record (abfd, test_len) <= 0)
288
        return FT_UNKNOWN;
289
 
290
#if VMS_DEBUG
291
      vms_debug (2, "file type is VAX module\n");
292
#endif
293
 
294
      return FT_MODULE;
295
    }
296
 
297
  if (bfd_bread (PRIV (vms_buf), test_len, abfd) != test_len)
298
    {
299
      bfd_set_error (bfd_error_file_truncated);
300
      return FT_UNKNOWN;
301
    }
302
 
303
  /* Is it an image?  */
304
  if ((bfd_getl32 (PRIV (vms_rec)) == EIHD_S_K_MAJORID)
305
      && (bfd_getl32 (PRIV (vms_rec) + 4) == EIHD_S_K_MINORID))
306
    {
307
      if (vms_get_remaining_image_record (abfd, test_len) <= 0)
308
        return FT_UNKNOWN;
309
 
310
#if VMS_DEBUG
311
      vms_debug (2, "file type is image\n");
312
#endif
313
 
314
      return FT_IMAGE;
315
    }
316
 
317
  /* Assume it's a module and adjust record pointer if necessary.  */
318
  maybe_adjust_record_pointer_for_object (abfd);
319
 
320
  /* But is it really a module?  */
321
  if (bfd_getl16 (PRIV (vms_rec)) <= EOBJ_S_C_MAXRECTYP
322
      && bfd_getl16 (PRIV (vms_rec) + 2) <= EOBJ_S_C_MAXRECSIZ)
323
    {
324
      if (vms_get_remaining_object_record (abfd, test_len) <= 0)
325
        return FT_UNKNOWN;
326
 
327
#if VMS_DEBUG
328
      vms_debug (2, "file type is module\n");
329
#endif
330
 
331
      return FT_MODULE;
332
    }
333
 
334
#if VMS_DEBUG
335
  vms_debug (2, "file type is unknown\n");
336
#endif
337
 
338
  return FT_UNKNOWN;
339
}
340
 
341
/* Implement step #1 of the object record reading procedure.
342
   Return the record type or -1 on failure.  */
343
 
344
int
345
_bfd_vms_get_object_record (bfd *abfd)
346
{
347
  unsigned int test_len;
348
  int type;
349
 
350
#if VMS_DEBUG
351
  vms_debug (8, "_bfd_vms_get_obj_record\n");
352
#endif
353
 
354
  if (PRIV (is_vax))
355
    test_len = 0;
356
  else
357
    {
358
      int off = 0;
359
 
360
      /* See _bfd_vms_get_first_record.  */
361
      test_len = 6;
362
 
363
      /* Skip odd alignment byte.  */
364
      if (bfd_tell (abfd) & 1)
365
        {
366
          if (bfd_bread (PRIV (vms_buf), 1, abfd) != 1)
367
            {
368
              bfd_set_error (bfd_error_file_truncated);
369
              return -1;
370
            }
371
          /* Alignment byte may be present or not.  This is not easy to
372
             detect but all object record types are not 0 (on Alpha VMS).
373
             We also hope that pad byte is 0.  */
374
          if (PRIV (vms_buf)[0])
375
            off = 1;
376
        }
377
 
378
      /* Read the record header  */
379
      if (bfd_bread (PRIV (vms_buf) + off, test_len - off, abfd)
380
          != test_len - off)
381
        {
382
          bfd_set_error (bfd_error_file_truncated);
383
          return -1;
384
        }
385
 
386
      /* Reset the record pointer.  */
387
      PRIV (vms_rec) = PRIV (vms_buf);
388
      maybe_adjust_record_pointer_for_object (abfd);
389
    }
390
 
391
  if (vms_get_remaining_object_record (abfd, test_len) <= 0)
392
    return -1;
393
 
394
  if (PRIV (is_vax))
395
    type = PRIV (vms_rec) [0];
396
  else
397
    type = bfd_getl16 (PRIV (vms_rec));
398
 
399
#if VMS_DEBUG
400
  vms_debug (8, "_bfd_vms_get_obj_record: rec %p, size %d, type %d\n",
401
              PRIV (vms_rec), PRIV (rec_size), type);
402
#endif
403
 
404
  return type;
405
}
406
 
407
/* Implement step #2 of the object record reading procedure.
408
   Return the size of the record or 0 on failure.  */
409
 
410
static int
411
vms_get_remaining_object_record (bfd *abfd, int read_so_far)
412
{
413
#if VMS_DEBUG
414
  vms_debug (8, "vms_get_remaining_obj_record\n");
415
#endif
416
 
417
  if (PRIV (is_vax))
418
    {
419
      if (read_so_far != 0)
420
        abort ();
421
 
422
      PRIV (rec_size) = bfd_bread (PRIV (vms_buf), PRIV (buf_size), abfd);
423
 
424
      if (PRIV (rec_size) <= 0)
425
        {
426
          bfd_set_error (bfd_error_file_truncated);
427
          return 0;
428
        }
429
 
430
      /* Reset the record pointer.  */
431
      PRIV (vms_rec) = PRIV (vms_buf);
432
    }
433
  else
434
    {
435
      unsigned int to_read;
436
 
437
      /* Extract record size.  */
438
      PRIV (rec_size) = bfd_getl16 (PRIV (vms_rec) + 2);
439
 
440
      if (PRIV (rec_size) <= 0)
441
        {
442
          bfd_set_error (bfd_error_file_truncated);
443
          return 0;
444
        }
445
 
446
      /* That's what the linker manual says.  */
447
      if (PRIV (rec_size) > EOBJ_S_C_MAXRECSIZ)
448
        {
449
          bfd_set_error (bfd_error_file_truncated);
450
          return 0;
451
        }
452
 
453
      /* Take into account object adjustment.  */
454
      to_read = PRIV (rec_size);
455
      if (PRIV (file_format) == FF_FOREIGN)
456
        to_read += VMS_OBJECT_ADJUSTMENT;
457
 
458
      /* Adjust the buffer.  */
459
      if (to_read > PRIV (buf_size))
460
        {
461
          PRIV (vms_buf)
462
            = (unsigned char *) bfd_realloc (PRIV (vms_buf), to_read);
463
          if (PRIV (vms_buf) == NULL)
464
            return 0;
465
          PRIV (buf_size) = to_read;
466
        }
467
 
468
      /* Read the remaining record.  */
469
      to_read -= read_so_far;
470
 
471
#if VMS_DEBUG
472
      vms_debug (8, "vms_get_remaining_obj_record: to_read %d\n", to_read);
473
#endif
474
 
475
      if (bfd_bread (PRIV (vms_buf) + read_so_far, to_read, abfd) != to_read)
476
        {
477
          bfd_set_error (bfd_error_file_truncated);
478
          return 0;
479
        }
480
 
481
      /* Reset the record pointer.  */
482
      PRIV (vms_rec) = PRIV (vms_buf);
483
      maybe_adjust_record_pointer_for_object (abfd);
484
    }
485
 
486
#if VMS_DEBUG
487
  vms_debug (8, "vms_get_remaining_obj_record: size %d\n", PRIV (rec_size));
488
#endif
489
 
490
  return PRIV (rec_size);
491
}
492
 
493
/* Implement step #2 of the record reading procedure for images.
494
   Return the size of the record or 0 on failure.  */
495
 
496
static int
497
vms_get_remaining_image_record (bfd *abfd, int read_so_far)
498
{
499
  unsigned int to_read;
500
  int remaining;
501
 
502
  /* Extract record size.  */
503
  PRIV (rec_size) = bfd_getl32 (PRIV (vms_rec) + EIHD_S_L_SIZE);
504
 
505
  if (PRIV (rec_size) > PRIV (buf_size))
506
    {
507
      PRIV (vms_buf) = bfd_realloc (PRIV (vms_buf), PRIV (rec_size));
508
 
509
      if (PRIV (vms_buf) == NULL)
510
        {
511
          bfd_set_error (bfd_error_no_memory);
512
          return 0;
513
        }
514
 
515
      PRIV (buf_size) = PRIV (rec_size);
516
    }
517
 
518
  /* Read the remaining record.  */
519
  remaining = PRIV (rec_size) - read_so_far;
520
  to_read = MIN (VMS_BLOCK_SIZE - read_so_far, remaining);
521
 
522
  while (remaining > 0)
523
    {
524
      if (bfd_bread (PRIV (vms_buf) + read_so_far, to_read, abfd) != to_read)
525
        {
526
          bfd_set_error (bfd_error_file_truncated);
527
          return 0;
528
        }
529
 
530
      read_so_far += to_read;
531
      remaining -= to_read;
532
 
533
      /* Eat trailing 0xff's.  */
534
      if (remaining > 0)
535
        while (PRIV (vms_buf) [read_so_far - 1] == 0xff)
536
          read_so_far--;
537
 
538
      to_read = MIN (VMS_BLOCK_SIZE, remaining);
539
    }
540
 
541
  /* Reset the record pointer.  */
542
  PRIV (vms_rec) = PRIV (vms_buf);
543
 
544
  return PRIV (rec_size);
545
}
546
 
547
/* Copy sized string (string with fixed size) to new allocated area
548
   size is string size (size of record)  */
549
 
550
char *
551
_bfd_vms_save_sized_string (unsigned char *str, int size)
552
{
553
  char *newstr = bfd_malloc ((bfd_size_type) size + 1);
554
 
555
  if (newstr == NULL)
556
    return NULL;
557
  strncpy (newstr, (char *) str, (size_t) size);
558
  newstr[size] = 0;
559
 
560
  return newstr;
561
}
562
 
563
/* Copy counted string (string with size at first byte) to new allocated area
564
   ptr points to size byte on entry  */
565
 
566
char *
567
_bfd_vms_save_counted_string (unsigned char *ptr)
568
{
569
  int len = *ptr++;
570
 
571
  return _bfd_vms_save_sized_string (ptr, len);
572
}
573
 
574
/* Stack routines for vms ETIR commands.  */
575
 
576
/* Push value and section index.  */
577
 
578
void
579
_bfd_vms_push (bfd * abfd, uquad val, int psect)
580
{
581
  static int last_psect;
582
 
583
#if VMS_DEBUG
584
  vms_debug (4, "<push %016lx (%d) at %d>\n", val, psect, PRIV (stackptr));
585
#endif
586
 
587
  if (psect >= 0)
588
    last_psect = psect;
589
 
590
  PRIV (stack[PRIV (stackptr)]).value = val;
591
  PRIV (stack[PRIV (stackptr)]).psect = last_psect;
592
  PRIV (stackptr)++;
593
  if (PRIV (stackptr) >= STACKSIZE)
594
    {
595
      bfd_set_error (bfd_error_bad_value);
596
      (*_bfd_error_handler) (_("Stack overflow (%d) in _bfd_vms_push"), PRIV (stackptr));
597
      exit (1);
598
    }
599
}
600
 
601
/* Pop value and section index.  */
602
 
603
uquad
604
_bfd_vms_pop (bfd * abfd, int *psect)
605
{
606
  uquad value;
607
 
608
  if (PRIV (stackptr) == 0)
609
    {
610
      bfd_set_error (bfd_error_bad_value);
611
      (*_bfd_error_handler) (_("Stack underflow in _bfd_vms_pop"));
612
      exit (1);
613
    }
614
  PRIV (stackptr)--;
615
  value = PRIV (stack[PRIV (stackptr)]).value;
616
  if ((psect != NULL) && (PRIV (stack[PRIV (stackptr)]).psect >= 0))
617
    *psect = PRIV (stack[PRIV (stackptr)]).psect;
618
 
619
#if VMS_DEBUG
620
  vms_debug (4, "<pop %016lx(%d)>\n", value, PRIV (stack[PRIV (stackptr)]).psect);
621
#endif
622
 
623
  return value;
624
}
625
 
626
/* Object output routines.   */
627
 
628
/* Begin new record or record header
629
   write 2 bytes rectype
630
   write 2 bytes record length (filled in at flush)
631
   write 2 bytes header type (ommitted if rechead == -1).  */
632
 
633
void
634
_bfd_vms_output_begin (bfd * abfd, int rectype, int rechead)
635
{
636
#if VMS_DEBUG
637
  vms_debug (6, "_bfd_vms_output_begin (type %d, head %d)\n", rectype,
638
              rechead);
639
#endif
640
 
641
  _bfd_vms_output_short (abfd, (unsigned int) rectype);
642
 
643
  /* Save current output position to fill in length later.   */
644
 
645
  if (PRIV (push_level) > 0)
646
    PRIV (length_pos) = PRIV (output_size);
647
 
648
#if VMS_DEBUG
649
  vms_debug (6, "_bfd_vms_output_begin: length_pos = %d\n",
650
              PRIV (length_pos));
651
#endif
652
 
653
  /* Placeholder for length.  */
654
  _bfd_vms_output_short (abfd, 0);
655
 
656
  if (rechead != -1)
657
    _bfd_vms_output_short (abfd, (unsigned int) rechead);
658
}
659
 
660
/* Set record/subrecord alignment.   */
661
 
662
void
663
_bfd_vms_output_alignment (bfd * abfd, int alignto)
664
{
665
#if VMS_DEBUG
666
  vms_debug (6, "_bfd_vms_output_alignment (%d)\n", alignto);
667
#endif
668
 
669
  PRIV (output_alignment) = alignto;
670
}
671
 
672
/* Prepare for subrecord fields.  */
673
 
674
void
675
_bfd_vms_output_push (bfd * abfd)
676
{
677
#if VMS_DEBUG
678
  vms_debug (6, "vms_output_push (pushed_size = %d)\n", PRIV (output_size));
679
#endif
680
 
681
  PRIV (push_level)++;
682
  PRIV (pushed_size) = PRIV (output_size);
683
}
684
 
685
/* End of subrecord fields.   */
686
 
687
void
688
_bfd_vms_output_pop (bfd * abfd)
689
{
690
#if VMS_DEBUG
691
  vms_debug (6, "vms_output_pop (pushed_size = %d)\n", PRIV (pushed_size));
692
#endif
693
 
694
  _bfd_vms_output_flush (abfd);
695
  PRIV (length_pos) = 2;
696
 
697
#if VMS_DEBUG
698
  vms_debug (6, "vms_output_pop: length_pos = %d\n", PRIV (length_pos));
699
#endif
700
 
701
  PRIV (pushed_size) = 0;
702
  PRIV (push_level)--;
703
}
704
 
705
/* Flush unwritten output, ends current record.  */
706
 
707
void
708
_bfd_vms_output_flush (bfd * abfd)
709
{
710
  int real_size = PRIV (output_size);
711
  int aligncount;
712
  int length;
713
 
714
#if VMS_DEBUG
715
  vms_debug (6, "_bfd_vms_output_flush (real_size = %d, pushed_size %d at lenpos %d)\n",
716
              real_size, PRIV (pushed_size), PRIV (length_pos));
717
#endif
718
 
719
  if (PRIV (push_level) > 0)
720
    length = real_size - PRIV (pushed_size);
721
  else
722
    length = real_size;
723
 
724
  if (length == 0)
725
    return;
726
  aligncount = (PRIV (output_alignment)
727
                - (length % PRIV (output_alignment))) % PRIV (output_alignment);
728
 
729
#if VMS_DEBUG
730
  vms_debug (6, "align: adding %d bytes\n", aligncount);
731
#endif
732
 
733
  while (aligncount-- > 0)
734
    {
735
      PRIV (output_buf)[real_size++] = 0;
736
      length++;
737
    }
738
 
739
  /* Put length to buffer.  */
740
  PRIV (output_size) = PRIV (length_pos);
741
  _bfd_vms_output_short (abfd, (unsigned int) length);
742
 
743
  if (PRIV (push_level) == 0)
744
    {
745
      /* File is open in undefined (UDF) format on VMS, but ultimately will be
746
         converted to variable length (VAR) format.  VAR format has a length
747
         word first which must be explicitly output in UDF format.  */
748
      bfd_bwrite (PRIV (output_buf) + 2, 2, abfd);
749
      bfd_bwrite (PRIV (output_buf), (size_t) real_size, abfd);
750
      PRIV (output_size) = 0;
751
    }
752
  else
753
    {
754
      PRIV (output_size) = real_size;
755
      PRIV (pushed_size) = PRIV (output_size);
756
    }
757
}
758
 
759
/* End record output.   */
760
 
761
void
762
_bfd_vms_output_end (bfd * abfd)
763
{
764
#if VMS_DEBUG
765
  vms_debug (6, "_bfd_vms_output_end\n");
766
#endif
767
 
768
  _bfd_vms_output_flush (abfd);
769
}
770
 
771
/* Check remaining buffer size
772
 
773
   Return what's left.  */
774
 
775
int
776
_bfd_vms_output_check (bfd * abfd, int size)
777
{
778
#if VMS_DEBUG
779
  vms_debug (6, "_bfd_vms_output_check (%d)\n", size);
780
#endif
781
 
782
  return (MAX_OUTREC_SIZE - (PRIV (output_size) + size + MIN_OUTREC_LUFT));
783
}
784
 
785
/* Output byte (8 bit) value.  */
786
 
787
void
788
_bfd_vms_output_byte (bfd * abfd, unsigned int value)
789
{
790
#if VMS_DEBUG
791
  vms_debug (6, "_bfd_vms_output_byte (%02x)\n", value);
792
#endif
793
 
794
  bfd_put_8 (abfd, value & 0xff, PRIV (output_buf) + PRIV (output_size));
795
  PRIV (output_size) += 1;
796
}
797
 
798
/* Output short (16 bit) value.  */
799
 
800
void
801
_bfd_vms_output_short (bfd * abfd, unsigned int value)
802
{
803
#if VMS_DEBUG
804
  vms_debug (6, "_bfd_vms_output_short (%04x)\n", value);
805
#endif
806
 
807
  bfd_put_16 (abfd, (bfd_vma) value & 0xffff,
808
              PRIV (output_buf) + PRIV (output_size));
809
  PRIV (output_size) += 2;
810
}
811
 
812
/* Output long (32 bit) value.  */
813
 
814
void
815
_bfd_vms_output_long (bfd * abfd, unsigned long value)
816
{
817
#if VMS_DEBUG
818
  vms_debug (6, "_bfd_vms_output_long (%08lx)\n", value);
819
#endif
820
 
821
  bfd_put_32 (abfd, (bfd_vma) value, PRIV (output_buf) + PRIV (output_size));
822
  PRIV (output_size) += 4;
823
}
824
 
825
/* Output quad (64 bit) value.  */
826
 
827
void
828
_bfd_vms_output_quad (bfd * abfd, uquad value)
829
{
830
#if VMS_DEBUG
831
  vms_debug (6, "_bfd_vms_output_quad (%016lx)\n", value);
832
#endif
833
 
834
  bfd_put_64(abfd, value, PRIV (output_buf) + PRIV (output_size));
835
  PRIV (output_size) += 8;
836
}
837
 
838
/* Output c-string as counted string.  */
839
 
840
void
841
_bfd_vms_output_counted (bfd * abfd, char *value)
842
{
843
  int len;
844
 
845
#if VMS_DEBUG
846
  vms_debug (6, "_bfd_vms_output_counted (%s)\n", value);
847
#endif
848
 
849
  len = strlen (value);
850
  if (len == 0)
851
    {
852
      (*_bfd_error_handler) (_("_bfd_vms_output_counted called with zero bytes"));
853
      return;
854
    }
855
  if (len > 255)
856
    {
857
      (*_bfd_error_handler) (_("_bfd_vms_output_counted called with too many bytes"));
858
      return;
859
    }
860
  _bfd_vms_output_byte (abfd, (unsigned int) len & 0xff);
861
  _bfd_vms_output_dump (abfd, (unsigned char *) value, len);
862
}
863
 
864
/* Output character area.  */
865
 
866
void
867
_bfd_vms_output_dump (bfd * abfd,
868
                      unsigned char *data,
869
                      int length)
870
{
871
#if VMS_DEBUG
872
  vms_debug (6, "_bfd_vms_output_dump (%d)\n", length);
873
#endif
874
 
875
  if (length == 0)
876
    return;
877
 
878
  memcpy (PRIV (output_buf) + PRIV (output_size), data, (size_t) length);
879
  PRIV (output_size) += length;
880
}
881
 
882
/* Output count bytes of value.  */
883
 
884
void
885
_bfd_vms_output_fill (bfd * abfd,
886
                      int value,
887
                      int count)
888
{
889
#if VMS_DEBUG
890
  vms_debug (6, "_bfd_vms_output_fill (val %02x times %d)\n", value, count);
891
#endif
892
 
893
  if (count == 0)
894
    return;
895
  memset (PRIV (output_buf) + PRIV (output_size), value, (size_t) count);
896
  PRIV (output_size) += count;
897
}
898
 
899
/* This hash routine borrowed from GNU-EMACS, and strengthened slightly.  ERY.  */
900
 
901
static int
902
hash_string (const char *ptr)
903
{
904
  const unsigned char *p = (unsigned char *) ptr;
905
  const unsigned char *end = p + strlen (ptr);
906
  unsigned char c;
907
  int hash = 0;
908
 
909
  while (p != end)
910
    {
911
      c = *p++;
912
      hash = ((hash << 3) + (hash << 15) + (hash >> 28) + c);
913
    }
914
  return hash;
915
}
916
 
917
/* Generate a length-hashed VMS symbol name (limited to maxlen chars).  */
918
 
919
char *
920
_bfd_vms_length_hash_symbol (bfd * abfd, const char *in, int maxlen)
921
{
922
  unsigned long result;
923
  int in_len;
924
  char *new_name;
925
  const char *old_name;
926
  int i;
927
  static char outbuf[EOBJ_S_C_SYMSIZ+1];
928
  char *out = outbuf;
929
 
930
#if VMS_DEBUG
931
  vms_debug (4, "_bfd_vms_length_hash_symbol \"%s\"\n", in);
932
#endif
933
 
934
  if (maxlen > EOBJ_S_C_SYMSIZ)
935
    maxlen = EOBJ_S_C_SYMSIZ;
936
 
937
  /* Save this for later.  */
938
  new_name = out;
939
 
940
  /* We may need to truncate the symbol, save the hash for later.  */
941
  in_len = strlen (in);
942
 
943
  result = (in_len > maxlen) ? hash_string (in) : 0;
944
 
945
  old_name = in;
946
 
947
  /* Do the length checking.  */
948
  if (in_len <= maxlen)
949
    i = in_len;
950
  else
951
    {
952
      if (PRIV (flag_hash_long_names))
953
        i = maxlen-9;
954
      else
955
        i = maxlen;
956
    }
957
 
958
  strncpy (out, in, (size_t) i);
959
  in += i;
960
  out += i;
961
 
962
  if ((in_len > maxlen)
963
      && PRIV (flag_hash_long_names))
964
    sprintf (out, "_%08lx", result);
965
  else
966
    *out = 0;
967
 
968
#if VMS_DEBUG
969
  vms_debug (4, "--> [%d]\"%s\"\n", strlen (outbuf), outbuf);
970
#endif
971
 
972
  if (in_len > maxlen
973
        && PRIV (flag_hash_long_names)
974
        && PRIV (flag_show_after_trunc))
975
    printf (_("Symbol %s replaced by %s\n"), old_name, new_name);
976
 
977
  return outbuf;
978
}
979
 
980
/* Allocate and initialize a new symbol.  */
981
 
982
static asymbol *
983
new_symbol (bfd * abfd, char *name)
984
{
985
  asymbol *symbol;
986
 
987
#if VMS_DEBUG
988
  _bfd_vms_debug (7,  "new_symbol %s\n", name);
989
#endif
990
 
991
  symbol = bfd_make_empty_symbol (abfd);
992
  if (symbol == 0)
993
    return symbol;
994
  symbol->name = name;
995
  symbol->section = (asection *)(unsigned long)-1;
996
 
997
  return symbol;
998
}
999
 
1000
/* Allocate and enter a new private symbol.  */
1001
 
1002
vms_symbol_entry *
1003
_bfd_vms_enter_symbol (bfd * abfd, char *name)
1004
{
1005
  vms_symbol_entry *entry;
1006
 
1007
#if VMS_DEBUG
1008
  _bfd_vms_debug (6,  "_bfd_vms_enter_symbol %s\n", name);
1009
#endif
1010
 
1011
  entry = (vms_symbol_entry *)
1012
          bfd_hash_lookup (PRIV (vms_symbol_table), name, FALSE, FALSE);
1013
  if (entry == 0)
1014
    {
1015
#if VMS_DEBUG
1016
      _bfd_vms_debug (8,  "creating hash entry for %s\n", name);
1017
#endif
1018
      entry = (vms_symbol_entry *) bfd_hash_lookup (PRIV (vms_symbol_table),
1019
                                                    name, TRUE, FALSE);
1020
      if (entry != 0)
1021
        {
1022
          asymbol *symbol;
1023
          symbol = new_symbol (abfd, name);
1024
          if (symbol != 0)
1025
            {
1026
              entry->symbol = symbol;
1027
              PRIV (gsd_sym_count)++;
1028
              abfd->symcount++;
1029
            }
1030
          else
1031
            entry = 0;
1032
        }
1033
      else
1034
        (*_bfd_error_handler) (_("failed to enter %s"), name);
1035
    }
1036
  else
1037
    {
1038
#if VMS_DEBUG
1039
      _bfd_vms_debug (8,  "found hash entry for %s\n", name);
1040
#endif
1041
    }
1042
 
1043
#if VMS_DEBUG
1044
  _bfd_vms_debug (7, "-> entry %p, entry->symbol %p\n", entry, entry->symbol);
1045
#endif
1046
  return entry;
1047
}

powered by: WebSVN 2.1.0

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