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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [bfd/] [opncls.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* opncls.c -- open and close a BFD.
2
   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
3
   2001, 2002
4
   Free Software Foundation, Inc.
5
 
6
   Written by Cygnus Support.
7
 
8
   This file is part of BFD, the Binary File Descriptor library.
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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
23
 
24
#include "bfd.h"
25
#include "sysdep.h"
26
#include "objalloc.h"
27
#include "libbfd.h"
28
 
29
#ifndef S_IXUSR
30
#define S_IXUSR 0100    /* Execute by owner.  */
31
#endif
32
#ifndef S_IXGRP
33
#define S_IXGRP 0010    /* Execute by group.  */
34
#endif
35
#ifndef S_IXOTH
36
#define S_IXOTH 0001    /* Execute by others.  */
37
#endif
38
 
39
/* fdopen is a loser -- we should use stdio exclusively.  Unfortunately
40
   if we do that we can't use fcntl.  */
41
 
42
/* Return a new BFD.  All BFD's are allocated through this routine.  */
43
 
44
bfd *
45
_bfd_new_bfd ()
46
{
47
  bfd *nbfd;
48
 
49
  nbfd = (bfd *) bfd_zmalloc ((bfd_size_type) sizeof (bfd));
50
  if (nbfd == NULL)
51
    return NULL;
52
 
53
  nbfd->memory = (PTR) objalloc_create ();
54
  if (nbfd->memory == NULL)
55
    {
56
      bfd_set_error (bfd_error_no_memory);
57
      free (nbfd);
58
      return NULL;
59
    }
60
 
61
  nbfd->arch_info = &bfd_default_arch_struct;
62
 
63
  nbfd->direction = no_direction;
64
  nbfd->iostream = NULL;
65
  nbfd->where = 0;
66
  if (!bfd_hash_table_init (&nbfd->section_htab, bfd_section_hash_newfunc))
67
    {
68
      free (nbfd);
69
      return NULL;
70
    }
71
  nbfd->sections = (asection *) NULL;
72
  nbfd->section_tail = &nbfd->sections;
73
  nbfd->format = bfd_unknown;
74
  nbfd->my_archive = (bfd *) NULL;
75
  nbfd->origin = 0;
76
  nbfd->opened_once = false;
77
  nbfd->output_has_begun = false;
78
  nbfd->section_count = 0;
79
  nbfd->usrdata = (PTR) NULL;
80
  nbfd->cacheable = false;
81
  nbfd->flags = BFD_NO_FLAGS;
82
  nbfd->mtime_set = false;
83
 
84
  return nbfd;
85
}
86
 
87
/* Allocate a new BFD as a member of archive OBFD.  */
88
 
89
bfd *
90
_bfd_new_bfd_contained_in (obfd)
91
     bfd *obfd;
92
{
93
  bfd *nbfd;
94
 
95
  nbfd = _bfd_new_bfd ();
96
  if (nbfd == NULL)
97
    return NULL;
98
  nbfd->xvec = obfd->xvec;
99
  nbfd->my_archive = obfd;
100
  nbfd->direction = read_direction;
101
  nbfd->target_defaulted = obfd->target_defaulted;
102
  return nbfd;
103
}
104
 
105
/* Delete a BFD.  */
106
 
107
void
108
_bfd_delete_bfd (abfd)
109
     bfd *abfd;
110
{
111
  bfd_hash_table_free (&abfd->section_htab);
112
  objalloc_free ((struct objalloc *) abfd->memory);
113
  free (abfd);
114
}
115
 
116
/*
117
SECTION
118
        Opening and closing BFDs
119
 
120
*/
121
 
122
/*
123
FUNCTION
124
        bfd_openr
125
 
126
SYNOPSIS
127
        bfd *bfd_openr(const char *filename, const char *target);
128
 
129
DESCRIPTION
130
        Open the file @var{filename} (using <<fopen>>) with the target
131
        @var{target}.  Return a pointer to the created BFD.
132
 
133
        Calls <<bfd_find_target>>, so @var{target} is interpreted as by
134
        that function.
135
 
136
        If <<NULL>> is returned then an error has occured.   Possible errors
137
        are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> or <<system_call>> error.
138
*/
139
 
140
bfd *
141
bfd_openr (filename, target)
142
     const char *filename;
143
     const char *target;
144
{
145
  bfd *nbfd;
146
  const bfd_target *target_vec;
147
 
148
  nbfd = _bfd_new_bfd ();
149
  if (nbfd == NULL)
150
    return NULL;
151
 
152
  target_vec = bfd_find_target (target, nbfd);
153
  if (target_vec == NULL)
154
    {
155
      _bfd_delete_bfd (nbfd);
156
      return NULL;
157
    }
158
 
159
  nbfd->filename = filename;
160
  nbfd->direction = read_direction;
161
 
162
  if (bfd_open_file (nbfd) == NULL)
163
    {
164
      /* File didn't exist, or some such.  */
165
      bfd_set_error (bfd_error_system_call);
166
      _bfd_delete_bfd (nbfd);
167
      return NULL;
168
    }
169
 
170
  return nbfd;
171
}
172
 
173
/* Don't try to `optimize' this function:
174
 
175
   o - We lock using stack space so that interrupting the locking
176
       won't cause a storage leak.
177
   o - We open the file stream last, since we don't want to have to
178
       close it if anything goes wrong.  Closing the stream means closing
179
       the file descriptor too, even though we didn't open it.  */
180
/*
181
FUNCTION
182
         bfd_fdopenr
183
 
184
SYNOPSIS
185
         bfd *bfd_fdopenr(const char *filename, const char *target, int fd);
186
 
187
DESCRIPTION
188
         <<bfd_fdopenr>> is to <<bfd_fopenr>> much like <<fdopen>> is to <<fopen>>.
189
         It opens a BFD on a file already described by the @var{fd}
190
         supplied.
191
 
192
         When the file is later <<bfd_close>>d, the file descriptor will be closed.
193
 
194
         If the caller desires that this file descriptor be cached by BFD
195
         (opened as needed, closed as needed to free descriptors for
196
         other opens), with the supplied @var{fd} used as an initial
197
         file descriptor (but subject to closure at any time), call
198
         bfd_set_cacheable(bfd, 1) on the returned BFD.  The default is to
199
         assume no cacheing; the file descriptor will remain open until
200
         <<bfd_close>>, and will not be affected by BFD operations on other
201
         files.
202
 
203
         Possible errors are <<bfd_error_no_memory>>, <<bfd_error_invalid_target>> and <<bfd_error_system_call>>.
204
*/
205
 
206
bfd *
207
bfd_fdopenr (filename, target, fd)
208
     const char *filename;
209
     const char *target;
210
     int fd;
211
{
212
  bfd *nbfd;
213
  const bfd_target *target_vec;
214
  int fdflags;
215
 
216
  bfd_set_error (bfd_error_system_call);
217
#if ! defined(HAVE_FCNTL) || ! defined(F_GETFL)
218
  fdflags = O_RDWR;                     /* Assume full access.  */
219
#else
220
  fdflags = fcntl (fd, F_GETFL, NULL);
221
#endif
222
  if (fdflags == -1)
223
    return NULL;
224
 
225
  nbfd = _bfd_new_bfd ();
226
  if (nbfd == NULL)
227
    return NULL;
228
 
229
  target_vec = bfd_find_target (target, nbfd);
230
  if (target_vec == NULL)
231
    {
232
      _bfd_delete_bfd (nbfd);
233
      return NULL;
234
    }
235
 
236
#ifndef HAVE_FDOPEN
237
  nbfd->iostream = (PTR) fopen (filename, FOPEN_RB);
238
#else
239
  /* (O_ACCMODE) parens are to avoid Ultrix header file bug.  */
240
  switch (fdflags & (O_ACCMODE))
241
    {
242
    case O_RDONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RB);   break;
243
    case O_WRONLY: nbfd->iostream = (PTR) fdopen (fd, FOPEN_RUB);  break;
244
    case O_RDWR:   nbfd->iostream = (PTR) fdopen (fd, FOPEN_RUB);  break;
245
    default: abort ();
246
    }
247
#endif
248
 
249
  if (nbfd->iostream == NULL)
250
    {
251
      _bfd_delete_bfd (nbfd);
252
      return NULL;
253
    }
254
 
255
  /* OK, put everything where it belongs.  */
256
  nbfd->filename = filename;
257
 
258
  /* As a special case we allow a FD open for read/write to
259
     be written through, although doing so requires that we end
260
     the previous clause with a preposition.  */
261
  /* (O_ACCMODE) parens are to avoid Ultrix header file bug.  */
262
  switch (fdflags & (O_ACCMODE))
263
    {
264
    case O_RDONLY: nbfd->direction = read_direction; break;
265
    case O_WRONLY: nbfd->direction = write_direction; break;
266
    case O_RDWR: nbfd->direction = both_direction; break;
267
    default: abort ();
268
    }
269
 
270
  if (! bfd_cache_init (nbfd))
271
    {
272
      _bfd_delete_bfd (nbfd);
273
      return NULL;
274
    }
275
  nbfd->opened_once = true;
276
 
277
  return nbfd;
278
}
279
 
