* elf.c (elf_obj_tdata): Merge elf_obj_tdata_struct and

elf_core_tdata_struct into a single common struct.  Core files
wouldn't have worked at all without this.
(bfd_elf_find_section):  New function for GDB's undercover use
to find string sections that BFD hides from it.
(elf_get_str_section):  Avoid multiple alloc&reads for same data; lint.
(elf_object_p, elf_core_file_p):  Allocate internal file header
storage dynamically.
* bfd.c (union {...} tdata):  Remove elf_core_tdata_struct.
* demo64.c:  Prevent "empty translation unit" warnings from idiots.
This commit is contained in:
John Gilmore
1992-06-11 08:10:04 +00:00
parent b5adcbd066
commit 80bdcb77bd
2 changed files with 195 additions and 146 deletions

View File

@ -1,3 +1,17 @@
Thu Jun 11 00:52:03 1992 John Gilmore (gnu at cygnus.com)
* elf.c (elf_obj_tdata): Merge elf_obj_tdata_struct and
elf_core_tdata_struct into a single common struct. Core files
wouldn't have worked at all without this.
(bfd_elf_find_section): New function for GDB's undercover use
to find string sections that BFD hides from it.
(elf_get_str_section): Avoid multiple alloc&reads for same data;
lint.
(elf_object_p, elf_core_file_p): Allocate internal file header
storage dynamically.
* bfd.c (union {...} tdata): Remove elf_core_tdata_struct.
* demo64.c: Prevent "empty translation unit" warnings from idiots.
Tue Jun 9 17:15:26 1992 Fred Fish (fnf at cygnus.com) Tue Jun 9 17:15:26 1992 Fred Fish (fnf at cygnus.com)
* config/{i386v4.mh, ncr3000.mh}: Update RANLIB, add INSTALL. * config/{i386v4.mh, ncr3000.mh}: Update RANLIB, add INSTALL.

151
bfd/elf.c
View File

