OpenSSL-1.0.2d vs AIX5

Miért is menne elsőre?! Azt mondja, hogy:


cd crypto/sha
gcc -I.. -I../.. -I../modes -I../asn1 -I../evp -I../../include  -DZLIB_SHARED -DZLIB -DOPENSSL_THREADS -pthread -DDSO_DLFCN -DHAVE_DLFCN_H -std=gnu99 -D__UNIX__ -D__unix__=1 -Dnl_langinfo=local_nl_langinfo -DUSE_LOCAL_ISPRINT -D_GNU_SOURCE -D_XOPEN_SOURCE=500 -D_ALL_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -D_THREAD_SAFE -I/usr/local/include -maix32 -O -DB_ENDIAN -DOPENSSL_BN_ASM_MONT -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DAES_ASM -DVPAES_ASM -c  -o sha256p8-ppc.o sha256p8-ppc.s
Assembler:
sha256p8-ppc.s: line 11: invalid opcode or pseudo-op

Kieg:


$ /usr/bin/as -v
as V5.2
$ lsattr -El proc0 -a type
type PowerPC_POWER5 Processor type False

A kérdéses program:


     1  .machine        "any"
     2  .csect  .text[PR],7
     3  
     4  .globl  .sha256_block_p8
     5  .align  6
     6  .sha256_block_p8:
     7          stwu    1,-392(1)
     8          mflr    8
     9          li      10,175
    10          li      11,191
    11          stvx    20,10,1
    12          addi    10,10,32
    13          mfspr   12,256
    14          stvx    21,11,1
    15          addi    11,11,32
    16          stvx    22,10,1
    17          addi    10,10,32
    18          stvx    23,11,1
    19          addi    11,11,32
    20          stvx    24,10,1

Hozzászólások

Azt mondanám, hogy ez itt a gond: http://wiki.hup.hu/index.php/AIX_FAQ#Melyik_processzorokban_van_AltiVec…

Így készül az Assembly source:


crypto/sha# make -n sha256p8-ppc.s 
asm/sha512p8-ppc.pl  sha256p8-ppc.s

Az új fejlesztés a crypto/sha könyvtárban:


sha256p8-ppc.s # T .sha256_block_p8
sha512p8-ppc.s # T .sha512_block_p8

Ez mintha (talán esetleg) Power8-at jelentene (bár nekem Power7-en fordult, látszólag fut)

A régebbi:


sha256-ppc.c # T .sha256_block_ppc
sha512-ppc.c # T .sha512_block_ppc

Úgy tűnik, az a teória, hogy mindkét változatot lefordítja, és futáskor dönti el, hogy a CPU AltiVec-képes-e; lásd a crypto/ppccap.c programban:


void sha256_block_p8(void *ctx, const void *inp, size_t len);
void sha256_block_ppc(void *ctx, const void *inp, size_t len);
void sha256_block_data_order(void *ctx, const void *inp, size_t len)
{
    OPENSSL_ppccap_P & PPC_CRYPTO207 ? sha256_block_p8(ctx, inp, len) :
        sha256_block_ppc(ctx, inp, len);
}

Akkor most két lehetőséget látok:
1. egy újabb Assembler, ami lefordít egy olyan kódot is, ami az adott gépen nem is megy
2. (ha lehetséges) beszélni az OpenSSL-lel, hogy ne is próbálja ezt fordítani
3. cross-compile másik (újabb Assemblerű) gépen...

Na szóval ez nem megy 64-biten:


(make:) ld  -r -o libcrypto.o -bnogc libcrypto.a

ld: 0711-712 ERROR: Archive member libcrypto.a[ppccpuid.o]
is stripped. The member is being ignored.
...

(A -b64 opció helyett az OBJECT_MODE envirót állítja be, hogy ezzel is színesítse a dolgot)

A file(1) utility szerint minden object egyformán:


64-bit XCOFF executable or object module not stripped

Az például hihetetlen lenne, ha a 'gas' nevű komponens (2.15) símán lefordítaná a sha256p8-ppc.s -t. Márpedig lefordítja, csak a sha256-ppc.s -t nem hajlandó:


 1254 ???? 43200000     bc  25,0,Lrounds
****  Error:invalid conditional option

Szerintem ez a 'bdnz- Lrounds' utasítás eredménye... akármit is jelentsen ez.

bc

bo (25=11001,a=1,t=1):


1a00t 	Decrement the CTR; then branch if the decremented CTR is not 0.
at=11 	The branch is very likely to be taken.

Talán csak régi a gas

Aki arra tippelt volna, hogy binutils-2.25 fordítása sem lesz elsőre tökéletes, az most vállon veregetheti magát...


rs6000-core.c:112:20: error: field 'old' has incomplete type
rs6000-core.c:125:18: error: field 'old' has incomplete type
rs6000-core.c: In function 'read_hdr':
rs6000-core.c:286:10: error: dereferencing pointer to incomplete type
rs6000-core.c:286:10: error: dereferencing pointer to incomplete type
...

Szerk: Jajj, emlékszem, ezen a régi gépen nem tudok 64-bitest fordítani olyan programokból, amik a sys/core.h-t használnák

Szerk: valahogy összeállt a 32-bites gas, jelenség ugyanaz, viszont rájöttem, hogy a -mpower5 opciótól megjön az életkedve. Namostan hogy fogja ezt a gcc meghívni?

gas eredménye linkelésnél:


ld: 0711-593 SEVERE ERROR: Symbol .bn_sqr_comba4 (entry 2) in object libcrypto.a[bn-ppc.o]
:
        The symbol refers to a csect with symbol number 0, which was not
        found. The new symbol cannot be associated with a csect and
        is being ignored.