280
/*
281
FUNCTION
282
        bfd_openstreamr
283
 
284
SYNOPSIS
285
        bfd *bfd_openstreamr(const char *, const char *, PTR);
286
 
287
DESCRIPTION
288
 
289
        Open a BFD for read access on an existing stdio stream.  When
290
        the BFD is passed to <<bfd_close>>, the stream will be closed.
291
*/
292
 
293
bfd *
294
bfd_openstreamr (filename, target, streamarg)
295
     const char *filename;
296
     const char *target;
297
     PTR streamarg;
298
{
299
  FILE *stream = (FILE *) streamarg;
300
  bfd *nbfd;
301
  const bfd_target *target_vec;
302
 
303
  nbfd = _bfd_new_bfd ();
304
  if (nbfd == NULL)
305
    return NULL;
306
 
307
  target_vec = bfd_find_target (target, nbfd);
308
  if (target_vec == NULL)
309
    {
310
      _bfd_delete_bfd (nbfd);
311
      return NULL;
312
    }
313
 
314
  nbfd->iostream = (PTR) stream;
315
  nbfd->filename = filename;
316
  nbfd->direction = read_direction;
317
 
318
  if (! bfd_cache_init (nbfd))
319
    {
320
      _bfd_delete_bfd (nbfd);
321
      return NULL;
322
    }
323
 
324
  return nbfd;
325
}
326
 
