* 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:
parent
7955ad1c4d
commit
f58809fd41
6 changed files with 262 additions and 186 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
205
bfd/coff-a29k.c
205
bfd/coff-a29k.c
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
94
bfd/libbfd.c
94
bfd/libbfd.c
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in a new issue