Description: * This patch enables libiberty to read AIX XCOFF. Tests: * Fedora25/x86_64 + GCC v7.1.0 : Configure/Build: SUCCESS - build made by means of a .spec file based on Fedora gcc-7.0.1-0.12 .spec file ../configure --enable-bootstrap --enable-languages=c,c++,objc,obj-c++,fortran,go,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl --enable-libmpx --enable-offload-targets=nvptx-none --without-cuda-driver --enable-gnu-indirect-function --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
ChangeLog: * libiberty/simple-object-xcoff.c: Enable libiberty to read AIX XCOFF Regards, Tony Reix Bull - ATOS IBM Coop Architect & Technical Leader Office : +33 (0) 4 76 29 72 67 1 rue de Provence - 38432 Échirolles - France www.atos.net
--- ./libiberty/simple-object-xcoff.c.ORIGIN 2017-03-21 17:08:59 -0500 +++ ./libiberty/simple-object-xcoff.c 2017-03-21 16:45:43 -0500 @@ -258,6 +258,8 @@ #define C_STAT (3) #define C_FILE (103) +#define DBXMASK 0x80 + /* Private data for an simple_object_read. */ struct simple_object_xcoff_read @@ -403,7 +405,9 @@ unsigned int nscns; char *strtab; size_t strtab_size; + struct external_syment *symtab = NULL; unsigned int i; + off_t textptr = 0; scnhdr_size = u64 ? SCNHSZ64 : SCNHSZ32; scnbuf = XNEWVEC (unsigned char, scnhdr_size * ocr->nscns); @@ -485,10 +489,116 @@ u.xcoff32.s_size)); } + if (strcmp (name, ".text") == 0) + textptr = scnptr; if (!(*pfn) (data, name, scnptr, size)) break; } + /* Special handling for .go_export CSECT. */ + if (textptr != 0 && ocr->nsyms > 0) + { + unsigned char *sym, *aux; + const char *n_name; + unsigned long n_value, n_offset, n_zeroes, x_scnlen; + + /* Read symbol table. */ + symtab = XNEWVEC (struct external_syment, ocr->nsyms * SYMESZ); + if (!simple_object_internal_read (sobj->descriptor, + sobj->offset + ocr->symptr, + (unsigned char *)symtab, + ocr->nsyms * SYMESZ, + &errmsg, err)) + { + XDELETEVEC (symtab); + XDELETEVEC (scnbuf); + return NULL; + } + /* Search in symbol table if we have a ".go_export" symbol. */ + for (i = 0; i < ocr->nsyms; ++i) + { + sym = (unsigned char *)&symtab[i]; + + if (symtab[i].n_sclass[0] & DBXMASK) + { + /* Skip debug symbols whose names are in stabs. */ + i += symtab[i].n_numaux[0]; + continue; + } + if (u64) + { + n_value = fetch_64 (sym + offsetof (struct external_syment, + u.xcoff64.n_value)); + n_offset = fetch_32 (sym + offsetof (struct external_syment, + u.xcoff64.n_offset)); + } + else + { + /* ".go_export" is longer than N_SYMNMLEN */ + n_zeroes = fetch_32 (sym + offsetof (struct external_syment, + u.xcoff32.n.n.n_zeroes)); + if (n_zeroes != 0) + { + /* Skip auxiliary entries. */ + i += symtab[i].n_numaux[0]; + continue; + } + n_value = fetch_32 (sym + offsetof (struct external_syment, + u.xcoff32.n_value)); + n_offset = fetch_32 (sym + offsetof (struct external_syment, + u.xcoff32.n.n.n_offset)); + } + /* The real section name is found in the string + table. */ + if (strtab == NULL) + { + strtab = simple_object_xcoff_read_strtab (sobj, + &strtab_size, + &errmsg, err); + if (strtab == NULL) + { + XDELETEVEC (symtab); + XDELETEVEC (scnbuf); + return errmsg; + } + } + + if (n_offset >= strtab_size) + { + XDELETEVEC (strtab); + XDELETEVEC (symtab); + XDELETEVEC (scnbuf); + *err = 0; + return "section string index out of range"; + } + n_name = strtab + n_offset; + if (!strcmp(n_name, ".go_export")) + { + /* Found .go_export symbol, read auxiliary entry. */ + if (i + 1 >= ocr->nsyms) + break; + + aux = (unsigned char *)&symtab[i + 1]; + if (u64) + { + x_scnlen = fetch_32 (aux + offsetof (union external_auxent, + u.xcoff64.x_csect.x_scnlen_lo)); + } + else + { + x_scnlen = fetch_32 (aux + offsetof (union external_auxent, + u.xcoff32.x_csect.x_scnlen)); + } + (*pfn) (data, ".go_export", textptr + n_value, x_scnlen); + break; + } + /* Skip auxiliary entries. */ + i += symtab[i].n_numaux[0]; + } + } + + if (symtab != NULL) + XDELETEVEC (symtab); if (strtab != NULL) XDELETEVEC (strtab); XDELETEVEC (scnbuf);