* targets.c (proto write_armap). Changed orl_count to unsigned.

* opncls.c (bfd_close_all_done). Added so that generative
	programs like gas can close a bfd without causing bfd confusion.
	* libbfd.h (changed becuase of protos)
	* amdcoff.c: messed with the way that jmp displacements are
	calcualated. This may not yet be totally correct.
	* archive.c (coff_write_armap): rewrote the way that ranlibs are
	written out.
	* coffcode.h (fixup_symbol_value): now doesn't core dump if a non
	abs symbol has no section (like a register symbol).
	(coff_write_symbol) now zeros auxent before filling it up to help
	with sensitive applications.
	* libbfd.c (bfd_write_bigendian_4byte_int): added.
This commit is contained in:
Steve Chamberlain 1991-10-21 16:42:54 +00:00
parent 7955ad1c4d
commit f58809fd41
6 changed files with 262 additions and 186 deletions

View file

@ -1,7 +1,33 @@
Mon Oct 21 09:34:11 1991 Steve Chamberlain (steve at rtl.cygnus.com)
* targets.c (proto write_armap). Changed orl_count to unsigned.
* opncls.c (bfd_close_all_done). Added so that generative
programs like gas can close a bfd without causing bfd confusion.
* libbfd.h (changed becuase of protos)
* amdcoff.c: messed with the way that jmp displacements are
calcualated. This may not yet be totally correct.
* archive.c (coff_write_armap): rewrote the way that ranlibs are
written out.
* coffcode.h (fixup_symbol_value): now doesn't core dump if a non
abs symbol has no section (like a register symbol).
(coff_write_symbol) now zeros auxent before filling it up to help
with sensitive applications.
* libbfd.c (bfd_write_bigendian_4byte_int): added.
Wed Oct 16 22:58:45 1991 John Gilmore (gnu at cygnus.com)
* bfd.c: Make sure we don't get a macro strerror().
* opncls.c (bfd_fdopenr): If FASCIST_FDOPEN, use "r", not "r+".
* trad-core.c (trad_unix_core_file_failing_command): Suppress
attempt to recover command, ifdef NO_CORE_COMMAND.
* hosts/h-tahoe.h: Add FASCIST_FDOPEN and NO_CORE_COMMAND;
revamp HOST_*, etc.
* hosts/h-i386v.h: Use <utime.h>, not <sys/utime.h>, unlike POSIX.
Wed Oct 16 12:43:49 1991 Per Bothner (bothner at cygnus.com) Wed Oct 16 12:43:49 1991 Per Bothner (bothner at cygnus.com)
* archive.c (bsd_write_argmap): The size of the ranlib structures * archive.c (bsd_write_argmap): The size of the ranlib structures
should not include teh size field itself. should not include the size field itself.
* aoutx.h, libaout.h (NAME(aout, sizeof_headers)): Use * aoutx.h, libaout.h (NAME(aout, sizeof_headers)): Use
adata(abfd)->exec_bytes_size field instead of constant macro, adata(abfd)->exec_bytes_size field instead of constant macro,
because aoutx.h compiles to a simple .o file shared by because aoutx.h compiles to a simple .o file shared by

View file