Az élet nem habostorta, Pelikán elvtárs!

Szerk: illetve már a gas is üzent korábban:


bn-ppc.s: Assembler messages:
bn-ppc.s: Warning: warning: symbol .bn_sqr_comba4 has no csect
bn-ppc.s: Warning: warning: symbol .bn_sqr_comba8 has no csect
bn-ppc.s: Warning: warning: symbol .bn_mul_comba4 has no csect

Hasonló:
https://github.com/ptudor/centos6-openssl/blob/master/SOURCES/openssl-1…

No, pusztán egy '.csect' hozzáadásától megjavult. Mármint 32-biten. 64-biten:


ld: 0711-712 ERROR: Archive member libcrypto.a[ppccpuid.o]
        is stripped. The member is being ignored.

És persze a Makefile.shared egy jó kis eszetlen kavarás, nehogy lássam, hogy mi is történik pontosan:


LINK_SO_A_VIA_O=        \
  SHOBJECTS=lib$(LIBNAME).o; \
  ALL=$$ALLSYMSFLAGS; ALLSYMSFLAGS=; NOALLSYMSFLAGS=; \
  ( $(SET_X); \
    ld $(LDFLAGS) -r -o lib$(LIBNAME).o $$ALL lib$(LIBNAME).a $(LIBEXTRAS) ); \
  $(LINK_SO) && rm -f lib$(LIBNAME).o

LINK_SO=        \
  ( $(SET_X);   \
    LIBDEPS="$${LIBDEPS:-$(LIBDEPS)}"; \
    SHAREDCMD="$${SHAREDCMD:-$(CC)}"; \
    SHAREDFLAGS="$${SHAREDFLAGS:-$(CFLAGS) $(SHARED_LDFLAGS)}"; \
    LIBPATH=`for x in $$LIBDEPS; do echo $$x; done | sed -e 's/^ *-L//;t' -e d | uniq`; \
    LIBPATH=`echo $$LIBPATH | sed -e 's/ /:/g'`; \
    LD_LIBRARY_PATH=$$LIBPATH:$$LD_LIBRARY_PATH \
    $${SHAREDCMD} $${SHAREDFLAGS} \
        -o $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX \
        $$ALLSYMSFLAGS $$SHOBJECTS $$NOALLSYMSFLAGS $$LIBDEPS \
  ) && $(SYMLINK_SO)

(Természetesen a LIBPATH és LD_LIBRARY_PATH változókat átalakítom másra, hiszen azoknak speéci jelentése van, nem pont azokkal kellene maszt... mesterkedni.)

64-biten a gyári 'as'-sal megy, a 'gas'-sal nem. (32-biten mindkettővel megy.) Az objdump a következő különbséget mutatja:


$ objdump -h crypto/ppccpuid_64.o

crypto/ppccpuid_64.o:     file format aix5coff64-rs6000

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         000001a0  0000000000000000  0000000000000000  00000060  2**2
                  CONTENTS, ALLOC, LOAD, CODE

$ objdump -h crypto/ppccpuid_g64.o

crypto/ppccpuid_g64.o:     file format aix5coff64-rs6000

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         00000200  0000000000000000  0000000000000000  000000f0  2**2
                  CONTENTS, ALLOC, LOAD, CODE
  1 .data         00000000  0000000000000200  0000000000000200  00000000  2**3
                  ALLOC, LOAD, DATA
  2 .bss          00000000  0000000000000200  0000000000000200  00000000  2**3

Vagyis a gas generált oda egy-egy üres .data és .bss section-t. De hogy ez-e a baj?

Szerk: ez a különbség 32-biten is megvan (de mint mondtam, ott mindkettővel mükszik.)

Szerk: úgy tűnik, hogy egy HAS_RELOC nevű jelző hiányzik valamiért a 64-bites gas-kimenetből

Szerk: itt kellene nyomozni:


binutils/filehdr.h
  /* BFD contains relocation entries.  */
#define HAS_RELOC      0x01

/usr/include/filehdr.h
 *    Bits for f_flags: (Most were defined for original COFF)
 *
 *    F_RELFLG       relocation info stripped from file
#define F_RELFLG 0x0001

Na itten kell nézelődni:


binutils-2.25/bfd/coffcode.h
binutils-2.25/bfd/coff-rs6000.c
binutils-2.25/bfd/coff64-rs6000.c

a harmadikban van egy ilyesmi:


static bfd_boolean
xcoff64_write_object_contents (bfd *abfd)
{
...
      if (current->reloc_count != 0)
        hasrelocs = TRUE;

...
  if (!hasrelocs)
    internal_f.f_flags |= F_RELFLG;
...
}

Szerk: Na az a rendkívül tudományos módszer pl működik, hogy hex-editorral kitörlöm a problémás flag-et... na jó, ez talán nem a végleges megoldás...

Nocsak, nocsak, nocsak, mit nem találok a coffcode.h-ban:


#ifdef RS6000COFF_C
      /* AIX appears to require that F_RELFLG not be set if there are
         local symbols but no relocations.  */
      internal_f.f_flags &=~ F_RELFLG;
#endif

Akkor már csak a coff64-rs6000.c-be kellene ugyanezt/hasonlót belehaxorizálni.

Szerk:
https://sourceware.org/bugzilla/show_bug.cgi?id=18671

A napló kevéért: az 5.3-as Assembler tudja az AltiVec-et, csak az 5.2-es nem... Néha tényleg jó lenne, ha nem félnék ennyire update-elni... végül is, az adatokon kívül nem veszthetünk semmit...