@ -103,32 +103,25 @@ typedef struct
} elf_symbol_type; } elf_symbol_type;
/* Some private data is stashed away for future use using the tdata pointer /* Some private data is stashed away for future use using the tdata pointer
in the bfd structure. This information is different for ELF core files in the bfd structure. */
and other ELF files. */
typedef struct elf_core_tdata_struct struct elf_obj_tdata
{ {
void *prstatus; /* The raw /proc prstatus structure */ Elf_Internal_Ehdr elf_header[1]; /* Actual data, but ref like ptr */
void *prpsinfo; /* The raw /proc prpsinfo structure */
} elf_core_tdata;
#define core_prpsinfo(bfd) (((bfd)->tdata.elf_core_data) -> prpsinfo)
#define core_prstatus(bfd) (((bfd)->tdata.elf_core_data) -> prstatus)
typedef struct elf_obj_tdata_struct
{
Elf_Internal_Ehdr *elf_header;
Elf_Internal_Shdr *elf_sect_ptr; Elf_Internal_Shdr *elf_sect_ptr;
struct strtab *strtab_ptr; struct strtab *strtab_ptr;
int symtab_section; int symtab_section;
} elf_obj_tdata; void *prstatus; /* The raw /proc prstatus structure */
void *prpsinfo; /* The raw /proc prpsinfo structure */
};
#define elf_tdata(bfd) ((bfd) -> tdata.elf_obj_data) #define elf_tdata(bfd) ((bfd) -> tdata.elf_obj_data)
#define elf_elfheader(bfd) (elf_tdata(bfd) -> elf_header) #define elf_elfheader(bfd) (elf_tdata(bfd) -> elf_header)
#define elf_elfsections(bfd) (elf_tdata(bfd) -> elf_sect_ptr) #define elf_elfsections(bfd) (elf_tdata(bfd) -> elf_sect_ptr)
#define elf_shstrtab(bfd) (elf_tdata(bfd) -> strtab_ptr) #define elf_shstrtab(bfd) (elf_tdata(bfd) -> strtab_ptr)
#define elf_onesymtab(bfd) (elf_tdata(bfd) -> symtab_section) #define elf_onesymtab(bfd) (elf_tdata(bfd) -> symtab_section)
#define core_prpsinfo(bfd) (elf_tdata(bfd) -> prpsinfo)
#define core_prstatus(bfd) (elf_tdata(bfd) -> prstatus)
/* Translate an ELF symbol in external format into an ELF symbol in internal /* Translate an ELF symbol in external format into an ELF symbol in internal
format. */ format. */
@ -332,7 +325,27 @@ static struct sec * EXFUN(section_from_elf_index, (bfd *, int));
static int EXFUN(elf_section_from_bfd_section, (bfd *, struct sec *)); static int EXFUN(elf_section_from_bfd_section, (bfd *, struct sec *));
static boolean EXFUN(elf_slurp_symbol_table, (bfd *, Elf_Internal_Shdr*)); static boolean EXFUN(elf_slurp_symbol_table, (bfd *, Elf_Internal_Shdr*));
static void EXFUN(elf_info_to_howto, (bfd *, arelent *, Elf_Internal_Rela *)); static void EXFUN(elf_info_to_howto, (bfd *, arelent *, Elf_Internal_Rela *));
static char *EXFUN(elf_get_str_section, (bfd *, unsigned int));
/* Helper functions for GDB to locate the string tables. */
Elf_Internal_Shdr *
DEFUN(bfd_elf_find_section, (abfd, name), /* .stabstr offset */
bfd *abfd AND
char *name)
{
Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd);
char *shstrtab = elf_get_str_section (abfd, elf_elfheader (abfd)->e_shstrndx);
unsigned int max = elf_elfheader (abfd)->e_shnum;
unsigned int i;
for (i = 1; i < max; i++)
if (!strcmp (&shstrtab[i_shdrp[i].sh_name], name))
return &i_shdrp[i];
return 0;
}
/* End of GDB support. */
static char * static char *
DEFUN(elf_get_str_section, (abfd, shindex), DEFUN(elf_get_str_section, (abfd, shindex),
@ -342,14 +355,19 @@ DEFUN(elf_get_str_section, (abfd, shindex),
Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd); Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd);
unsigned int shstrtabsize = i_shdrp[shindex].sh_size; unsigned int shstrtabsize = i_shdrp[shindex].sh_size;
unsigned int offset = i_shdrp[shindex].sh_offset; unsigned int offset = i_shdrp[shindex].sh_offset;
char *shstrtab; char *shstrtab = i_shdrp[shindex].rawdata;
if (shstrtab)
return shstrtab;
if ((shstrtab = elf_read (abfd, offset, shstrtabsize)) == NULL) if ((shstrtab = elf_read (abfd, offset, shstrtabsize)) == NULL)
{ {
return (NULL); return (NULL);
} }
i_shdrp[shindex].rawdata = (void*)shstrtab; i_shdrp[shindex].rawdata = (void*)shstrtab;
return shstrtab;
} }
static char * static char *
DEFUN(elf_string_from_elf_section, (abfd, shindex, strindex), DEFUN(elf_string_from_elf_section, (abfd, shindex, strindex),
bfd *abfd AND bfd *abfd AND
@ -358,6 +376,7 @@ DEFUN(elf_string_from_elf_section, (abfd, shindex, strindex),
{ {
Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd); Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd);
Elf_Internal_Shdr *hdr = i_shdrp + shindex; Elf_Internal_Shdr *hdr = i_shdrp + shindex;
if (! hdr->rawdata) if (! hdr->rawdata)
{ {
if (elf_get_str_section (abfd, shindex) == NULL) if (elf_get_str_section (abfd, shindex) == NULL)
@ -462,8 +481,10 @@ DEFUN(bfd_section_from_shdr, (abfd, shindex),
target_sect->flags |= SEC_RELOC; target_sect->flags |= SEC_RELOC;
target_sect->relocation = 0; target_sect->relocation = 0;
target_sect->rel_filepos = hdr->sh_offset; target_sect->rel_filepos = hdr->sh_offset;
#if 0
fprintf(stderr, "ELF>> section %s reading %d relocs\n", fprintf(stderr, "ELF>> section %s reading %d relocs\n",
target_sect->name, target_sect->reloc_count); target_sect->name, target_sect->reloc_count);
#endif
return true; return true;
} }
@ -471,16 +492,23 @@ DEFUN(bfd_section_from_shdr, (abfd, shindex),
case SHT_HASH: case SHT_HASH:
case SHT_DYNAMIC: case SHT_DYNAMIC:
case SHT_DYNSYM: /* could treat this like symtab... */ case SHT_DYNSYM: /* could treat this like symtab... */
#if 0
fprintf(stderr, "Dynamic Linking sections not yet supported.\n"); fprintf(stderr, "Dynamic Linking sections not yet supported.\n");
abort (); abort ();
#endif
break; break;
case SHT_NOTE: case SHT_NOTE:
#if 0
fprintf(stderr, "Note Sections not yet supported.\n"); fprintf(stderr, "Note Sections not yet supported.\n");
abort (); abort ();
#endif
break; break;
case SHT_SHLIB: case SHT_SHLIB:
#if 0
fprintf(stderr, "SHLIB Sections not supported (and non conforming.)\n"); fprintf(stderr, "SHLIB Sections not supported (and non conforming.)\n");
#endif
return true; return true;
default: default:
break; break;
} }
@ -1001,7 +1029,7 @@ static bfd_target *
DEFUN (elf_object_p, (abfd), bfd *abfd) DEFUN (elf_object_p, (abfd), bfd *abfd)
{ {
Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ Elf_External_Ehdr x_ehdr; /* Elf file header, external form */
Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form */ Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */
Elf_External_Shdr x_shdr; /* Section header table entry, external form */ Elf_External_Shdr x_shdr; /* Section header table entry, external form */
Elf_Internal_Shdr *i_shdrp; /* Section header table, internal form */ Elf_Internal_Shdr *i_shdrp; /* Section header table, internal form */
int shindex; int shindex;
@ -1065,27 +1093,27 @@ wrong:
/* Allocate an instance of the elf_obj_tdata structure and hook it up to /* Allocate an instance of the elf_obj_tdata structure and hook it up to
the tdata pointer in the bfd. */ the tdata pointer in the bfd. */
if ((abfd -> tdata.elf_obj_data = if (NULL == (elf_tdata (abfd) = (struct elf_obj_tdata *)
(elf_obj_tdata*) bfd_zalloc (abfd, sizeof (elf_obj_tdata))) bfd_zalloc (abfd, sizeof (struct elf_obj_tdata))))
== NULL)
{ {
bfd_error = no_memory; bfd_error = no_memory;
return (NULL); return (NULL);
} }
/* FIXME: Any `wrong' exits below here will leak memory (tdata). */
/* Now that we know the byte order, swap in the rest of the header */ /* Now that we know the byte order, swap in the rest of the header */
elf_swap_ehdr_in (abfd, &x_ehdr, &i_ehdr); i_ehdrp = elf_elfheader (abfd);
/* FIXME: should be alloc'ed */ elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);
elf_elfheader (abfd) = &i_ehdr;
/* If there is no section header table, we're hosed. */ /* If there is no section header table, we're hosed. */
if (i_ehdr.e_shoff == 0) if (i_ehdrp->e_shoff == 0)
goto wrong; goto wrong;
if (i_ehdr.e_type == ET_EXEC || i_ehdr.e_type == ET_DYN) if (i_ehdrp->e_type == ET_EXEC || i_ehdrp->e_type == ET_DYN)
abfd -> flags |= EXEC_P; abfd -> flags |= EXEC_P;
switch (i_ehdr.e_machine) switch (i_ehdrp->e_machine)
{ {
case EM_NONE: case EM_NONE:
case EM_M32: /* or should this be bfd_arch_obscure? */ case EM_M32: /* or should this be bfd_arch_obscure? */
@ -1119,21 +1147,21 @@ wrong:
check, verify that the what BFD thinks is the size of each section check, verify that the what BFD thinks is the size of each section
header table entry actually matches the size recorded in the file. */ header table entry actually matches the size recorded in the file. */
if (i_ehdr.e_shentsize != sizeof (x_shdr)) if (i_ehdrp->e_shentsize != sizeof (x_shdr))
goto wrong; goto wrong;
i_shdrp = (Elf_Internal_Shdr *) i_shdrp = (Elf_Internal_Shdr *)
bfd_alloc (abfd, sizeof (*i_shdrp) * i_ehdr.e_shnum); bfd_alloc (abfd, sizeof (*i_shdrp) * i_ehdrp->e_shnum);
if (! i_shdrp) if (! i_shdrp)
{ {
bfd_error = no_memory; bfd_error = no_memory;
return (NULL); return (NULL);
} }
if (bfd_seek (abfd, i_ehdr.e_shoff, SEEK_SET) == -1) if (bfd_seek (abfd, i_ehdrp->e_shoff, SEEK_SET) == -1)
{ {
bfd_error = system_call_error; bfd_error = system_call_error;
return (NULL); return (NULL);
} }
for (shindex = 0; shindex < i_ehdr.e_shnum; shindex++) for (shindex = 0; shindex < i_ehdrp->e_shnum; shindex++)
{ {
if (bfd_read ((PTR) &x_shdr, sizeof x_shdr, 1, abfd) if (bfd_read ((PTR) &x_shdr, sizeof x_shdr, 1, abfd)
!= sizeof (x_shdr)) != sizeof (x_shdr))
@ -1152,7 +1180,7 @@ wrong:
bfd_section_from_shdr with it (since this particular strtab is bfd_section_from_shdr with it (since this particular strtab is
used to find all of the ELF section names.) */ used to find all of the ELF section names.) */
shstrtab = elf_get_str_section (abfd, i_ehdr.e_shstrndx); shstrtab = elf_get_str_section (abfd, i_ehdrp->e_shstrndx);
if (! shstrtab) if (! shstrtab)
return (NULL); return (NULL);
@ -1164,14 +1192,14 @@ wrong:
offset and section size for both the symbol table section and the offset and section size for both the symbol table section and the
associated string table section. */ associated string table section. */
for (shindex = 1; shindex < i_ehdr.e_shnum; shindex++) for (shindex = 1; shindex < i_ehdrp->e_shnum; shindex++)
{ {
bfd_section_from_shdr (abfd, shindex); bfd_section_from_shdr (abfd, shindex);
} }
/* Remember the entry point specified in the ELF file header. */ /* Remember the entry point specified in the ELF file header. */
bfd_get_start_address (abfd) = i_ehdr.e_entry; bfd_get_start_address (abfd) = i_ehdrp->e_entry;
return (abfd->xvec); return (abfd->xvec);
} }
@ -1193,7 +1221,7 @@ static bfd_target *
DEFUN (elf_core_file_p, (abfd), bfd *abfd) DEFUN (elf_core_file_p, (abfd), bfd *abfd)
{ {
Elf_External_Ehdr x_ehdr; /* Elf file header, external form */ Elf_External_Ehdr x_ehdr; /* Elf file header, external form */
Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form */ Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */
Elf_External_Phdr x_phdr; /* Program header table entry, external form */ Elf_External_Phdr x_phdr; /* Program header table entry, external form */
Elf_Internal_Phdr *i_phdrp; /* Program header table, internal form */ Elf_Internal_Phdr *i_phdrp; /* Program header table, internal form */
unsigned int phindex; unsigned int phindex;
@ -1250,46 +1278,49 @@ wrong:
goto wrong; goto wrong;
} }
/* Now that we know the byte order, swap in the rest of the header */ /* Allocate an instance of the elf_obj_tdata structure and hook it up to
elf_swap_ehdr_in (abfd, &x_ehdr, &i_ehdr);
/* If there is no program header, or the type is not a core file, then
we are hosed. */
if (i_ehdr.e_phoff == 0 || i_ehdr.e_type != ET_CORE)
goto wrong;
/* Allocate an instance of the elf_core_tdata structure and hook it up to
the tdata pointer in the bfd. */ the tdata pointer in the bfd. */
abfd->tdata.elf_core_data = elf_tdata (abfd) =
(elf_core_tdata *) bfd_zalloc (abfd, sizeof (elf_core_tdata)); (struct elf_obj_tdata *) bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
if (abfd->tdata.elf_core_data == NULL) if (elf_tdata (abfd) == NULL)
{ {
bfd_error = no_memory; bfd_error = no_memory;
return (NULL); return (NULL);
} }
/* FIXME, `wrong' returns from this point onward, leak memory. */
/* Now that we know the byte order, swap in the rest of the header */
i_ehdrp = elf_elfheader (abfd);
elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);
/* If there is no program header, or the type is not a core file, then
we are hosed. */
if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE)
goto wrong;
/* Allocate space for a copy of the program header table in /* Allocate space for a copy of the program header table in
internal form, seek to the program header table in the file, internal form, seek to the program header table in the file,
read it in, and convert it to internal form. As a simple sanity read it in, and convert it to internal form. As a simple sanity
check, verify that the what BFD thinks is the size of each program check, verify that the what BFD thinks is the size of each program
header table entry actually matches the size recorded in the file. */ header table entry actually matches the size recorded in the file. */
if (i_ehdr.e_phentsize != sizeof (x_phdr)) if (i_ehdrp->e_phentsize != sizeof (x_phdr))
goto wrong; goto wrong;
i_phdrp = (Elf_Internal_Phdr *) i_phdrp = (Elf_Internal_Phdr *)
bfd_alloc (abfd, sizeof (*i_phdrp) * i_ehdr.e_phnum); bfd_alloc (abfd, sizeof (*i_phdrp) * i_ehdrp->e_phnum);
if (! i_phdrp) if (! i_phdrp)
{ {
bfd_error = no_memory; bfd_error = no_memory;
return (NULL); return (NULL);
} }
if (bfd_seek (abfd, i_ehdr.e_phoff, SEEK_SET) == -1) if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) == -1)
{ {
bfd_error = system_call_error; bfd_error = system_call_error;
return (NULL); return (NULL);
} }
for (phindex = 0; phindex < i_ehdr.e_phnum; phindex++) for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++)
{ {
if (bfd_read ((PTR) &x_phdr, sizeof (x_phdr), 1, abfd) if (bfd_read ((PTR) &x_phdr, sizeof (x_phdr), 1, abfd)
!= sizeof (x_phdr)) != sizeof (x_phdr))
@ -1303,7 +1334,7 @@ wrong:
/* Once all of the program headers have been read and converted, we /* Once all of the program headers have been read and converted, we
can start processing them. */ can start processing them. */
for (phindex = 0; phindex < i_ehdr.e_phnum; phindex++) for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++)
{ {
bfd_section_from_phdr (abfd, i_phdrp + phindex, phindex); bfd_section_from_phdr (abfd, i_phdrp + phindex, phindex);
if ((i_phdrp + phindex) -> p_type == PT_NOTE) if ((i_phdrp + phindex) -> p_type == PT_NOTE)
@ -1314,7 +1345,7 @@ wrong:
/* Remember the entry point specified in the ELF file header. */ /* Remember the entry point specified in the ELF file header. */
bfd_get_start_address (abfd) = i_ehdr.e_entry; bfd_get_start_address (abfd) = i_ehdrp->e_entry;
return (abfd->xvec); return (abfd->xvec);
} }
@ -1324,8 +1355,8 @@ DEFUN (elf_mkobject, (abfd), bfd *abfd)
{ {
/* this just does initialization */ /* this just does initialization */
/* coff_mkobject zalloc's space for tdata.coff_obj_data ... */ /* coff_mkobject zalloc's space for tdata.coff_obj_data ... */
elf_tdata(abfd) = (elf_obj_tdata *) elf_tdata(abfd) = (struct elf_obj_tdata *)
bfd_zalloc (abfd, sizeof(elf_obj_tdata)); bfd_zalloc (abfd, sizeof(struct elf_obj_tdata));
if (elf_tdata(abfd) == 0) { if (elf_tdata(abfd) == 0) {
bfd_error = no_memory; bfd_error = no_memory;
return false; return false;
@ -1526,8 +1557,7 @@ DEFUN (elf_compute_section_file_positions, (abfd), bfd *abfd)
elf_sect_thunk est; elf_sect_thunk est;
if (! elf_shstrtab (abfd)) { if (! elf_shstrtab (abfd)) {
i_ehdrp = (Elf_Internal_Ehdr *) i_ehdrp = elf_elfheader (abfd); /* build new header in tdata memory */
bfd_alloc (abfd, sizeof (*i_ehdrp));
shstrtab = bfd_new_strtab(abfd); shstrtab = bfd_new_strtab(abfd);
i_ehdrp->e_ident[EI_MAG0] = ELFMAG0; i_ehdrp->e_ident[EI_MAG0] = ELFMAG0;
@ -1620,7 +1650,6 @@ DEFUN (elf_compute_section_file_positions, (abfd), bfd *abfd)
i_ehdrp->e_shnum = 1; i_ehdrp->e_shnum = 1;
elf_elfheader (abfd) = i_ehdrp;
elf_elfsections (abfd) = i_shdrp; elf_elfsections (abfd) = i_shdrp;
elf_shstrtab (abfd) = shstrtab; elf_shstrtab (abfd) = shstrtab;
} }
@ -1921,6 +1950,12 @@ DEFUN (elf_slurp_symbol_table, (abfd, hdr),
sym -> name = elf_string_from_elf_section(abfd, hdr->sh_link, sym -> name = elf_string_from_elf_section(abfd, hdr->sh_link,
i_sym.st_name); i_sym.st_name);
sym -> value = i_sym.st_value; sym -> value = i_sym.st_value;
/* FIXME -- this is almost certainly bogus. It's from Pace Willisson's
hasty Solaris support, to pass the sizes of object files or functions
down into GDB via the back door, to circumvent some other kludge in
how Sun hacked stabs. */
sym -> udata = (PTR)i_sym.st_size;
/* FIXME -- end of bogosity. */
if (i_sym.st_shndx > 0 && i_sym.st_shndx < SHN_LORESERV) if (i_sym.st_shndx > 0 && i_sym.st_shndx < SHN_LORESERV)
{ {
sym -> section = section_from_elf_index (abfd, i_sym.st_shndx); sym -> section = section_from_elf_index (abfd, i_sym.st_shndx);