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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [bfd/] [opncls.c] - Blame information for rev 1776

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

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

powered by: WebSVN 2.1.0

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