@ -28,7 +28,7 @@ Archives are supported in BFD in @code{archive.c}.
An archive is represented internally just like another BFD, with a An archive is represented internally just like another BFD, with a
pointer to a chain of contained BFDs. Archives can be created by pointer to a chain of contained BFDs. Archives can be created by
opening BFDs, linking them together and attatching them as children to opening BFDs, linking them together and attaching them as children to
another BFD and then closing the parent BFD. another BFD and then closing the parent BFD.
*-*/ *-*/
@ -41,8 +41,8 @@ another BFD and then closing the parent BFD.
/* $Id$ */ /* $Id$ */
#include <sysdep.h>
#include "bfd.h" #include "bfd.h"
#include "sysdep.h"
#include "libbfd.h" #include "libbfd.h"
#include "ar.h" #include "ar.h"
#include "ranlib.h" #include "ranlib.h"
@ -124,9 +124,12 @@ _bfd_create_empty_archive_element_shell (obfd)
} }
/*proto* bfd_set_archive_head /*proto* bfd_set_archive_head
Used whilst processing archives. Sets the head of the chain of BFDs Used whilst processing archives. Sets the head of the chain of BFDs
contained in an archive to @var{new_head}. (see chapter on archives) contained in an archive to @var{new_head}. (see chapter on archives)
*; PROTO(boolean, bfd_set_archive_head, (bfd *output, bfd *new_head)); *; PROTO(boolean, bfd_set_archive_head, (bfd *output, bfd *new_head));
*/ */
boolean boolean
@ -340,6 +343,7 @@ get_elt_at_filepos (archive, filepos)
} }
/*proto* bfd_get_elt_at_index /*proto* bfd_get_elt_at_index
Return the sub bfd contained within the archive at archive index n.
*; PROTO(bfd *, bfd_get_elt_at_index, (bfd *, int)); *; PROTO(bfd *, bfd_get_elt_at_index, (bfd *, int));
@ -562,12 +566,15 @@ bfd_slurp_coff_armap (abfd)
} }
/* The coff armap must be read sequentially. So we construct a bsd-style /* The coff armap must be read sequentially. So we construct a bsd-style
one in core all at once, for simplicity. */ one in core all at once, for simplicity.
stringsize = mapdata->parsed_size - (4 * (*raw_armap)) - 4; It seems that all numeric information in a coff archive is always
in big endian format, nomatter the host or target. */
stringsize = mapdata->parsed_size - (4 * (_do_getb32((PTR)raw_armap))) - 4;
{ {
unsigned int nsymz = *raw_armap; unsigned int nsymz = _do_getb32( (PTR)raw_armap);
unsigned int carsym_size = (nsymz * sizeof (carsym)); unsigned int carsym_size = (nsymz * sizeof (carsym));
unsigned int ptrsize = (4 * nsymz); unsigned int ptrsize = (4 * nsymz);
unsigned int i; unsigned int i;
@ -586,14 +593,14 @@ bfd_slurp_coff_armap (abfd)
for (i = 0; i < nsymz; i++) for (i = 0; i < nsymz; i++)
{ {
rawptr = raw_armap + i + 1; rawptr = raw_armap + i + 1;
carsyms->file_offset = *rawptr; carsyms->file_offset = _do_getb32((PTR)rawptr);
carsyms->name = stringbase; carsyms->name = stringbase;
for (; *(stringbase++);); for (; *(stringbase++););
carsyms++; carsyms++;
} }
*stringbase = 0; *stringbase = 0;
} }
ardata->symdef_count = *raw_armap; ardata->symdef_count = _do_getb32((PTR)raw_armap);
ardata->first_file_filepos = bfd_tell (abfd); ardata->first_file_filepos = bfd_tell (abfd);
/* Pad to an even boundary if you have to */ /* Pad to an even boundary if you have to */
ardata->first_file_filepos += (ardata->first_file_filepos) %2; ardata->first_file_filepos += (ardata->first_file_filepos) %2;
@ -1153,9 +1160,9 @@ bsd_write_armap (arch, elength, map, orl_count, stridx)
int orl_count; int orl_count;
int stridx; int stridx;
{ {
unsigned int ranlibsize = (orl_count * sizeof (struct ranlib)) + 4; unsigned int ranlibsize = orl_count * sizeof (struct ranlib);
unsigned int stringsize = stridx + 4; unsigned int stringsize = stridx + 4;
unsigned int mapsize = stringsize + ranlibsize; unsigned int mapsize = stringsize + ranlibsize + 4;
file_ptr firstreal; file_ptr firstreal;
bfd *current = arch->archive_head; bfd *current = arch->archive_head;
bfd *last_elt = current; /* last element arch seen */ bfd *last_elt = current; /* last element arch seen */
@ -1233,19 +1240,22 @@ bsd_write_armap (arch, elength, map, orl_count, stridx)
*/ */
boolean boolean
coff_write_armap (arch, elength, map, orl_count, stridx) coff_write_armap (arch, elength, map, symbol_count, stridx)
bfd *arch; bfd *arch;
unsigned int elength; unsigned int elength;
struct orl *map; struct orl *map;
int orl_count; unsigned int symbol_count;
int stridx; int stridx;
{ {
unsigned int ranlibsize = (orl_count * 4) + 4; /* The size of the ranlib is the number of exported symbols in the
archive * the number of bytes in a int, + an int for the count */
unsigned int ranlibsize = (symbol_count * 4) + 4;
unsigned int stringsize = stridx; unsigned int stringsize = stridx;
unsigned int mapsize = stringsize + ranlibsize; unsigned int mapsize = stringsize + ranlibsize;
file_ptr archive_member_file_ptr; file_ptr archive_member_file_ptr;
bfd *current = arch->archive_head; bfd *current = arch->archive_head;
int last_eltno = 0; /* last element arch seen */ bfd *last_elt = current; /* last element arch seen */
int count; int count;
struct ar_hdr hdr; struct ar_hdr hdr;
unsigned int i; unsigned int i;
@ -1253,8 +1263,8 @@ coff_write_armap (arch, elength, map, orl_count, stridx)
if (padit) mapsize ++; if (padit) mapsize ++;
archive_member_file_ptr = /* work out where the first object file will go in the archive */
mapsize + elength + sizeof (struct ar_hdr) + SARMAG; archive_member_file_ptr = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
memset ((char *)(&hdr), 0, sizeof (struct ar_hdr)); memset ((char *)(&hdr), 0, sizeof (struct ar_hdr));
hdr.ar_name[0] = '/'; hdr.ar_name[0] = '/';
@ -1267,37 +1277,44 @@ coff_write_armap (arch, elength, map, orl_count, stridx)
hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n'; hdr.ar_fmag[0] = '`'; hdr.ar_fmag[1] = '\n';
for (i = 0; i < sizeof (struct ar_hdr); i++) for (i = 0; i < sizeof (struct ar_hdr); i++)
if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' '; if (((char *)(&hdr))[i] == '\0') (((char *)(&hdr))[i]) = ' ';
/* Write the ar header for this item and the number of symbols */ /* Write the ar header for this item and the number of symbols */
bfd_write ((PTR)&hdr, 1, sizeof (struct ar_hdr), arch); bfd_write ((PTR)&hdr, 1, sizeof (struct ar_hdr), arch);
/* FIXME, this needs to be byte-swapped */
bfd_write ((PTR)&orl_count, 1, sizeof (orl_count), arch); bfd_write_bigendian_4byte_int(arch, symbol_count);
/* Two passes, first write the file offsets for each symbol - /* Two passes, first write the file offsets for each symbol -
remembering that each offset is on a two byte boundary remembering that each offset is on a two byte boundary
*/ */
for (count = 0; count < orl_count; count++) { /* Write out the file offset for the file associated with each
while ((map[count]).pos != last_eltno) { symbol, and remember to keep the offsets padded out */
/* If this is the first time we've seen a ref to this archive
then remember it's size */ current = arch->archive_head;
archive_member_file_ptr += count = 0;
arelt_size (current) + sizeof (struct ar_hdr); while (current != (bfd *)NULL && count < symbol_count) {
archive_member_file_ptr += archive_member_file_ptr % 2; /* For each symbol which is used defined in this object, write out
current = current->next; the object file's address in the archive */
last_eltno++;
while (((bfd *)(map[count]).pos) == current) {
bfd_write_bigendian_4byte_int(arch, archive_member_file_ptr);
count++;
} }
/* FIXME, this needs to be byte-swapped */ /* Add size of this archive entry */
bfd_write ((PTR)&archive_member_file_ptr, archive_member_file_ptr += arelt_size (current) + sizeof (struct
1, ar_hdr);
sizeof (archive_member_file_ptr), /* remember aboout the even alignment */
arch); archive_member_file_ptr += archive_member_file_ptr % 2;
current = current->next;
} }
/* now write the strings themselves */ /* now write the strings themselves */
for (count = 0; count < orl_count; count++) { for (count = 0; count < symbol_count; count++) {
bfd_write ((PTR)*((map[count]).name), bfd_write ((PTR)*((map[count]).name),
1, 1,
strlen (*((map[count]).name))+1, arch); strlen (*((map[count]).name))+1, arch);
@ -1306,7 +1323,7 @@ coff_write_armap (arch, elength, map, orl_count, stridx)
/* The spec sez this should be a newline. But in order to be /* The spec sez this should be a newline. But in order to be
bug-compatible for arc960 we use a null. */ bug-compatible for arc960 we use a null. */
if (padit) if (padit)
bfd_write("\0",1,1,arch); bfd_write("\0",1,1,arch);
return true; return true;
} }

View file

@ -63,113 +63,120 @@ asymbol *symbol_in;
unsigned char *data; unsigned char *data;
asection *input_section; asection *input_section;
{ {
static unsigned long part1_consth_active=0; static unsigned long part1_consth_active=0;
static unsigned long part1_consth_value; static unsigned long part1_consth_value;
unsigned long insn, value, sym_value; unsigned long insn, value, sym_value;
unsigned short r_type; unsigned short r_type;
/* bfd_reloc_status_type result;*/ /* bfd_reloc_status_type result;*/
/* coff_symbol_type *cs = coffsymbol(symbol_in);*/ /* coff_symbol_type *cs = coffsymbol(symbol_in);*/
r_type = reloc_entry->howto->type; r_type = reloc_entry->howto->type;
/* FIXME: Do we need to check for partial linking here */ /* FIXME: Do we need to check for partial linking here */
if (symbol_in && (symbol_in->flags & BSF_UNDEFINED)) { if (symbol_in && (symbol_in->flags & BSF_UNDEFINED)) {
/* Keep the state machine happy in case we're called again */ /* Keep the state machine happy in case we're called again */
if (r_type == R_IHIHALF) { if (r_type == R_IHIHALF) {
part1_consth_active = 1; part1_consth_active = 1;
part1_consth_value = 0; part1_consth_value = 0;
}
return(bfd_reloc_undefined);
} }
return(bfd_reloc_undefined);
}
if ((part1_consth_active) && (r_type != R_IHCONST)) { if ((part1_consth_active) && (r_type != R_IHCONST)) {
fprintf(stderr,"Relocation problem : ");
fprintf(stderr,"Missing IHCONST in module %s\n",abfd->filename);
part1_consth_active = 0;
return(bfd_reloc_dangerous);
}
insn = bfd_get_32(abfd, data + reloc_entry->address);
sym_value = get_symbol_value(symbol_in);
switch (r_type) {
case R_IREL:
/* We don't want to use the value already in the offset..
The field isn't big enought to hold the full range of values.
Will the break anything ? Steve@cygnus */
value = 0; /*EXTRACT_HWORD(insn) << 2;*/
value += sym_value + reloc_entry->addend;
if (0 && value <= 0x3ffff) { /* Absolute jmp/call */
insn |= 0x01000000; /* Make it absolute */
/* FIXME: Should we change r_type to R_IABS */
} else {
/* Relative jmp/call, so subtract from the value the
address of the place we're coming from */
value -= reloc_entry->address +
input_section->output_section->vma +
input_section->output_offset;
if (value > 0x3ffff) {
fprintf(stderr,"Relocation problem : "); fprintf(stderr,"Relocation problem : ");
fprintf(stderr,"Missing IHCONST in module %s\n",abfd->filename); fprintf(stderr,"Jmp/call too far; to %s from %s\n",
part1_consth_active = 0; symbol_in->name,abfd->filename);
return(bfd_reloc_dangerous); return(bfd_reloc_outofrange);
}
} }
value >>= 2;
insn = bfd_get_32(abfd, data + reloc_entry->address); insn = INSERT_HWORD(insn,value);
sym_value = get_symbol_value(symbol_in); break;
case R_ILOHALF:
switch (r_type) { value = EXTRACT_HWORD(insn);
case R_IREL: value += sym_value + reloc_entry->addend;
value = EXTRACT_HWORD(insn) << 2; insn = INSERT_HWORD(insn,value);
value += sym_value + reloc_entry->addend; break;
if (value <= 0x3ffff) { /* Absolute jmp/call */ case R_IHIHALF: /* consth, part 1 */
insn |= 0x01000000; /* Make it absolute */ /* Just get the symbol value that is referenced */
/* FIXME: Should we change r_type to R_IABS */ part1_consth_active = 1;
} else { /* Relative jmp/call */ part1_consth_value = sym_value + reloc_entry->addend;
value -= reloc_entry->address; return(bfd_reloc_ok); /* Don't modify insn until R_IHCONST */
if (value > 0x3ffff) { break;
fprintf(stderr,"Relocation problem : "); case R_IHCONST: /* consth, part 2 */
fprintf(stderr,"Jmp/call too far; to %s from %s\n", /* Now relocate the reference */
symbol_in->name,abfd->filename); if (!part1_consth_active) {
return(bfd_reloc_outofrange); fprintf(stderr,"Relocation problem : ");
} fprintf(stderr,"IHIHALF missing in module %s\n",
} abfd->filename);
value >>= 2; part1_consth_active = 0;
insn = INSERT_HWORD(insn,value); return(bfd_reloc_dangerous);
break;
case R_ILOHALF:
value = EXTRACT_HWORD(insn);
value += sym_value + reloc_entry->addend;
insn = INSERT_HWORD(insn,value);
break;
case R_IHIHALF: /* consth, part 1 */
/* Just get the symbol value that is referenced */
part1_consth_active = 1;
part1_consth_value = sym_value + reloc_entry->addend;
return(bfd_reloc_ok); /* Don't modify insn until R_IHCONST */
break;
case R_IHCONST: /* consth, part 2 */
/* Now relocate the reference */
if (!part1_consth_active) {
fprintf(stderr,"Relocation problem : ");
fprintf(stderr,"IHIHALF missing in module %s\n",
abfd->filename);
part1_consth_active = 0;
return(bfd_reloc_dangerous);
}
/* sym_ptr_ptr = r_symndx, in coff_slurp_reloc_table() */
value = (unsigned int)reloc_entry->addend; /* r_symndx */
value += part1_consth_value;
value >>= 16;
insn = INSERT_HWORD(insn,value);
part1_consth_active = 0;
break;
case R_BYTE:
value = (insn >> 24) + sym_value + reloc_entry->addend;
if (value & 0xffffff00) {
fprintf(stderr,"Relocation problem : ");
fprintf(stderr,"byte value too large in module %s\n",
abfd->filename);
return(bfd_reloc_overflow);
}
insn = (insn & 0x00ffffff) | (value << 24);
break;
case R_HWORD:
value = (insn >> 16) + sym_value + reloc_entry->addend;
if (value & 0xffff0000) {
fprintf(stderr,"Relocation problem : ");
fprintf(stderr,"hword value too large in module %s\n",
abfd->filename);
return(bfd_reloc_overflow);
}
insn = (insn & 0x0000ffff) | (value<<16);
break;
case R_WORD:
insn += sym_value + reloc_entry->addend;
break;
default:
fprintf(stderr,"Relocation problem : ");
fprintf(stderr,"Unrecognized reloc type %d, in module %s\n",
r_type,abfd->filename);
return (bfd_reloc_dangerous);
} }
/* sym_ptr_ptr = r_symndx, in coff_slurp_reloc_table() */
value = (unsigned int)reloc_entry->addend; /* r_symndx */
value += part1_consth_value;
value >>= 16;
insn = INSERT_HWORD(insn,value);
part1_consth_active = 0;
break;
case R_BYTE:
value = (insn >> 24) + sym_value + reloc_entry->addend;
if (value & 0xffffff00) {
fprintf(stderr,"Relocation problem : ");
fprintf(stderr,"byte value too large in module %s\n",
abfd->filename);
return(bfd_reloc_overflow);
}
insn = (insn & 0x00ffffff) | (value << 24);
break;
case R_HWORD:
value = (insn >> 16) + sym_value + reloc_entry->addend;
if (value & 0xffff0000) {
fprintf(stderr,"Relocation problem : ");
fprintf(stderr,"hword value too large in module %s\n",
abfd->filename);
return(bfd_reloc_overflow);
}
insn = (insn & 0x0000ffff) | (value<<16);
break;
case R_WORD:
insn += sym_value + reloc_entry->addend;
break;
default:
fprintf(stderr,"Relocation problem : ");
fprintf(stderr,"Unrecognized reloc type %d, in module %s\n",
r_type,abfd->filename);
return (bfd_reloc_dangerous);
}
bfd_put_32(abfd, insn, data+reloc_entry->address); bfd_put_32(abfd, insn, data+reloc_entry->address);
return(bfd_reloc_ok); return(bfd_reloc_ok);
} }
/* type rightshift /* type rightshift

View file

@ -249,16 +249,6 @@ $ } coff_symbol_type;
/* $Id$ */ /* $Id$ */
/* Most of this hacked by Steve Chamberlain, steve@cygnus.com */ /* Most of this hacked by Steve Chamberlain, steve@cygnus.com */
/* Align an address upward to a boundary, expressed as a number of bytes.
E.g. align to an 8-byte boundary with argument of 8. */
#define ALIGN(this, boundary) \
((( (this) + ((boundary) -1)) & (~((boundary)-1))))
/* Align an address upward to a power of two. Argument is the power
of two, e.g. 8-byte alignment uses argument of 3 (8 == 2^3). */
#define i960_align(addr, align) \
( ((addr) + ((1<<(align))-1)) & (-1 << (align)))
#define PUTWORD bfd_h_put_32 #define PUTWORD bfd_h_put_32
#define PUTHALF bfd_h_put_16 #define PUTHALF bfd_h_put_16
@ -1188,13 +1178,20 @@ struct internal_syment *syment)
syment->n_value = coff_symbol_ptr->symbol.value; syment->n_value = coff_symbol_ptr->symbol.value;
} }
else { else {
syment->n_scnum = if (coff_symbol_ptr->symbol.section) {
coff_symbol_ptr->symbol.section->output_section->index+1; syment->n_scnum =
coff_symbol_ptr->symbol.section->output_section->index+1;
syment->n_value = syment->n_value =
coff_symbol_ptr->symbol.value + coff_symbol_ptr->symbol.value +
coff_symbol_ptr->symbol.section->output_offset + coff_symbol_ptr->symbol.section->output_offset +
coff_symbol_ptr->symbol.section->output_section->vma; coff_symbol_ptr->symbol.section->output_section->vma;
}
else {
/* This can happen, but I don't know why yet (steve@cygnus.com) */
syment->n_scnum = N_ABS;
syment->n_value = coff_symbol_ptr->symbol.value;
}
} }
} }
@ -1530,6 +1527,7 @@ unsigned int written)
for (j = 0; j != native->u.syment.n_numaux; j++) for (j = 0; j != native->u.syment.n_numaux; j++)
{ {
AUXENT buf1; AUXENT buf1;
bzero((PTR)&buf, AUXESZ);
coff_swap_aux_out(abfd, coff_swap_aux_out(abfd,
&( (native + j + 1)->u.auxent), type, class, &buf1); &( (native + j + 1)->u.auxent), type, class, &buf1);
bfd_write((PTR) (&buf1), 1, AUXESZ, abfd); bfd_write((PTR) (&buf1), 1, AUXESZ, abfd);

View file

@ -1,30 +1,29 @@
/* Copyright (C) 1990, 1991 Free Software Foundation, Inc. /* libbfd.c -- random BFD support routines, only used internally.
Copyright (C) 1990-1991 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Diddler. This file is part of BFD, the Binary File Descriptor library.
BFD is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option) the Free Software Foundation; either version 2 of the License, or
any later version. (at your option) any later version.
BFD is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with BFD; see the file COPYING. If not, write to along with this program; if not, write to the Free Software
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* $Id$ */ /* $Id$ */
/*** libbfd.c -- random bfd support routines used internally only. */
#include <sysdep.h>
#include "bfd.h" #include "bfd.h"
#include "sysdep.h"
#include "libbfd.h" #include "libbfd.h"
/** Dummies for targets that don't want or need to implement /** Dummies for targets that don't want or need to implement
certain operations */ certain operations */
@ -130,7 +129,7 @@ DEFUN(zalloc,(size),
/* Note that archive entries don't have streams; they share their parent's. /* Note that archive entries don't have streams; they share their parent's.
This allows someone to play with the iostream behind bfd's back. This allows someone to play with the iostream behind BFD's back.
Also, note that the origin pointer points to the beginning of a file's Also, note that the origin pointer points to the beginning of a file's
contents (0 for non-archive elements). For archive entries this is the contents (0 for non-archive elements). For archive entries this is the
@ -157,7 +156,7 @@ DEFUN(bfd_read,(ptr, size, nitems, abfd),
bfd_size_type bfd_size_type
DEFUN(bfd_write,(ptr, size, nitems, abfd), DEFUN(bfd_write,(ptr, size, nitems, abfd),
PTR ptr AND CONST PTR ptr AND
bfd_size_type size AND bfd_size_type size AND
bfd_size_type nitems AND bfd_size_type nitems AND
bfd *abfd) bfd *abfd)
@ -165,13 +164,23 @@ DEFUN(bfd_write,(ptr, size, nitems, abfd),
return fwrite (ptr, 1, (int)(size*nitems), bfd_cache_lookup(abfd)); return fwrite (ptr, 1, (int)(size*nitems), bfd_cache_lookup(abfd));
} }
void
DEFUN(bfd_write_bigendian_4byte_int,(abfd, i),
bfd *abfd AND
int i)
{
char buffer[4];
_do_putb32(i, buffer);
bfd_write(buffer, 4, 1, abfd);
}
int int
DEFUN(bfd_seek,(abfd, position, direction), DEFUN(bfd_seek,(abfd, position, direction),
bfd * CONST abfd AND bfd * CONST abfd AND
CONST file_ptr position AND CONST file_ptr position AND
CONST int direction) CONST int direction)
{ {
/* For the time being, a bfd may not seek to it's end. The /* For the time being, a BFD may not seek to it's end. The
problem is that we don't easily have a way to recognize problem is that we don't easily have a way to recognize
the end of an element in an archive. */ the end of an element in an archive. */
@ -274,7 +283,7 @@ DEFUN(bfd_add_to_string_table,(table, new_string, table_length, free_ptr),
*i bfd_get_size *i bfd_get_size
These macros as used for reading and writing raw data in sections; These macros as used for reading and writing raw data in sections;
each access (except for bytes) is vectored through the target format each access (except for bytes) is vectored through the target format
of the bfd and mangled accordingly. The mangling performs any of the BFD and mangled accordingly. The mangling performs any
necessary endian translations and removes alignment restrictions. necessary endian translations and removes alignment restrictions.
*+ *+
#define bfd_put_8(abfd, val, ptr) \ #define bfd_put_8(abfd, val, ptr) \
@ -324,14 +333,14 @@ endan order.
*- *-
*-*/ *-*/
unsigned int bfd_vma
DEFUN(_do_getb16,(addr), DEFUN(_do_getb16,(addr),
register bfd_byte *addr) register bfd_byte *addr)
{ {
return (addr[0] << 8) | addr[1]; return (addr[0] << 8) | addr[1];
} }
unsigned int bfd_vma
DEFUN(_do_getl16,(addr), DEFUN(_do_getl16,(addr),
register bfd_byte *addr) register bfd_byte *addr)
{ {
@ -340,7 +349,7 @@ DEFUN(_do_getl16,(addr),
void void
DEFUN(_do_putb16,(data, addr), DEFUN(_do_putb16,(data, addr),
int data AND bfd_vma data AND
register bfd_byte *addr) register bfd_byte *addr)
{ {
addr[0] = (bfd_byte)(data >> 8); addr[0] = (bfd_byte)(data >> 8);
@ -349,28 +358,28 @@ DEFUN(_do_putb16,(data, addr),
void void
DEFUN(_do_putl16,(data, addr), DEFUN(_do_putl16,(data, addr),
int data AND bfd_vma data AND
register bfd_byte *addr) register bfd_byte *addr)
{ {
addr[0] = (bfd_byte )data; addr[0] = (bfd_byte )data;
addr[1] = (bfd_byte)(data >> 8); addr[1] = (bfd_byte)(data >> 8);
} }
unsigned int bfd_vma
DEFUN(_do_getb32,(addr), DEFUN(_do_getb32,(addr),
register bfd_byte *addr) register bfd_byte *addr)
{ {
return ((((addr[0] << 8) | addr[1]) << 8) | addr[2]) << 8 | addr[3]; return ((((addr[0] << 8) | addr[1]) << 8) | addr[2]) << 8 | addr[3];
} }
unsigned int bfd_vma
_do_getl32 (addr) _do_getl32 (addr)
register bfd_byte *addr; register bfd_byte *addr;
{ {
return ((((addr[3] << 8) | addr[2]) << 8) | addr[1]) << 8 | addr[0]; return ((((addr[3] << 8) | addr[2]) << 8) | addr[1]) << 8 | addr[0];
} }
bfd_64_type bfd_vma
DEFUN(_do_getb64,(addr), DEFUN(_do_getb64,(addr),
register bfd_byte *addr) register bfd_byte *addr)
{ {
@ -389,14 +398,13 @@ DEFUN(_do_getb64,(addr),
return high << 32 | low; return high << 32 | low;
#else #else
bfd_64_type foo;
BFD_FAIL(); BFD_FAIL();
return foo; return 0;
#endif #endif
} }
bfd_64_type bfd_vma
DEFUN(_do_getl64,(addr), DEFUN(_do_getl64,(addr),
register bfd_byte *addr) register bfd_byte *addr)
{ {
@ -415,16 +423,15 @@ DEFUN(_do_getl64,(addr),
return high << 32 | low; return high << 32 | low;
#else #else
bfd_64_type foo;
BFD_FAIL(); BFD_FAIL();
return foo; return 0;
#endif #endif
} }
void void
DEFUN(_do_putb32,(data, addr), DEFUN(_do_putb32,(data, addr),
unsigned long data AND bfd_vma data AND
register bfd_byte *addr) register bfd_byte *addr)
{ {
addr[0] = (bfd_byte)(data >> 24); addr[0] = (bfd_byte)(data >> 24);
@ -435,7 +442,7 @@ DEFUN(_do_putb32,(data, addr),
void void
DEFUN(_do_putl32,(data, addr), DEFUN(_do_putl32,(data, addr),
unsigned long data AND bfd_vma data AND
register bfd_byte *addr) register bfd_byte *addr)
{ {
addr[0] = (bfd_byte)data; addr[0] = (bfd_byte)data;
@ -445,7 +452,7 @@ DEFUN(_do_putl32,(data, addr),
} }
void void
DEFUN(_do_putb64,(data, addr), DEFUN(_do_putb64,(data, addr),
bfd_64_type data AND bfd_vma data AND
register bfd_byte *addr) register bfd_byte *addr)
{ {
#ifdef HOST_64_BIT #ifdef HOST_64_BIT
@ -465,7 +472,7 @@ DEFUN(_do_putb64,(data, addr),
void void
DEFUN(_do_putl64,(data, addr), DEFUN(_do_putl64,(data, addr),
bfd_64_type data AND bfd_vma data AND
register bfd_byte *addr) register bfd_byte *addr)
{ {
#ifdef HOST_64_BIT #ifdef HOST_64_BIT
@ -496,13 +503,34 @@ DEFUN(bfd_generic_get_section_contents, (abfd, section, location, offset, count)
{ {
if (count == 0) if (count == 0)
return true; return true;
if ((bfd_size_type)offset >= section->size if ((bfd_size_type)(offset+count) > section->size
|| bfd_seek(abfd,(file_ptr)( section->filepos + offset), SEEK_SET) == -1 || bfd_seek(abfd,(file_ptr)( section->filepos + offset), SEEK_SET) == -1
|| bfd_read(location, (bfd_size_type)1, count, abfd) != count) || bfd_read(location, (bfd_size_type)1, count, abfd) != count)
return (false); /* on error */ return (false); /* on error */
return (true); return (true);
} }
/* This generic function can only be used in implementations where creating
NEW sections is disallowed. It is useful in patching existing sections
in read-write files, though. See other set_section_contents functions
to see why it doesn't work for new sections. */
boolean
DEFUN(bfd_generic_set_section_contents, (abfd, section, location, offset, count),
bfd *abfd AND
sec_ptr section AND
PTR location AND
file_ptr offset AND
bfd_size_type count)
{
if (count == 0)
return true;
if ((bfd_size_type)(offset+count) > section->size
|| bfd_seek(abfd, (file_ptr)(section->filepos + offset), SEEK_SET) == -1
|| bfd_write(location, (bfd_size_type)1, count, abfd) != count)
return (false); /* on error */
return (true);
}
/*proto-internal* /*proto-internal*
*i bfd_log2 *i bfd_log2
Return the log base 2 of the value supplied, rounded up. eg an arg Return the log base 2 of the value supplied, rounded up. eg an arg

View file

@ -216,7 +216,7 @@ $ SDEF (void, _bfd_truncate_arname, (bfd *, CONST char *, char *));
$ SDEF (boolean, write_armap, (bfd *arch, $ SDEF (boolean, write_armap, (bfd *arch,
$ unsigned int elength, $ unsigned int elength,
$ struct orl *map, $ struct orl *map,
$ int orl_count, $ unsigned int orl_count,
$ int stridx)); $ int stridx));
Standard stuff. Standard stuff.
@ -340,6 +340,7 @@ extern bfd_target m68kcoff_vec;
extern bfd_target i386coff_vec; extern bfd_target i386coff_vec;
extern bfd_target i386aout_vec; extern bfd_target i386aout_vec;
extern bfd_target a29kcoff_big_vec; extern bfd_target a29kcoff_big_vec;
extern bfd_target trad_core_vec;
#ifdef SELECT_VECS #ifdef SELECT_VECS
@ -469,8 +470,7 @@ bfd_target *target_vector[] = {
#endif #endif
#ifdef TRAD_CORE #ifdef TRAD_CORE
&trad_core_big_vec, &trad_core_vec,
&trad_core_little_vec,
#endif #endif
NULL, /* end of list marker */ NULL, /* end of list marker */