1 /* lkar.c - ar library format handling
3 Copyright (C) 1989-1995 Alan R. Baldwin
4 721 Berkeley St., Kent, Ohio 44240
5 Copyright (C) 2008-2009 Borut Razem, borut dot razem at siol dot net
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 * With contributions for the
23 * object libraries from
25 * kenh@cmf.nrl.navy.mil
30 * Extensions: P. Felber
45 # define max(a,b) ((a) > (b) ? (a) : (b))
49 # define min(a,b) ((a) < (b) ? (a) : (b))
59 if (!(ret = fread (buf, 1, sizeof (buf), libfp) == sizeof (buf) && memcmp (buf, ARMAG, SARMAG) == 0))
65 static struct ar_hdr *
66 ar_get_header (struct ar_hdr *hdr, FILE * libfp)
68 char header[ARHDR_LEN];
69 char buf[AR_DATE_LEN + 1];
71 if (fread (header, 1, sizeof (header), libfp) != sizeof (header)
72 || memcmp (header + AR_FMAG_OFFSET, ARFMAG, AR_FMAG_LEN) != 0)
74 /* not an ar archive */
78 memcpy (hdr->ar_name, &header[AR_NAME_OFFSET], AR_NAME_LEN);
79 hdr->ar_name[AR_NAME_LEN] = '\0';
81 memcpy (buf, &header[AR_DATE_OFFSET], AR_DATE_LEN);
82 buf[AR_DATE_LEN] = '\0';
83 hdr->ar_date = strtol (buf, NULL, 0);
85 memcpy (buf, &header[AR_UID_OFFSET], AR_GID_LEN);
86 buf[AR_GID_LEN] = '\0';
87 hdr->ar_uid = (uid_t) strtol (buf, NULL, 0);
89 memcpy (buf, &header[AR_GID_OFFSET], AR_DATE_LEN);
90 buf[AR_DATE_LEN] = '\0';
91 hdr->ar_gid = (gid_t) strtol (buf, NULL, 0);
93 memcpy (buf, &header[AR_MODE_OFFSET], AR_MODE_LEN);
94 buf[AR_MODE_LEN] = '\0';
95 hdr->ar_mode = (mode_t) strtoul (buf, NULL, 0);
97 memcpy (buf, &header[AR_SIZE_OFFSET], AR_SIZE_LEN);
98 buf[AR_SIZE_LEN] = '\0';
99 hdr->ar_size = strtol (buf, NULL, 0);
104 static char *sym_tab;
105 static int sym_tab_size;
108 loadfile_ar (struct lbfile *lbfh)
113 char posix_path[PATH_MAX];
114 void cygwin_conv_to_full_posix_path (char *win_path, char *posix_path);
115 cygwin_conv_to_full_posix_path (lbfh->libspc, posix_path);
116 fp = fopen (posix_path, "rb");
118 fp = fopen (lbfh->libspc, "rb");
125 fseek (fp, lbfh->offset, SEEK_SET);
126 if (ar_get_header (&hdr, fp))
128 D ("Loading module %s from file %s.\n", hdr.ar_name, lbfh->libspc);
129 load_rel (fp, hdr.ar_size);
134 fprintf (stderr, "?ASlink-Error-Bad offset in library file %s(%s)\n", lbfh->libspc, lbfh->relfil);
141 fprintf (stderr, "?ASlink-Error-Opening library '%s'\n", lbfh->libspc);
148 get_member_name (char *name)
156 int name_offset = strtol (++name, &p, 0);
157 if (p != name && name_offset < sym_tab_size)
159 int len = p - name + 1;
160 while (len < AR_NAME_LEN && name[len++] == ' ')
162 if (len == AR_NAME_LEN)
166 /* long name: get it from the symbol table */
167 name = &sym_tab[name_offset];
168 for (p = name; *p != '/' && *p != '\n'; ++p)
169 assert (p < &sym_tab[sym_tab_size]);
171 if (p[0] != '/' || p[1] != '\n')
173 assert (p < &sym_tab[sym_tab_size]);
175 n = (char *) malloc (p - name + 1);
176 memcpy (n, name, p - name);
185 char *p = strrchr (name, '/');
190 while (name[++len] == ' ')
192 if (len == AR_NAME_LEN)
194 char *n = (char *) malloc (p - name + 1);
195 memcpy (n, name, p - name);
202 /* bad formed member name:
205 return strdup (name);
209 get_member_name_by_offset (FILE * fp, long offset)
213 fseek (fp, offset, SEEK_SET);
215 /* walk trough all archive members */
216 return (NULL != ar_get_header (&hdr, fp)) ? get_member_name (hdr.ar_name) : NULL;
220 find_member_by_offset (const char *libspc, long offset)
224 for (p = libr; p; p = p->next)
226 if (0 == strcmp (libspc, p->libspc) && p->offset == offset)
234 buildlibraryindex_ar (struct lbname *lbnh, FILE * libfp, pmlibraryfile This, int type)
238 /* walk trough all archive members */
239 while (ar_get_header (&hdr, libfp))
241 if (AR_IS_SYMBOL_TABLE (hdr))
247 buf = (char *) new (hdr.ar_size);
249 if ((off_t) fread (buf, 1, hdr.ar_size, libfp) != hdr.ar_size)
260 for (i = 0; i < nsym; ++i)
262 pmlibrarysymbol ThisSym;
271 while (*ps++ != '\0')
274 if ((entry = find_member_by_offset (lbnh->libspc, offset)) != NULL)
276 for (ThisSym = entry->symbols; ThisSym->next != NULL; ThisSym = ThisSym->next)
281 /* Opened OK - create a new libraryfile object for it */
284 assert (libr == NULL);
285 libr = This = (pmlibraryfile) new (sizeof (mlibraryfile));
289 This->next = (pmlibraryfile) new (sizeof (mlibraryfile));
294 This->libspc = lbnh->libspc;
295 This->offset = offset;
296 This->relfil = get_member_name_by_offset (libfp, offset); /* member name */
297 This->filspc = strdup (This->relfil); /* member file name */
300 /* start a new linked list of symbols for this module. */
301 This->symbols = ThisSym = NULL;
305 ThisSym = This->symbols = (pmlibrarysymbol) new (sizeof (mlibrarysymbol));
308 ThisSym->next = (pmlibrarysymbol) new (sizeof (mlibrarysymbol));
309 ThisSym = ThisSym->next;
312 ThisSym->next = NULL;
319 else if (AR_IS_STRING_TABLE (hdr))
324 sym_tab = (char *) new (hdr.ar_size);
326 if ((off_t) fread (sym_tab, 1, hdr.ar_size, libfp) != hdr.ar_size)
332 sym_tab_size = hdr.ar_size;
336 long moduleOffset = ftell (libfp);
338 /* Opened OK - create a new libraryfile object for it */
341 assert (libr == NULL);
342 libr = This = (pmlibraryfile) new (sizeof (mlibraryfile));
346 This->next = (pmlibraryfile) new (sizeof (mlibraryfile));
351 This->libspc = lbnh->libspc;
352 This->offset = moduleOffset - ARHDR_LEN;
354 This->relfil = get_member_name (hdr.ar_name); /* member name */
355 This->filspc = strdup (This->relfil); /* member file name */
357 D (" Indexing module: %s\n", This->relfil);
361 /* start a new linked list of symbols for this module. */
362 This->symbols = NULL;
364 add_rel_index (libfp, hdr.ar_size, This);
366 fseek (libfp, moduleOffset + hdr.ar_size, SEEK_SET);
371 int c = getc (libfp);
372 assert (c == EOF || c == '\n');
390 load_adb (FILE * libfp, struct lbfile *lbfh)
395 /* check if it is a .rel file */
396 if (0 != stricmp (&lbfh->relfil[strlen (lbfh->relfil) - 4], ".rel"))
400 adb_name = (char *) new (strlen (lbfh->relfil) + 1);
401 memcpy (adb_name, lbfh->relfil, strlen (lbfh->relfil) - 4);
402 memcpy (&adb_name[strlen (lbfh->relfil) - 4], ".adb", 5);
406 fprintf (stderr, "?ASlink-Error-%s is not an archive\n", lbfh->libspc);
412 /* walk trough all archive members */
413 while (ar_get_header (&hdr, libfp))
415 if (AR_IS_STRING_TABLE (hdr))
420 sym_tab = (char *) new (hdr.ar_size);
422 if ((off_t) fread (sym_tab, 1, hdr.ar_size, libfp) != hdr.ar_size)
428 sym_tab_size = hdr.ar_size;
430 if (AR_IS_SYMBOL_TABLE (hdr) || 0 != stricmp (get_member_name (hdr.ar_name), adb_name))
432 /* skip the mamber */
433 fseek (libfp, hdr.ar_size + (hdr.ar_size & 1), SEEK_CUR);
437 long left = hdr.ar_size;
442 size_t n = min (left, sizeof buf);
444 if (fread (buf, 1, n, libfp) != n)
449 fwrite (buf, 1, n, dfp);
456 int c = getc (libfp);
457 assert (c == EOF || c == '\n');
471 fndsym_ar (const char *name, struct lbname *lbnh, FILE * libfp, int type)
476 /* walk trough all archive members */
477 while (ar_get_header (&hdr, libfp))
479 char filspc[PATH_MAX];
481 if (lbnh->path != NULL)
483 strcpy (filspc, lbnh->path);
485 if (*filspc != '\0' && (filspc[strlen (filspc) - 1] != '/') && (filspc[strlen (filspc) - 1] != LKDIRSEP))
487 strcat (filspc, LKDIRSEPSTR);
492 if (AR_IS_SYMBOL_TABLE (hdr))
498 buf = (char *) new (hdr.ar_size);
500 if ((off_t) fread (buf, 1, hdr.ar_size, libfp) != hdr.ar_size)
511 for (i = 0; i < nsym; ++i)
520 while (*ps++ != '\0')
523 if (0 == strcmp (name, sym))
525 fseek (libfp, offset, SEEK_SET);
526 if (ar_get_header (&hdr, libfp))
528 sprintf (&filspc[strlen (filspc)], "%s", hdr.ar_name);
530 /* If this module has been loaded already don't load it again. */
531 if (!is_module_loaded (filspc))
533 struct lbfile *lbfh, *lbf;
535 lbfh = (struct lbfile *) new (sizeof (struct lbfile));
536 lbfh->libspc = strdup (lbnh->libspc);
537 lbfh->relfil = strdup (hdr.ar_name);
538 lbfh->filspc = strdup (filspc);
539 lbfh->offset = offset;
548 for (lbf = lbfhead; lbf->next != NULL; lbf = lbf->next)
554 D ("Loading module %s from file %s.\n", hdr.ar_name, lbfh->libspc);
555 load_rel (libfp, hdr.ar_size);
556 ///* if cdb information required & .adb file present */
559 // if (load_adb(FILE *libfp, struct lbfile *lbfh))
560 // SaveLinkedFilePath (filspc);
568 fprintf (stderr, "?ASlink-Error-Bad offset in library file %s(%s)\n", lbnh->libspc, name);
578 else if (AR_IS_STRING_TABLE (hdr))
583 sym_tab = (char *) new (hdr.ar_size);
585 if ((off_t) fread (sym_tab, 1, hdr.ar_size, libfp) != hdr.ar_size)
592 sym_tab_size = hdr.ar_size;
596 long moduleOffset = ftell (libfp);
598 D (" Module: %s\n", hdr.ar_name);
600 sprintf (&filspc[strlen (filspc)], "%s", hdr.ar_name);
602 /* Opened OK - create a new libraryfile object for it */
603 ret = add_rel_file (name, lbnh, hdr.ar_name, filspc, moduleOffset - ARHDR_LEN, libfp, hdr.ar_size, type);
604 ///* if cdb information required & .adb file present */
607 // if (load_adb(FILE *libfp, struct lbfile *lbfh))
608 // SaveLinkedFilePath (filspc);
613 fseek (libfp, moduleOffset + hdr.ar_size, SEEK_SET);
618 int c = getc (libfp);
619 assert (c == EOF || c == '\n');
634 struct aslib_target aslib_target_ar = {
637 &buildlibraryindex_ar,