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

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [bfd/] [vms-misc.c] - Blame information for rev 1781

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

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

powered by: WebSVN 2.1.0

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