327
/* bfd_openw -- open for writing.
328
   Returns a pointer to a freshly-allocated BFD on success, or NULL.
329
 
330
   See comment by bfd_fdopenr before you try to modify this function.  */
331
 
332
/*
333
FUNCTION
334
        bfd_openw
335
 
336
SYNOPSIS
337
        bfd *bfd_openw(const char *filename, const char *target);
338
 
339
DESCRIPTION
340
        Create a BFD, associated with file @var{filename}, using the
341
        file format @var{target}, and return a pointer to it.
342
 
343
        Possible errors are <<bfd_error_system_call>>, <<bfd_error_no_memory>>,
344
        <<bfd_error_invalid_target>>.
345
*/
346
 
347
bfd *
348
bfd_openw (filename, target)
349
     const char *filename;
350
     const char *target;
351
{
352
  bfd *nbfd;
353
  const bfd_target *target_vec;
354
 
355
  /* nbfd has to point to head of malloc'ed block so that bfd_close may
356
     reclaim it correctly.  */
357
  nbfd = _bfd_new_bfd ();
358
  if (nbfd == NULL)
359
    return NULL;
360
 
361
  target_vec = bfd_find_target (target, nbfd);
362
  if (target_vec == NULL)
363
    {
364
      _bfd_delete_bfd (nbfd);
365
      return NULL;
366
    }
367
 
368
  nbfd->filename = filename;
369
  nbfd->direction = write_direction;
370
 
371
  if (bfd_open_file (nbfd) == NULL)
372
    {
373
      /* File not writeable, etc.  */
374
      bfd_set_error (bfd_error_system_call);
375
      _bfd_delete_bfd (nbfd);
376
      return NULL;
377
  }
378
 
379
  return nbfd;
380
}
381
 
382
/*
383
 
384
FUNCTION
385
        bfd_close
386
 
387
SYNOPSIS
388
        boolean bfd_close(bfd *abfd);
389
 
390
DESCRIPTION
391
 
392
        Close a BFD. If the BFD was open for writing,
393
        then pending operations are completed and the file written out
394
        and closed. If the created file is executable, then
395
        <<chmod>> is called to mark it as such.
396
 
397
        All memory attached to the BFD is released.
398
 
399
        The file descriptor associated with the BFD is closed (even
400
        if it was passed in to BFD by <<bfd_fdopenr>>).
401
 
402
RETURNS
403
        <<true>> is returned if all is ok, otherwise <<false>>.
404
*/
405
 
