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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [bfd/] [vms-misc.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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