summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/ld/lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/ld/lib.c')
-rw-r--r--gnu/usr.bin/ld/lib.c234
1 files changed, 129 insertions, 105 deletions
diff --git a/gnu/usr.bin/ld/lib.c b/gnu/usr.bin/ld/lib.c
index 78d337e..7eaaa98 100644
--- a/gnu/usr.bin/ld/lib.c
+++ b/gnu/usr.bin/ld/lib.c
@@ -1,14 +1,16 @@
/*
- * $Id: lib.c,v 1.8 1993/12/22 23:28:11 jkh Exp $ - library routines
+ * $Id: lib.c,v 1.9 1994/02/13 20:41:37 jkh Exp $ - library routines
*/
#include <sys/param.h>
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/time.h>
+#include <err.h>
#include <fcntl.h>
#include <ar.h>
#include <ranlib.h>
@@ -16,6 +18,7 @@
#include <stab.h>
#include <string.h>
#include <dirent.h>
+#include <ctype.h>
#include "ld.h"
@@ -26,15 +29,15 @@ static struct file_entry *decode_library_subfile __P((int,
int, int *));
/*
- * Search the library ENTRY, already open on descriptor DESC. This means
+ * Search the library ENTRY, already open on descriptor FD. This means
* deciding which library members to load, making a chain of `struct
* file_entry' for those members, and entering their global symbols in the
* hash table.
*/
void
-search_library(desc, entry)
- int desc;
+search_library(fd, entry)
+ int fd;
struct file_entry *entry;
{
int member_length;
@@ -45,7 +48,7 @@ search_library(desc, entry)
return;
/* Examine its first member, which starts SARMAG bytes in. */
- subentry = decode_library_subfile(desc, entry, SARMAG, &member_length);
+ subentry = decode_library_subfile(fd, entry, SARMAG, &member_length);
if (!subentry)
return;
@@ -55,21 +58,21 @@ search_library(desc, entry)
/* Search via __.SYMDEF if that exists, else linearly. */
if (!strcmp(name, "__.SYMDEF"))
- symdef_library(desc, entry, member_length);
+ symdef_library(fd, entry, member_length);
else
- linear_library(desc, entry);
+ linear_library(fd, entry);
}
/*
* Construct and return a file_entry for a library member. The library's
- * file_entry is library_entry, and the library is open on DESC.
+ * file_entry is library_entry, and the library is open on FD.
* SUBFILE_OFFSET is the byte index in the library of this member's header.
* We store the length of the member into *LENGTH_LOC.
*/
static struct file_entry *
-decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
- int desc;
+decode_library_subfile(fd, library_entry, subfile_offset, length_loc)
+ int fd;
struct file_entry *library_entry;
int subfile_offset;
int *length_loc;
@@ -82,17 +85,20 @@ decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
struct ar_hdr hdr1;
register struct file_entry *subentry;
- lseek(desc, subfile_offset, 0);
+ lseek(fd, subfile_offset, 0);
- bytes_read = read(desc, &hdr1, sizeof hdr1);
+ bytes_read = read(fd, &hdr1, sizeof hdr1);
if (!bytes_read)
return 0; /* end of archive */
if (sizeof hdr1 != bytes_read)
- fatal_with_file("malformed library archive ", library_entry);
+ errx(1, "%s: malformed library archive",
+ get_file_name(library_entry));
if (sscanf(hdr1.ar_size, "%d", &member_length) != 1)
- fatal_with_file("malformatted header of archive member in ", library_entry);
+ errx(1, "%s: malformatted header of archive member: %.*s",
+ get_file_name(library_entry),
+ sizeof(hdr1.ar_name), hdr1.ar_name);
subentry = (struct file_entry *) xmalloc(sizeof(struct file_entry));
bzero(subentry, sizeof(struct file_entry));
@@ -116,10 +122,10 @@ decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
namelen = atoi(&hdr1.ar_name[sizeof(AR_EFMT1) - 1]);
name = (char *)xmalloc(namelen + 1);
- if (read(desc, name, namelen) != namelen)
- fatal_with_file(
- "malformatted header of archive member in ",
- library_entry);
+ if (read(fd, name, namelen) != namelen)
+ errx(1, "%s: malformatted archive member: %.*s",
+ get_file_name(library_entry),
+ sizeof(hdr1.ar_name), hdr1.ar_name);
name[namelen] = 0;
content_length -= namelen;
starting_offset += namelen;
@@ -134,14 +140,16 @@ decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
subentry->filename = name;
subentry->local_sym_name = name;
+ subentry->starting_offset = starting_offset;
+ subentry->superfile = library_entry;
+ subentry->total_size = content_length;
+#if 0
subentry->symbols = 0;
subentry->strings = 0;
subentry->subfiles = 0;
- subentry->starting_offset = starting_offset;
- subentry->superfile = library_entry;
subentry->chain = 0;
subentry->flags = 0;
- subentry->total_size = content_length;
+#endif
(*length_loc) = member_length;
@@ -151,15 +159,15 @@ decode_library_subfile(desc, library_entry, subfile_offset, length_loc)
static int subfile_wanted_p __P((struct file_entry *));
/*
- * Search a library that has a __.SYMDEF member. DESC is a descriptor on
+ * Search a library that has a __.SYMDEF member. FD is a descriptor on
* which the library is open. The file pointer is assumed to point at the
* __.SYMDEF data. ENTRY is the library's file_entry. MEMBER_LENGTH is the
* length of the __.SYMDEF data.
*/
static void
-symdef_library(desc, entry, member_length)
- int desc;
+symdef_library(fd, entry, member_length)
+ int fd;
struct file_entry *entry;
int member_length;
{
@@ -174,14 +182,16 @@ symdef_library(desc, entry, member_length)
struct file_entry *prev = 0;
int prev_offset = 0;
- bytes_read = read(desc, symdef_data, member_length);
+ bytes_read = read(fd, symdef_data, member_length);
if (bytes_read != member_length)
- fatal_with_file("malformatted __.SYMDEF in ", entry);
+ errx(1, "%s: malformatted __.SYMDEF",
+ get_file_name(entry));
nsymdefs = md_swap_long(*symdef_data) / sizeof(struct ranlib);
if (nsymdefs < 0 ||
nsymdefs * sizeof(struct ranlib) + 2 * sizeof(int) > member_length)
- fatal_with_file("malformatted __.SYMDEF in ", entry);
+ errx(1, "%s: malformatted __.SYMDEF",
+ get_file_name(entry));
symdef_base = (struct ranlib *) (symdef_data + 1);
length_of_strings = md_swap_long(*(int *) (symdef_base + nsymdefs));
@@ -189,7 +199,8 @@ symdef_library(desc, entry, member_length)
if (length_of_strings < 0
|| nsymdefs * sizeof(struct ranlib) + length_of_strings
+ 2 * sizeof(int) > member_length)
- fatal_with_file("malformatted __.SYMDEF in ", entry);
+ errx(1, "%s: malformatted __.SYMDEF",
+ get_file_name(entry));
sym_name_base = sizeof(int) + (char *) (symdef_base + nsymdefs);
@@ -199,7 +210,8 @@ symdef_library(desc, entry, member_length)
register int index = symdef_base[i].ran_un.ran_strx;
if (index < 0 || index >= length_of_strings
|| (index && *(sym_name_base + index - 1)))
- fatal_with_file("malformatted __.SYMDEF in ", entry);
+ errx(1, "%s: malformatted __.SYMDEF",
+ get_file_name(entry));
}
/*
@@ -268,19 +280,19 @@ symdef_library(desc, entry, member_length)
* Read the symbol table of the archive member.
*/
- subentry = decode_library_subfile(desc,
+ subentry = decode_library_subfile(fd,
entry, offset, &junk);
if (subentry == 0)
- fatal(
+ errx(1,
"invalid offset for %s in symbol table of %s",
sym_name_base
+ symdef_base[i].ran_un.ran_strx,
entry->filename);
- read_entry_symbols(desc, subentry);
+ read_entry_symbols(fd, subentry);
subentry->strings = (char *)
- malloc(subentry->string_size);
- read_entry_strings(desc, subentry);
+ alloca(subentry->string_size);
+ read_entry_strings(fd, subentry);
/*
* Now scan the symbol table and decide whether to
@@ -289,6 +301,7 @@ symdef_library(desc, entry, member_length)
if (!(link_mode & FORCEARCHIVE) &&
!subfile_wanted_p(subentry)) {
+ if (subentry->symbols)
free(subentry->symbols);
free(subentry);
} else {
@@ -301,7 +314,7 @@ symdef_library(desc, entry, member_length)
not_finished = 1;
- read_entry_relocation(desc, subentry);
+ read_entry_relocation(fd, subentry);
enter_file_symbols(subentry);
if (prev)
@@ -320,28 +333,27 @@ symdef_library(desc, entry, member_length)
if (symdef_base[j].ran_off == offset)
symdef_base[j].ran_un.ran_strx = -1;
}
- }
/*
- * We'll read the strings again if we need them
- * again.
+ * We'll read the strings again
+ * if we need them.
*/
- free(subentry->strings);
subentry->strings = 0;
}
}
+ }
free(symdef_data);
}
/*
* Search a library that has no __.SYMDEF. ENTRY is the library's file_entry.
- * DESC is the descriptor it is open on.
+ * FD is the descriptor it is open on.
*/
static void
-linear_library(desc, entry)
- int desc;
+linear_library(fd, entry)
+ int fd;
struct file_entry *entry;
{
register struct file_entry *prev = 0;
@@ -353,22 +365,23 @@ linear_library(desc, entry)
int member_length;
register struct file_entry *subentry;
- subentry = decode_library_subfile(desc, entry,
+ subentry = decode_library_subfile(fd, entry,
this_subfile_offset, &member_length);
if (!subentry)
return;
- read_entry_symbols(desc, subentry);
- subentry->strings = (char *) alloca(subentry->string_size);
- read_entry_strings(desc, subentry);
+ read_entry_symbols(fd, subentry);
+ subentry->strings = (char *)alloca(subentry->string_size);
+ read_entry_strings(fd, subentry);
if (!(link_mode & FORCEARCHIVE) &&
!subfile_wanted_p(subentry)) {
+ if (subentry->symbols)
free(subentry->symbols);
free(subentry);
} else {
- read_entry_relocation(desc, subentry);
+ read_entry_relocation(fd, subentry);
enter_file_symbols(subentry);
if (prev)
@@ -527,6 +540,7 @@ subfile_wanted_p(entry)
/*
* But this member wants it to be
* a common; ignore it.
+ */
continue;
}
@@ -550,7 +564,9 @@ subfile_wanted_p(entry)
if (write_map) {
print_file_name(entry, stdout);
- fprintf(stdout, " needed due to shared lib ref %s\n", sp->name);
+ fprintf(stdout,
+ " needed due to shared lib ref %s\n",
+ sp->name);
}
return 1;
}
@@ -561,12 +577,12 @@ subfile_wanted_p(entry)
/*
* Read the symbols of dynamic entity ENTRY into core. Assume it is already
- * open, on descriptor DESC.
+ * open, on descriptor FD.
*/
void
-read_shared_object (desc, entry)
+read_shared_object(fd, entry)
struct file_entry *entry;
- int desc;
+ int fd;
{
struct _dynamic dyn;
struct section_dispatch_table sdt;
@@ -575,22 +591,23 @@ read_shared_object (desc, entry)
int n, i, has_nz = 0;
if (!(entry->flags & E_HEADER_VALID))
- read_header (desc, entry);
+ read_header(fd, entry);
/* Read DYNAMIC structure (first in data segment) */
- lseek (desc,
- text_offset (entry) + entry->header.a_text,
- L_SET);
- if (read(desc, &dyn, sizeof dyn) != sizeof dyn) {
- fatal_with_file (
- "premature eof in data segment of ", entry);
+ if (lseek(fd, text_offset(entry) + entry->header.a_text, L_SET) ==
+ (off_t)-1)
+ err(1, "%s: lseek", get_file_name(entry));
+ if (read(fd, &dyn, sizeof dyn) != sizeof dyn) {
+ errx(1, "%s: premature EOF reading _dynamic",
+ get_file_name(entry));
}
md_swapin__dynamic(&dyn);
/* Check version */
switch (dyn.d_version) {
default:
- fatal_with_file( "unsupported _DYNAMIC version ", entry);
+ errx(1, "%s: unsupported _DYNAMIC version: %d",
+ get_file_name(entry), dyn.d_version);
break;
case LD_VERSION_SUN:
break;
@@ -600,29 +617,33 @@ read_shared_object (desc, entry)
}
/* Read Section Dispatch Table (from data segment) */
- lseek (desc,
+ if (lseek(fd,
text_offset(entry) + (long)dyn.d_un.d_sdt -
(DATA_START(entry->header) - N_DATOFF(entry->header)),
- L_SET);
- if (read(desc, &sdt, sizeof sdt) != sizeof sdt) {
- fatal_with_file( "premature eof in data segment of ", entry);
- }
+ L_SET) == (off_t)-1)
+ err(1, "%s: lseek", get_file_name(entry));
+ if (read(fd, &sdt, sizeof sdt) != sizeof sdt)
+ errx(1, "%s: premature EOF reading sdt",
+ get_file_name(entry));
md_swapin_section_dispatch_table(&sdt);
/* Read symbols (text segment) */
n = sdt.sdt_strings - sdt.sdt_nzlist;
entry->nsymbols = n /
(has_nz ? sizeof(struct nzlist) : sizeof(struct nlist));
- nzp = (struct nzlist *)(np = (struct nlist *) alloca (n));
+ nzp = (struct nzlist *)(np = (struct nlist *)alloca (n));
entry->symbols = (struct localsymbol *)
xmalloc(entry->nsymbols * sizeof(struct localsymbol));
- lseek(desc, text_offset(entry) + (long)sdt.sdt_nzlist -
+
+ if (lseek(fd,
+ text_offset(entry) + (long)sdt.sdt_nzlist -
(TEXT_START(entry->header) - N_TXTOFF(entry->header)),
- L_SET);
- if (read(desc, (char *)nzp, n) != n) {
- fatal_with_file(
- "premature eof while reading object symbols ", entry);
- }
+ L_SET) == (off_t)-1)
+ err(1, "%s: lseek", get_file_name(entry));
+ if (read(fd, (char *)nzp, n) != n)
+ errx(1, "%s: premature EOF reading symbols ",
+ get_file_name(entry));
+
if (has_nz)
md_swapin_zsymbols(nzp, entry->nsymbols);
else
@@ -645,15 +666,16 @@ read_shared_object (desc, entry)
/* Read strings (text segment) */
n = entry->string_size = sdt.sdt_str_sz;
- entry->strings = (char *) alloca(n);
+ entry->strings = (char *)alloca(n);
entry->strings_offset = text_offset(entry) + sdt.sdt_strings;
- lseek(desc, entry->strings_offset -
+ if (lseek(fd,
+ entry->strings_offset -
(TEXT_START(entry->header) - N_TXTOFF(entry->header)),
- L_SET);
- if (read(desc, entry->strings, n) != n) {
- fatal_with_file(
- "premature eof while reading object strings ", entry);
- }
+ L_SET) == (off_t)-1)
+ err(1, "%s: lseek", get_file_name(entry));
+ if (read(fd, entry->strings, n) != n)
+ errx(1, "%s: premature EOF reading strings",
+ get_file_name(entry));
enter_file_symbols (entry);
entry->strings = 0;
@@ -675,19 +697,21 @@ read_shared_object (desc, entry)
bzero(subentry, sizeof(struct file_entry));
subentry->superfile = entry;
- lseek(desc, offset -
- (TEXT_START(entry->header) - N_TXTOFF(entry->header)),
- L_SET);
- if (read(desc, &sod, sizeof(sod)) != sizeof(sod)) {
- fatal_with_file(
- "premature eof while reading sod ",
- entry);
- }
+ if (lseek(fd,
+ offset - (TEXT_START(entry->header) -
+ N_TXTOFF(entry->header)),
+ L_SET) == (off_t)-1)
+ err(1, "%s: lseek", get_file_name(entry));
+ if (read(fd, &sod, sizeof(sod)) != sizeof(sod))
+ errx(1, "%s: premature EOF reding sod",
+ get_file_name(entry));
md_swapin_sod(&sod, 1);
- (void)lseek(desc, (off_t)sod.sod_name -
- (TEXT_START(entry->header) - N_TXTOFF(entry->header)),
- L_SET);
- (void)read(desc, name, sizeof(name)); /*XXX*/
+ if (lseek(fd,
+ (off_t)sod.sod_name - (TEXT_START(entry->header) -
+ N_TXTOFF(entry->header)),
+ L_SET) == (off_t)-1)
+ err(1, "%s: lseek", get_file_name(entry));
+ (void)read(fd, name, sizeof(name)); /*XXX*/
if (sod.sod_library) {
int sod_major = sod.sod_major;
int sod_minor = sod.sod_minor;
@@ -695,7 +719,7 @@ read_shared_object (desc, entry)
libname = findshlib(name,
&sod_major, &sod_minor, 0);
if (libname == NULL)
- fatal("no shared -l%s.%d.%d available",
+ errx(1,"no shared -l%s.%d.%d available",
name, sod.sod_major, sod.sod_minor);
subentry->filename = libname;
subentry->local_sym_name = concat("-l", name, "");
@@ -710,7 +734,7 @@ read_shared_object (desc, entry)
else
entry->subfiles = subentry;
prev = subentry;
- desc = file_open(entry);
+ fd = file_open(entry);
if ((offset = (off_t)sod.sod_next) == 0)
break;
}
@@ -746,7 +770,7 @@ read_shared_object (desc, entry)
(void)read(fd, armag, SARMAG);
(void)close(fd);
if (strncmp(armag, ARMAG, SARMAG) != 0) {
- error("%s: malformed silly archive",
+ warnx("%s: malformed silly archive",
get_file_name(entry));
goto out;
}
@@ -774,9 +798,8 @@ int
findlib(p)
struct file_entry *p;
{
- int desc;
int i;
- int len;
+ int fd = -1;
int major = -1, minor = -1;
char *cp, *fname = NULL;
@@ -785,14 +808,14 @@ struct file_entry *p;
fname = findshlib(p->filename, &major, &minor, 1);
- if (fname && (desc = open (fname, O_RDONLY, 0)) > 0) {
+ if (fname && (fd = open(fname, O_RDONLY, 0)) > 0) {
p->filename = fname;
p->lib_major = major;
p->lib_minor = minor;
p->flags &= ~E_SEARCH_DIRS;
- return desc;
+ return fd;
}
- free (fname);
+ (void)free(fname);
dot_a:
p->flags &= ~E_SEARCH_DYNAMIC;
@@ -804,16 +827,17 @@ dot_a:
fname = concat("lib", p->filename, ".a");
for (i = 0; i < n_search_dirs; i++) {
- register char *string
- = concat (search_dirs[i], "/", fname);
- desc = open (string, O_RDONLY, 0);
- if (desc > 0) {
- p->filename = string;
+ register char *path
+ = concat(search_dirs[i], "/", fname);
+ fd = open(path, O_RDONLY, 0);
+ if (fd > 0) {
+ p->filename = path;
p->flags &= ~E_SEARCH_DIRS;
break;
}
- free (string);
+ (void)free(path);
}
- return desc;
+ (void)free(fname);
+ return fd;
}
OpenPOWER on IntegriCloud