}
+#define RECORD_TYPE_EXTDEF 0x8C
+#define RECORD_TYPE_PUBDEF 0x90
+
+static void omf_get_symbols (void *object, char *filename, unsigned long bytes, long offset) {
+
+ unsigned char *pos = (unsigned char *) object;
+
+ unsigned char record_type;
+ unsigned short record_len;
+
+ unsigned char *pubdef_name, *pubdef_name_end;
+ unsigned char pubdef_name_len;
+
+ unsigned char *extdef_name, *extdef_name_end;
+ unsigned char extdef_name_len;
+
+ struct strtab *strtab;
+ int big_fields;
+
+ while (pos < (unsigned char *) object + bytes) {
+
+ record_type = pos[0];
+
+ big_fields = record_type & 1;
+ record_type &= ~1;
+
+ record_len = array_to_integer (pos + 1, 2);
+
+ {
+
+ unsigned char checksum = 0;
+ unsigned long i;
+
+ for (i = 0; i < (unsigned long) record_len + 3; i++) {
+ checksum += pos[i];
+ }
+
+ if (checksum != 0) {
+ report_at (program_name, 0, REPORT_WARNING, "%s: invalid checksum", filename);
+ }
+
+ }
+
+ pos += 3;
+
+ if (record_type == RECORD_TYPE_EXTDEF) {
+
+ extdef_name_end = (extdef_name = pos) + record_len - 1;
+
+ while (extdef_name != extdef_name_end) {
+
+ extdef_name_len = extdef_name[0];
+
+ if (extdef_name + 1 + extdef_name_len + 1 > extdef_name_end) {
+
+ report_at (program_name, 0, REPORT_FATAL_ERROR, "%s: incorrect string length", filename);
+ exit (EXIT_FAILURE);
+
+ }
+
+ strtab = xmalloc (sizeof (*strtab));
+ strtab->length = extdef_name_len;
+
+ strtab->name = xstrndup ((char *) extdef_name + 1, extdef_name_len);
+ strtab->offset = offset;
+
+ /*report_at (program_name, 0, REPORT_WARNING, "Got length of %#x for %s", extdef_name_len, strtab->name);*/
+
+ add_strtab (&gstrtab, strtab);
+ extdef_name = extdef_name + 1 + extdef_name_len + 1;
+
+ }
+
+ } else if (record_type == RECORD_TYPE_PUBDEF) {
+
+ pubdef_name_end = (pubdef_name = pos) + record_len - 3;
+
+ if (big_fields) {
+
+ report_at (program_name, 0, REPORT_INTERNAL_ERROR, "%s: big fields not supported for record %#x", filename, record_type);
+ exit (EXIT_FAILURE);
+
+ }
+
+ while (pubdef_name != pubdef_name_end) {
+
+ pubdef_name_len = pubdef_name[2];
+
+ if (pubdef_name + 2 + 1 + pubdef_name_len + 1 > pubdef_name_end) {
+
+ report_at (program_name, 0, REPORT_FATAL_ERROR, "%s: incorrect string length", filename);
+ exit (EXIT_FAILURE);
+
+ }
+
+ strtab = xmalloc (sizeof (*strtab));
+ strtab->length = pubdef_name_len;
+
+ strtab->name = xstrndup ((char *) pubdef_name + 3, pubdef_name_len);
+ strtab->offset = offset;
+
+ /*report_at (program_name, 0, REPORT_WARNING, "Got length of %#x for %s", pubdef_name_len, strtab->name);*/
+
+ add_strtab (&gstrtab, strtab);
+ pubdef_name = pubdef_name + 2 + 1 + pubdef_name_len + 1;
+
+ }
+
+ }
+
+ pos += record_len;
+
+ }
+
+}
+
void ranlib (void) {
FILE *tfp = tmpfile ();
void *contents;
char temp[16];
- /*int valid = 0;*/
for (;;) {
struct ar_header hdr;
- long bytes;
+ long bytes, real_size;
if (fread (&hdr, sizeof (hdr), 1, arfp) != 1) {
}
bytes = conv_dec (hdr.size, 10);
+ real_size = bytes;
if (bytes % 2) {
bytes++;
}
- /*valid = ((object[0] == 0x07 && object[1] == 0x01) || (object[0] == 0x4C && object[1] == 0x01) || (object[0] == 0x64 && object[1] == 0x86));
-
- if (!valid) {
-
- free (object);
-
- offset += sizeof (hdr);
- offset += bytes;
-
- fseek (arfp, bytes, SEEK_CUR);
- continue;
-
- }*/
-
if (object[0] == 0x07 && object[1] == 0x01) {
aout_get_symbols (object, offset + 8);
}
+ if (object[0] == 0x80 /* RECORD_TYPE_THEADR */) {
+
+ char filename[17] = { 0 };
+ memcpy (filename, hdr.name, 16);
+
+ for (i = 16; i >= 0; --i) {
+
+ if (filename[i] == ' ') {
+ filename[i] = '\0';
+ }
+
+ }
+
+ omf_get_symbols (object, filename, real_size, offset + 8);
+ free (object);
+
+ offset += sizeof (hdr);
+ offset += bytes;
+
+ continue;
+
+ }
+
free (object);
offset += sizeof (hdr);