406
 
407
boolean
408
bfd_close (abfd)
409
     bfd *abfd;
410
{
411
  boolean ret;
412
 
413
  if (bfd_write_p (abfd))
414
    {
415
      if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
416
        return false;
417
    }
418
 
419
  if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
420
    return false;
421
 
422
  ret = bfd_cache_close (abfd);
423
 
424
  /* If the file was open for writing and is now executable,
425
     make it so.  */
426
  if (ret
427
      && abfd->direction == write_direction
428
      && abfd->flags & EXEC_P)
429
    {
430
      struct stat buf;
431
 
432
      if (stat (abfd->filename, &buf) == 0)
433
        {
434
          unsigned int mask = umask (0);
435
 
436
          umask (mask);
437
          chmod (abfd->filename,
438
                 (0777
439
                  & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
440
        }
441
    }
442
 
443
  _bfd_delete_bfd (abfd);
444
 
445
  return ret;
446
}
447
 
448
/*
449
FUNCTION
450
        bfd_close_all_done
451
 
452
SYNOPSIS
453
        boolean bfd_close_all_done(bfd *);
454
 
455
DESCRIPTION
456
        Close a BFD.  Differs from <<bfd_close>>
457
        since it does not complete any pending operations.  This
458
        routine would be used if the application had just used BFD for
459
        swapping and didn't want to use any of the writing code.
460
 
461
        If the created file is executable, then <<chmod>> is called
462
        to mark it as such.
463
 
464
        All memory attached to the BFD is released.
465
 
466
RETURNS
467
        <<true>> is returned if all is ok, otherwise <<false>>.
468
*/
469
 
470
boolean
471
bfd_close_all_done (abfd)
472
     bfd *abfd;
473
{
474
  boolean ret;
475
 
476
  ret = bfd_cache_close (abfd);
477
 
478
  /* If the file was open for writing and is now executable,
479
     make it so.  */
480
  if (ret
481
      && abfd->direction == write_direction
482
      && abfd->flags & EXEC_P)
483
    {
484
      struct stat buf;
485
 
486
      if (stat (abfd->filename, &buf) == 0)
487
        {
488
          unsigned int mask = umask (0);
489
 
490
          umask (mask);
491
          chmod (abfd->filename,
492
                 (0777
493
                  & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
494
        }
495
    }
496
 
497
  _bfd_delete_bfd (abfd);
498
 
499
  return ret;
500
}
501
 
502
/*
503
FUNCTION
504
        bfd_create
505
 
506
SYNOPSIS
507
        bfd *bfd_create(const char *filename, bfd *templ);
508
 
509
DESCRIPTION
510
        Create a new BFD in the manner of
511
        <<bfd_openw>>, but without opening a file. The new BFD
512
        takes the target from the target used by @var{template}. The
513
        format is always set to <<bfd_object>>.
514
*/
515
 
516
bfd *
517
bfd_create (filename, templ)
518
     const char *filename;
519
     bfd *templ;
520
{
521
  bfd *nbfd;
522
 
523
  nbfd = _bfd_new_bfd ();
524
  if (nbfd == NULL)
525
    return NULL;
526
  nbfd->filename = filename;
527
  if (templ)
528
    nbfd->xvec = templ->xvec;
529
  nbfd->direction = no_direction;
530
  bfd_set_format (nbfd, bfd_object);
531
 
532
  return nbfd;
533
}
534
 
535
/*
536
FUNCTION
537
        bfd_make_writable
538
 
539
SYNOPSIS
540
        boolean bfd_make_writable(bfd *abfd);
541
 
542
DESCRIPTION
543
        Takes a BFD as created by <<bfd_create>> and converts it
544
        into one like as returned by <<bfd_openw>>.  It does this
545
        by converting the BFD to BFD_IN_MEMORY.  It's assumed that
546
        you will call <<bfd_make_readable>> on this bfd later.
547
 
548
RETURNS
549
        <<true>> is returned if all is ok, otherwise <<false>>.
550
*/
551
 
552
boolean
553
bfd_make_writable(abfd)
554
     bfd *abfd;
555
{
556
  struct bfd_in_memory *bim;
557
 
558
  if (abfd->direction != no_direction)
559
    {
560
      bfd_set_error (bfd_error_invalid_operation);
561
      return false;
562
    }
563
 
564
  bim = ((struct bfd_in_memory *)
565
         bfd_malloc ((bfd_size_type) sizeof (struct bfd_in_memory)));
566
  abfd->iostream = (PTR) bim;
567
  /* bfd_bwrite will grow these as needed.  */
568
  bim->size = 0;
569
  bim->buffer = 0;
570
 
571
  abfd->flags |= BFD_IN_MEMORY;
572
  abfd->direction = write_direction;
573
  abfd->where = 0;
574
 
575
  return true;
576
}
577
 
578
/*
579
FUNCTION
580
        bfd_make_readable
581
 
582
SYNOPSIS
583
        boolean bfd_make_readable(bfd *abfd);
584
 
585
DESCRIPTION
586
        Takes a BFD as created by <<bfd_create>> and
587
        <<bfd_make_writable>> and converts it into one like as
588
        returned by <<bfd_openr>>.  It does this by writing the
589
        contents out to the memory buffer, then reversing the
590
        direction.
591
 
592
RETURNS
593
        <<true>> is returned if all is ok, otherwise <<false>>.  */
594
 
595
boolean
596
bfd_make_readable(abfd)
597
     bfd *abfd;
598
{
599
  if (abfd->direction != write_direction || !(abfd->flags & BFD_IN_MEMORY))
600
    {
601
      bfd_set_error (bfd_error_invalid_operation);
602
      return false;
603
    }
604
 
605
  if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
606
    return false;
607
 
608
  if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
609
    return false;
610
 
611
 
612
  abfd->arch_info = &bfd_default_arch_struct;
613
 
614
  abfd->where = 0;
615
  abfd->format = bfd_unknown;
616
  abfd->my_archive = (bfd *) NULL;
617
  abfd->origin = 0;
618
  abfd->opened_once = false;
619
  abfd->output_has_begun = false;
620
  abfd->section_count = 0;
621
  abfd->usrdata = (PTR) NULL;
622
  abfd->cacheable = false;
623
  abfd->flags = BFD_IN_MEMORY;
624
  abfd->mtime_set = false;
625
 
626
  abfd->target_defaulted = true;
627
  abfd->direction = read_direction;
628
  abfd->sections = 0;
629
  abfd->symcount = 0;
630
  abfd->outsymbols = 0;
631
  abfd->tdata.any = 0;
632
 
633
  bfd_section_list_clear (abfd);
634
  bfd_check_format (abfd, bfd_object);
635
 
636
  return true;
637
}
638
 
639
/*
640
INTERNAL_FUNCTION
641
        bfd_alloc
642
 
643
SYNOPSIS
644
        PTR bfd_alloc (bfd *abfd, size_t wanted);
645
 
646
DESCRIPTION
647
        Allocate a block of @var{wanted} bytes of memory attached to
648
        <<abfd>> and return a pointer to it.
649
*/
650
 
651
 
652
PTR
653
bfd_alloc (abfd, size)
654
     bfd *abfd;
655
     bfd_size_type size;
656
{
657
  PTR ret;
658
 
659
  if (size != (unsigned long) size)
660
    {
661
      bfd_set_error (bfd_error_no_memory);
662
      return NULL;
663
    }
664
 
665
  ret = objalloc_alloc (abfd->memory, (unsigned long) size);
666
  if (ret == NULL)
667
    bfd_set_error (bfd_error_no_memory);
668
  return ret;
669
}
670
 
671
PTR
672
bfd_zalloc (abfd, size)
673
     bfd *abfd;
674
     bfd_size_type size;
675
{
676
  PTR res;
677
 
678
  res = bfd_alloc (abfd, size);
679
  if (res)
680
    memset (res, 0, (size_t) size);
681
  return res;
682
}
683
 
684
/* Free a block allocated for a BFD.
685
   Note:  Also frees all more recently allocated blocks!  */
686
 
687
void
688
bfd_release (abfd, block)
689
     bfd *abfd;
690
     PTR block;
691
{
692
  objalloc_free_block ((struct objalloc *) abfd->memory, block);
693
}

powered by: WebSVN 2.1.0

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