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

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [bfd/] [vms-misc.c] - Blame information for rev 1778

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

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

powered by: WebSVN 2.1.0

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