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

Subversion Repositories or1k

[/] [or1k/] [branches/] [oc/] [gdb-5.0/] [bfd/] [opncls.c] - Blame information for rev 1771

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

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

powered by: WebSVN 2.1.0

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