From 084a6a3d98ef33be4c01ed4d3c7a2acb8b72b448 Mon Sep 17 00:00:00 2001 From: dkimitsa Date: Wed, 6 Apr 2022 18:40:24 +0300 Subject: [PATCH 1/3] * fix for `ld: unaligned pointer(s) for architecture arm64` 1. attribute/class info structs: these are now generated to be not packed (will consume a bit more ram) 2. VM code updated to new structure layouts 3. Debugger code updated to new structure layouts --- .../robovm/compiler/AttributesEncoder.java | 97 ++++++++++--------- .../org/robovm/compiler/ClassCompiler.java | 3 +- .../compiler/llvm/StructureConstant.java | 28 ++++++ compiler/vm/bc/src/aligned.h | 71 ++++++++++++++ compiler/vm/bc/src/classinfo.c | 2 +- compiler/vm/core/src/attribute.c | 52 ++++++---- .../state/classdata/ClassInfoImpl.java | 10 +- .../state/classdata/ClassInfoLoader.java | 2 +- .../debugger/state/classdata/FieldInfo.java | 8 +- .../debugger/state/classdata/MethodInfo.java | 18 ++-- .../utils/bytebuffer/DataBufferReader.java | 10 ++ 11 files changed, 213 insertions(+), 88 deletions(-) create mode 100755 compiler/vm/bc/src/aligned.h diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/AttributesEncoder.java b/compiler/compiler/src/main/java/org/robovm/compiler/AttributesEncoder.java index 04cd8e50c..859426dc9 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/AttributesEncoder.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/AttributesEncoder.java @@ -33,8 +33,8 @@ import org.robovm.compiler.llvm.Global; import org.robovm.compiler.llvm.IntegerConstant; import org.robovm.compiler.llvm.Linkage; -import org.robovm.compiler.llvm.PackedStructureConstant; -import org.robovm.compiler.llvm.PackedStructureType; +import org.robovm.compiler.llvm.StructureConstant; +import org.robovm.compiler.llvm.StructureType; import org.robovm.compiler.llvm.StructureConstant; import org.robovm.compiler.llvm.Type; import org.robovm.compiler.llvm.Value; @@ -92,10 +92,10 @@ public class AttributesEncoder { public void encode(ModuleBuilder mb, SootClass sootClass) { this.mb = mb; - dependencies = new HashSet(); + dependencies = new HashSet<>(); classAttributes = null; - fieldAttributes = new HashMap(); - methodAttributes = new HashMap(); + fieldAttributes = new HashMap<>(); + methodAttributes = new HashMap<>(); encodeAttributes(sootClass); Constant classAttributes = encodeAttributes(sootClass); @@ -152,21 +152,21 @@ public Global getMethodAttributes(SootMethod m) { return methodAttributes.get(m); } - private PackedStructureType getAnnotationElementType(AnnotationElem ae) { + private StructureType getAnnotationElementType(AnnotationElem ae) { if (ae instanceof AnnotationIntElem) { - return new PackedStructureType(I8, I32); + return new StructureType(I8, I32); } else if (ae instanceof AnnotationLongElem) { - return new PackedStructureType(I8, I64); + return new StructureType(I8, I64); } else if (ae instanceof AnnotationFloatElem) { - return new PackedStructureType(I8, FLOAT); + return new StructureType(I8, FLOAT); } else if (ae instanceof AnnotationDoubleElem) { - return new PackedStructureType(I8, DOUBLE); + return new StructureType(I8, DOUBLE); } else if (ae instanceof AnnotationStringElem) { - return new PackedStructureType(I8, I8_PTR); + return new StructureType(I8, I8_PTR); } else if (ae instanceof AnnotationClassElem) { - return new PackedStructureType(I8, I8_PTR); + return new StructureType(I8, I8_PTR); } else if (ae instanceof AnnotationEnumElem) { - return new PackedStructureType(I8, I8_PTR, I8_PTR); + return new StructureType(I8, I8_PTR, I8_PTR); } else if (ae instanceof AnnotationArrayElem) { AnnotationArrayElem aae = (AnnotationArrayElem) ae; Type[] types = new Type[aae.getNumValues() + 2]; @@ -175,46 +175,46 @@ private PackedStructureType getAnnotationElementType(AnnotationElem ae) { for (int i = 0; i < aae.getNumValues(); i++) { types[i + 2] = getAnnotationElementType(aae.getValueAt(i)); } - return new PackedStructureType(types); + return new StructureType(types); } else if (ae instanceof AnnotationAnnotationElem) { AnnotationAnnotationElem aae = (AnnotationAnnotationElem) ae; - return new PackedStructureType(I8, getAnnotationTagType(aae.getValue())); + return new StructureType(I8, getAnnotationTagType(aae.getValue())); } throw new IllegalArgumentException("Unknown AnnotationElem type: " + ae.getClass()); } - private PackedStructureConstant encodeAnnotationElementValue(AnnotationElem ae) { - PackedStructureType type = getAnnotationElementType(ae); + private StructureConstant encodeAnnotationElementValue(AnnotationElem ae) { + StructureType type = getAnnotationElementType(ae); Value kind = new IntegerConstant((byte) ae.getKind()); if (ae instanceof AnnotationIntElem) { AnnotationIntElem aie = (AnnotationIntElem) ae; - return new PackedStructureConstant(type, kind, + return new StructureConstant(type, kind, new IntegerConstant(aie.getValue())); } else if (ae instanceof AnnotationLongElem) { AnnotationLongElem ale = (AnnotationLongElem) ae; - return new PackedStructureConstant(type, kind, + return new StructureConstant(type, kind, new IntegerConstant(ale.getValue())); } else if (ae instanceof AnnotationFloatElem) { AnnotationFloatElem afe = (AnnotationFloatElem) ae; - return new PackedStructureConstant(type, kind, + return new StructureConstant(type, kind, new FloatingPointConstant(afe.getValue())); } else if (ae instanceof AnnotationDoubleElem) { AnnotationDoubleElem ade = (AnnotationDoubleElem) ae; - return new PackedStructureConstant(type, kind, + return new StructureConstant(type, kind, new FloatingPointConstant(ade.getValue())); } else if (ae instanceof AnnotationStringElem) { AnnotationStringElem ase = (AnnotationStringElem) ae; - return new PackedStructureConstant(type, kind, + return new StructureConstant(type, kind, getStringOrNull(ase.getValue())); } else if (ae instanceof AnnotationClassElem) { AnnotationClassElem ace = (AnnotationClassElem) ae; addDependencyIfNeeded(ace.getDesc()); - return new PackedStructureConstant(type, kind, + return new StructureConstant(type, kind, getStringOrNull(ace.getDesc())); } else if (ae instanceof AnnotationEnumElem) { AnnotationEnumElem aee = (AnnotationEnumElem) ae; addDependencyIfNeeded(aee.getTypeName()); - return new PackedStructureConstant(type, kind, + return new StructureConstant(type, kind, getStringOrNull(aee.getTypeName()), getStringOrNull(aee.getConstantName())); } else if (ae instanceof AnnotationArrayElem) { @@ -225,15 +225,15 @@ private PackedStructureConstant encodeAnnotationElementValue(AnnotationElem ae) for (int i = 0; i < aae.getNumValues(); i++) { values[i + 2] = encodeAnnotationElementValue(aae.getValueAt(i)); } - return new PackedStructureConstant(type, values); + return new StructureConstant(type, values); } else if (ae instanceof AnnotationAnnotationElem) { AnnotationAnnotationElem aae = (AnnotationAnnotationElem) ae; - return new PackedStructureConstant(type, kind, encodeAnnotationTagValue(aae.getValue())); + return new StructureConstant(type, kind, encodeAnnotationTagValue(aae.getValue())); } throw new IllegalArgumentException("Unknown AnnotationElem type: " + ae.getClass()); } - private PackedStructureType getAnnotationTagType(AnnotationTag tag) { + private StructureType getAnnotationTagType(AnnotationTag tag) { Type[] types = new Type[tag.getNumElems() * 2 + 2]; types[0] = I8_PTR; types[1] = I32; @@ -241,10 +241,10 @@ private PackedStructureType getAnnotationTagType(AnnotationTag tag) { types[i * 2 + 2] = I8_PTR; types[i * 2 + 2 + 1] = getAnnotationElementType(tag.getElemAt(i)); } - return new PackedStructureType(types); + return new StructureType(types); } - private PackedStructureConstant encodeAnnotationTagValue(AnnotationTag tag) { + private StructureConstant encodeAnnotationTagValue(AnnotationTag tag) { Value[] values = new Value[tag.getNumElems() * 2 + 2]; values[0] = getString(tag.getType()); addDependencyIfNeeded(tag.getType()); @@ -253,27 +253,27 @@ private PackedStructureConstant encodeAnnotationTagValue(AnnotationTag tag) { values[i * 2 + 2] = getString(tag.getElemAt(i).getName()); values[i * 2 + 2 + 1] = encodeAnnotationElementValue(tag.getElemAt(i)); } - return new PackedStructureConstant(getAnnotationTagType(tag), values); + return new StructureConstant(getAnnotationTagType(tag), values); } private Constant encodeAttributes(Host host) { - List attributes = new ArrayList(); + List attributes = new ArrayList<>(); for (Tag tag : host.getTags()) { if (tag instanceof SourceFileTag) { // Skip. We don't need this at this time. Value sourceFile = getString(((SourceFileTag) tag).getSourceFile()); - attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I8_PTR), + attributes.add(new StructureConstant(new StructureType(I8, I8_PTR), new IntegerConstant(SOURCE_FILE), sourceFile)); } else if (tag instanceof EnclosingMethodTag) { EnclosingMethodTag emt = (EnclosingMethodTag) tag; Value eClass = getString(emt.getEnclosingClass()); Value eMethod = getStringOrNull(emt.getEnclosingMethod()); Value eDesc = getStringOrNull(emt.getEnclosingMethodSig()); - attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I8_PTR, I8_PTR, I8_PTR), + attributes.add(new StructureConstant(new StructureType(I8, I8_PTR, I8_PTR, I8_PTR), new IntegerConstant(ENCLOSING_METHOD), eClass, eMethod, eDesc)); } else if (tag instanceof SignatureTag) { Value signature = getString(((SignatureTag) tag).getSignature()); - attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I8_PTR), + attributes.add(new StructureConstant(new StructureType(I8, I8_PTR), new IntegerConstant(SIGNATURE), signature)); } else if (tag instanceof InnerClassTag) { InnerClassTag ict = (InnerClassTag) tag; @@ -281,11 +281,11 @@ private Constant encodeAttributes(Host host) { Value outerClass = getStringOrNull(ict.getOuterClass()); Value innerName = getStringOrNull(ict.getShortName()); Value innerClassAccess = new IntegerConstant(ict.getAccessFlags()); - attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I8_PTR, I8_PTR, I8_PTR, I32), + attributes.add(new StructureConstant(new StructureType(I8, I8_PTR, I8_PTR, I8_PTR, I32), new IntegerConstant(INNER_CLASS), innerClass, outerClass, innerName, innerClassAccess)); } else if (tag instanceof AnnotationDefaultTag) { StructureConstant value = encodeAnnotationElementValue(((AnnotationDefaultTag) tag).getDefaultVal()); - attributes.add(new PackedStructureConstant(new PackedStructureType(I8, value.getType()), + attributes.add(new StructureConstant(new StructureType(I8, value.getType()), new IntegerConstant(ANNOTATION_DEFAULT), value)); } else if (tag instanceof VisibilityAnnotationTag) { VisibilityAnnotationTag vat = (VisibilityAnnotationTag) tag; @@ -298,14 +298,14 @@ private Constant encodeAttributes(Host host) { types[i] = values[i].getType(); i++; } - attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I32, new PackedStructureType(types)), + attributes.add(new StructureConstant(new StructureType(I8, I32, new StructureType(types)), new IntegerConstant(RUNTIME_VISIBLE_ANNOTATIONS), new IntegerConstant(vat.getAnnotations().size()), - new PackedStructureConstant(new PackedStructureType(types), values))); + new StructureConstant(new StructureType(types), values))); } } else if (tag instanceof VisibilityParameterAnnotationTag) { VisibilityParameterAnnotationTag vpat = (VisibilityParameterAnnotationTag) tag; - List typesList = new ArrayList(); - List valuesList = new ArrayList(); + List typesList = new ArrayList<>(); + List valuesList = new ArrayList<>(); boolean hasRuntimeVisible = false; for (VisibilityAnnotationTag vat : vpat.getVisibilityAnnotations()) { typesList.add(I32); @@ -315,19 +315,20 @@ private Constant encodeAttributes(Host host) { hasRuntimeVisible = true; valuesList.add(new IntegerConstant(vat.getAnnotations().size())); for (AnnotationTag at : vat.getAnnotations()) { - valuesList.add(encodeAnnotationTagValue(at)); - typesList.add(valuesList.get(valuesList.size() - 1).getType()); + StructureConstant value = encodeAnnotationTagValue(at); + valuesList.add(value); + typesList.add(value.getType()); } } else { valuesList.add(new IntegerConstant(0)); } } if (hasRuntimeVisible) { - Type[] types = typesList.toArray(new Type[typesList.size()]); - Value[] values = valuesList.toArray(new Value[valuesList.size()]); - attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I32, new PackedStructureType(types)), + Type[] types = typesList.toArray(new Type[0]); + Value[] values = valuesList.toArray(new Value[0]); + attributes.add(new StructureConstant(new StructureType(I8, I32, new StructureType(types)), new IntegerConstant(RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS), new IntegerConstant(vpat.getVisibilityAnnotations().size()), - new PackedStructureConstant(new PackedStructureType(types), values))); + new StructureConstant(new StructureType(types), values))); } } } @@ -340,7 +341,7 @@ private Constant encodeAttributes(Host host) { values[i] = getString(exName); addDependency(exName); } - attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I32, new ArrayType(exceptions.size(), I8_PTR)), + attributes.add(new StructureConstant(new StructureType(I8, I32, new ArrayType(exceptions.size(), I8_PTR)), new IntegerConstant(EXCEPTIONS), new IntegerConstant(exceptions.size()), new ArrayConstant(new ArrayType(exceptions.size(), I8_PTR), values))); } @@ -356,7 +357,7 @@ private Constant encodeAttributes(Host host) { for (int i = 0; i < types.length; i++) { types[i] = attributes.get(i).getType(); } - return new PackedStructureConstant(new PackedStructureType(types), attributes.toArray(new Value[0])); + return new StructureConstant(new StructureType(types), attributes.toArray(new Value[0])).flatten(); } private Constant getString(String string) { diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/ClassCompiler.java b/compiler/compiler/src/main/java/org/robovm/compiler/ClassCompiler.java index 0291491f5..2669072b5 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/ClassCompiler.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/ClassCompiler.java @@ -52,7 +52,6 @@ import org.robovm.compiler.llvm.Load; import org.robovm.compiler.llvm.NullConstant; import org.robovm.compiler.llvm.Ordering; -import org.robovm.compiler.llvm.PackedStructureConstantBuilder; import org.robovm.compiler.llvm.PointerType; import org.robovm.compiler.llvm.Ret; import org.robovm.compiler.llvm.Store; @@ -1304,7 +1303,7 @@ private StructureConstant createClassInfoStruct() { header.add(new IntegerConstant((short) countReferences(classFields))); header.add(new IntegerConstant((short) countReferences(instanceFields))); - PackedStructureConstantBuilder body = new PackedStructureConstantBuilder(); + StructureConstantBuilder body = new StructureConstantBuilder(); body.add(new IntegerConstant((short) sootClass.getInterfaceCount())); body.add(new IntegerConstant((short) sootClass.getFieldCount())); body.add(new IntegerConstant((short) sootClass.getMethodCount())); diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/StructureConstant.java b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/StructureConstant.java index b1878a069..20188fe08 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/llvm/StructureConstant.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/llvm/StructureConstant.java @@ -16,6 +16,9 @@ */ package org.robovm.compiler.llvm; +import java.util.ArrayList; +import java.util.List; + /** * * @version $Id$ @@ -34,6 +37,31 @@ public StructureType getType() { return type; } + + + // flatten all contained structs in way removing struct and inserting struct members + private static void flattenInto(List dest, StructureConstant struct) { + for (Value v: struct.values) { + if (v instanceof StructureConstant) + flattenInto(dest, (StructureConstant)v); + else + dest.add(v); + } + } + + public StructureConstant flatten() { + List flattenValues = new ArrayList<>(); + flattenInto(flattenValues, this); + + Type[] types = new Type[flattenValues.size()]; + int i = 0; + for (Value v : flattenValues) { + types[i++] = v.getType(); + } + + return new StructureConstant(new StructureType(types), flattenValues.toArray(new Value[0])); + } + @Override public String toString() { StringBuilder sb = new StringBuilder(); diff --git a/compiler/vm/bc/src/aligned.h b/compiler/vm/bc/src/aligned.h new file mode 100755 index 000000000..9a031723e --- /dev/null +++ b/compiler/vm/bc/src/aligned.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2012 RoboVM AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef ALIGNED_H +#define ALIGNED_H + +#include + +#define ALIGN(pp, t) (void*)(((uintptr_t) (pp) + sizeof(t) - 1) & ~(sizeof(t) - 1)) + +static inline jbyte readByte(void** p) { + jbyte v = *(jbyte*) *p; + *p += sizeof(jbyte); + return v; +} + +static inline jchar readChar(void** p) { + *p = ALIGN(*p, jchar); + jchar v = *(jchar*) *p; + *p += sizeof(jchar); + return v; +} + +static inline jshort readShort(void** p) { + *p = ALIGN(*p, jshort); + jshort v = *(jshort*) *p; + *p += sizeof(jshort); + return v; +} + +static inline jint readInt(void** p) { + *p = ALIGN(*p, jint); + jint v = *(jint*) *p; + *p += sizeof(jint); + return v; +} + +static inline char* readString(void** p) { + *p = ALIGN(*p, char*); + char* v = *(char**) *p; + *p += sizeof(char*); + return v; +} + +static inline void* readPtr(void** p) { + *p = ALIGN(*p, void*); + void* v = *(void**) *p; + *p += sizeof(void*); + return v; +} + +static inline void writeInt(void** p, jint v) { + *p = ALIGN(*p, jint); + *(jint*) *p = v; + *p += sizeof(jint); +} + +#endif + diff --git a/compiler/vm/bc/src/classinfo.c b/compiler/vm/bc/src/classinfo.c index 410762565..5dc1bdda1 100755 --- a/compiler/vm/bc/src/classinfo.c +++ b/compiler/vm/bc/src/classinfo.c @@ -14,7 +14,7 @@ * limitations under the License. */ #include -#include "packed.h" +#include "aligned.h" #include "classinfo.h" #define FI_ACCESS_MASK 0x3 diff --git a/compiler/vm/core/src/attribute.c b/compiler/vm/core/src/attribute.c index 16f8ec02a..df33fefc0 100755 --- a/compiler/vm/core/src/attribute.c +++ b/compiler/vm/core/src/attribute.c @@ -25,15 +25,6 @@ #define RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS 7 #define ANNOTATION_DEFAULT 8 -typedef union { - jshort s; - jint i; - jlong j; - jfloat f; - jdouble d; - void* p; -} unaligned __attribute__ ((aligned (1))); - static Class* java_lang_TypeNotPresentException = NULL; static Class* java_lang_annotation_AnnotationFormatError = NULL; static Class* java_lang_annotation_Annotation = NULL; @@ -61,6 +52,8 @@ static jboolean throwFormatError(Env* env, char* expectedType) { return FALSE; } +#define ALIGN(pp, t) (void*)(((uintptr_t) (pp) + sizeof(t) - 1) & ~(sizeof(t) - 1)) + static inline jbyte getByte(void** attributes) { jbyte v = *(jbyte*) *attributes; *attributes += sizeof(jbyte); @@ -68,41 +61,54 @@ static inline jbyte getByte(void** attributes) { } static inline jchar getChar(void** attributes) { + *attributes = ALIGN(*attributes, jchar); jchar v = *(jchar*) *attributes; *attributes += sizeof(jchar); return v; } static inline jint getInt(void** attributes) { - jint v = ((unaligned*) *attributes)->i; + *attributes = ALIGN(*attributes, jint); + jint v = *(jint*) *attributes; *attributes += sizeof(jint); return v; } static inline jlong getLong(void** attributes) { - jlong v = ((unaligned*) *attributes)->j; + *attributes = ALIGN(*attributes, jlong); + jlong v = *(jlong*) *attributes; *attributes += sizeof(jlong); return v; } static inline jfloat getFloat(void** attributes) { - jfloat v = ((unaligned*) *attributes)->f; + *attributes = ALIGN(*attributes, jfloat); + jfloat v = *(jfloat*) *attributes; *attributes += sizeof(jfloat); return v; } static inline jdouble getDouble(void** attributes) { - jdouble v = ((unaligned*) *attributes)->d; + *attributes = ALIGN(*attributes, jdouble); + jdouble v = *(jdouble*) *attributes; *attributes += sizeof(jdouble); return v; } static inline char* getString(void** attributes) { - char* v = (char*) ((unaligned*) *attributes)->p; + *attributes = ALIGN(*attributes, char*); + char* v = *(char**) *attributes; *attributes += sizeof(char*); return v; } +static inline char* getPtr(void** attributes) { + *attributes = ALIGN(*attributes, void*); + void* v = *(void**) *attributes; + *attributes += sizeof(void*); + return v; +} + static void skipElementValue(void** attributes); static void skipAnnotationElementValue(void** attributes) { @@ -178,17 +184,27 @@ static void iterateAttributes(Env* env, void* attributes, jboolean (*f)(Env*, jb switch (type) { case SOURCE_FILE: case SIGNATURE: - attributes += sizeof(char*); + // attributes += sizeof(char*); + getPtr(&attributes); break; case INNER_CLASS: - attributes += 3 * sizeof(char*) + sizeof(jint); + // attributes += 3 * sizeof(char*) + sizeof(jint); + getPtr(&attributes); + getPtr(&attributes); + getPtr(&attributes); + getInt(&attributes); break; case ENCLOSING_METHOD: - attributes += 3 * sizeof(char*); + //attributes += 3 * sizeof(char*); + getPtr(&attributes); + getPtr(&attributes); + getPtr(&attributes); break; case EXCEPTIONS: length = getInt(&attributes); - attributes += length * sizeof(char*); + //attributes += length * sizeof(char*); + while (length--) + getPtr(&attributes); break; case ANNOTATION_DEFAULT: skipElementValue(&attributes); diff --git a/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/ClassInfoImpl.java b/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/ClassInfoImpl.java index 33f511ba6..7e510e070 100644 --- a/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/ClassInfoImpl.java +++ b/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/ClassInfoImpl.java @@ -119,10 +119,10 @@ void readClassInfoHeader(DataBufferReader reader) { // save position to continue once loadData is called endOfHeaderPos = reader.position(); - // read little bit more to get super class name + // read a bit more to get super class name if (!isInterface()) { reader.skip(2 + 2 + 2); // interfaceCount + fieldCount + methodCount - long superNamePtr = reader.readPointer(); + long superNamePtr = reader.readPointer(true); if (superNamePtr != 0) { superclassName = reader.readStringZ(superNamePtr); superclassSignature = "L" + superclassName + ";"; @@ -151,18 +151,18 @@ void loadData(ClassInfoLoader loader) { if (!isInterface()) { // skip super name as already has been read - reader.skip(reader.pointerSize()); + reader.readPointer(true); } if ((flags & ClassDataConsts.classinfo.ATTRIBUTES) != 0) { // TODO: skip attributes for now - reader.skip(reader.pointerSize()); + reader.readPointer(true); } // reading interfaces interfaces = new ClassInfo[interfaceCount]; for (int idx = 0; idx < interfaceCount; idx++) { - long ptr = reader.readPointer(); + long ptr = reader.readPointer(true); String interfaceSignature = "L" + reader.readStringZ(ptr) + ";"; interfaces[idx] = loader.classInfoBySignature(interfaceSignature); if (interfaces[idx] == null) diff --git a/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/ClassInfoLoader.java b/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/ClassInfoLoader.java index 1f4501416..47cb6a559 100644 --- a/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/ClassInfoLoader.java +++ b/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/ClassInfoLoader.java @@ -75,7 +75,7 @@ public ClassInfoLoader(RefIdHolder classRefIdHolder, RefIdHolder(this.signatureToDataInfo.values())); } - private void parseHash( long hash) { + private void parseHash(long hash) { reader.setPosition(hash); long pointerSize = reader.pointerSize(); int classInfoCount = reader.readInt32(); diff --git a/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/FieldInfo.java b/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/FieldInfo.java index 4fb77eb8a..35e00e6e5 100644 --- a/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/FieldInfo.java +++ b/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/FieldInfo.java @@ -49,7 +49,7 @@ public FieldInfo(ClassInfoImpl classInfo) { public void readFieldInfo(DataBufferReader reader) { flags = reader.readInt16(); - name = reader.readStringZ(reader.readPointer()); + name = reader.readStringZ(reader.readPointer(true)); if ((flags >> 12) != 0) { switch ((flags >> 12) & 0xf) { @@ -63,14 +63,14 @@ public void readFieldInfo(DataBufferReader reader) { case ClassDataConsts.desc.Z: signature = "Z"; break; } } else { - signature = reader.readStringZ(reader.readPointer()); + signature = reader.readStringZ(reader.readPointer(true)); } - offset = reader.readInt32(); + offset = reader.readInt32(true); if ((flags & ClassDataConsts.fieldinfo.ATTRIBUTES) != 0) { // TODO: skip attributes for now - reader.skip(reader.pointerSize()); + reader.readPointer(true); } } diff --git a/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/MethodInfo.java b/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/MethodInfo.java index c01e54e04..504a44315 100644 --- a/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/MethodInfo.java +++ b/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/MethodInfo.java @@ -57,7 +57,7 @@ public void readMethodInfo(DataBufferReader reader) { flags = reader.readInt16(); int vtableIndex = reader.readInt16(); - name = reader.readStringZ(reader.readPointer()); + name = reader.readStringZ(reader.readPointer(true)); if ((flags & ClassDataConsts.methodinfo.COMPACT_DESC) != 0) { switch (reader.readByte()) { @@ -90,31 +90,31 @@ public void readMethodInfo(DataBufferReader reader) { break; } } else { - desc = reader.readStringZ(reader.readPointer()); + desc = reader.readStringZ(reader.readPointer(true)); } if ((flags & ClassDataConsts.methodinfo.ATTRIBUTES) != 0) { // TODO: skip attributes - reader.skip(reader.pointerSize()); + reader.readPointer(true); } long synchronizedImpl = 0; long linetable = 0; if (!isAbstract()) { - implPtr = reader.readPointer(); - methodCodeSize = reader.readInt32(); + implPtr = reader.readPointer(true); + methodCodeSize = reader.readInt32(true); if (isSynchronized()) - synchronizedImpl = reader.readPointer(); + synchronizedImpl = reader.readPointer(true); if (!isNative()) { - linetable = reader.readPointer(); + linetable = reader.readPointer(true); } } long targetFnPtr = 0; if (isBroBridge()) - targetFnPtr = reader.readPointer(); + targetFnPtr = reader.readPointer(true); long callbackImpl = 0; if (isBroCallback()) - callbackImpl = reader.readPointer(); + callbackImpl = reader.readPointer(true); } public String name() { diff --git a/plugins/debugger/src/main/java/org/robovm/debugger/utils/bytebuffer/DataBufferReader.java b/plugins/debugger/src/main/java/org/robovm/debugger/utils/bytebuffer/DataBufferReader.java index 838a70d9a..75dc229e7 100644 --- a/plugins/debugger/src/main/java/org/robovm/debugger/utils/bytebuffer/DataBufferReader.java +++ b/plugins/debugger/src/main/java/org/robovm/debugger/utils/bytebuffer/DataBufferReader.java @@ -66,6 +66,16 @@ default char readChar16() { int readInt32(); + default int readInt32(boolean aligned) { + if (aligned) { + long savedPosition = position(); + long alignedPosition = DataUtils.align(savedPosition, 4); + if (savedPosition != alignedPosition) + setPosition(alignedPosition); + } + return readInt32(); + } + default long readUnsignedInt32() { return Integer.toUnsignedLong(readInt32()); } From ea2305af9c9867db162bdea4d59339fc3b864c89 Mon Sep 17 00:00:00 2001 From: dkimitsa Date: Fri, 8 Apr 2022 11:47:31 +0300 Subject: [PATCH 2/3] * removed linker flags: - `-w` that was suppressing all warnings - `-no_pie` -- as it is not supported for arm targets (and debugger can handle it) - `-sdk_version` as linker picks one from `platform_version` --- .../org/robovm/compiler/target/ios/IOSTarget.java | 11 +---------- .../java/org/robovm/compiler/util/ToolchainUtil.java | 5 ----- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/target/ios/IOSTarget.java b/compiler/compiler/src/main/java/org/robovm/compiler/target/ios/IOSTarget.java index 813f6fe40..2ef94849c 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/target/ios/IOSTarget.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/target/ios/IOSTarget.java @@ -288,27 +288,18 @@ protected void doBuild(File outFile, List ccArgs, ccArgs.add("--target=" + config.getClangTriple(getMinimumOSVersion())); if (isDeviceArch(arch)) { - if (config.isDebug()) { - ccArgs.add("-Wl,-no_pie"); - } if (config.isEnableBitcode()) { // tells clang to keep bitcode while linking ccArgs.add("-fembed-bitcode"); } } else { - if (config.getArch().getCpuArch() == CpuArch.x86 || config.isDebug()) { + if (config.getArch().getCpuArch() == CpuArch.x86) { ccArgs.add("-Wl,-no_pie"); } } ccArgs.add("-isysroot"); ccArgs.add(sdk.getRoot().getAbsolutePath()); - // specify sdk version for linker - libArgs.add("-Xlinker"); - libArgs.add("-sdk_version"); - libArgs.add("-Xlinker"); - libArgs.add(sdk.getVersion()); - // add runtime path to swift libs first to support swift-5 libs location libArgs.add("-Xlinker"); libArgs.add("-rpath"); diff --git a/compiler/compiler/src/main/java/org/robovm/compiler/util/ToolchainUtil.java b/compiler/compiler/src/main/java/org/robovm/compiler/util/ToolchainUtil.java index f20327ecf..f4e44eab1 100755 --- a/compiler/compiler/src/main/java/org/robovm/compiler/util/ToolchainUtil.java +++ b/compiler/compiler/src/main/java/org/robovm/compiler/util/ToolchainUtil.java @@ -393,11 +393,6 @@ public static void link(Config config, List args, List objectFiles for (File objectsFile : objectsFiles) { opts.add("-Wl,-filelist," + objectsFile.getAbsolutePath()); } - /* - * See #123, ignore ld: warning: pointer not aligned at address [infostruct] message with Xcode 8.3 - * unless we find a better solution - */ - opts.add("-w"); } else { opts.add(config.getArch().is32Bit() ? "-m32" : "-m64"); for (File objectsFile : objectsFiles) { From d210580e164259b43c956fbd6585f767405fb7e2 Mon Sep 17 00:00:00 2001 From: dkimitsa Date: Tue, 19 Apr 2022 17:28:46 +0300 Subject: [PATCH 3/3] * Debugger: short field should also be read as aligned to boundary --- .../debugger/state/classdata/FieldInfo.java | 2 +- .../debugger/state/classdata/MethodInfo.java | 4 +-- .../utils/bytebuffer/DataBufferReader.java | 32 ++++++++++--------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/FieldInfo.java b/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/FieldInfo.java index 35e00e6e5..85528c352 100644 --- a/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/FieldInfo.java +++ b/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/FieldInfo.java @@ -47,7 +47,7 @@ public FieldInfo(ClassInfoImpl classInfo) { } public void readFieldInfo(DataBufferReader reader) { - flags = reader.readInt16(); + flags = reader.readInt16(true); name = reader.readStringZ(reader.readPointer(true)); diff --git a/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/MethodInfo.java b/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/MethodInfo.java index 504a44315..30dcf8784 100644 --- a/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/MethodInfo.java +++ b/plugins/debugger/src/main/java/org/robovm/debugger/state/classdata/MethodInfo.java @@ -54,9 +54,9 @@ public class MethodInfo extends BaseModifiersInfo { private CallSpec callspec; public void readMethodInfo(DataBufferReader reader) { - flags = reader.readInt16(); + flags = reader.readInt16(true); - int vtableIndex = reader.readInt16(); + int vtableIndex = reader.readInt16(true); name = reader.readStringZ(reader.readPointer(true)); if ((flags & ClassDataConsts.methodinfo.COMPACT_DESC) != 0) { diff --git a/plugins/debugger/src/main/java/org/robovm/debugger/utils/bytebuffer/DataBufferReader.java b/plugins/debugger/src/main/java/org/robovm/debugger/utils/bytebuffer/DataBufferReader.java index 75dc229e7..679063bf9 100644 --- a/plugins/debugger/src/main/java/org/robovm/debugger/utils/bytebuffer/DataBufferReader.java +++ b/plugins/debugger/src/main/java/org/robovm/debugger/utils/bytebuffer/DataBufferReader.java @@ -48,6 +48,13 @@ default void expects(int bytes) { // redeclare for proper return type DataBufferReader setPosition(long position); + default void alignPosition(int boundary) { + long savedPosition = position(); + long alignedPosition = DataUtils.align(savedPosition, boundary); + if (savedPosition != alignedPosition) + setPosition(alignedPosition); + } + byte readByte(); default boolean readBoolean() { @@ -56,6 +63,11 @@ default boolean readBoolean() { short readInt16(); + default int readInt16(boolean aligned) { + if (aligned) alignPosition(2); + return readInt16(); + } + default int readUnsignedInt16() { return Short.toUnsignedInt(readInt16()); } @@ -67,12 +79,7 @@ default char readChar16() { int readInt32(); default int readInt32(boolean aligned) { - if (aligned) { - long savedPosition = position(); - long alignedPosition = DataUtils.align(savedPosition, 4); - if (savedPosition != alignedPosition) - setPosition(alignedPosition); - } + if (aligned) alignPosition(4); return readInt32(); } @@ -212,22 +219,17 @@ default String readStringWithLen() { * reads un-aligned pointer */ default long readPointer() { - return readPointer(false); + return is64bit() ? readLong() : readUnsignedInt32(); } /** * reads optionally aligned pointer to pointer size boundary ( * - * @param aligned true if pointer has to be alligned + * @param aligned true if pointer has to be aligned */ default long readPointer(boolean aligned) { - if (aligned) { - long savedPosition = position(); - long alignedPosition = DataUtils.align(savedPosition, pointerSize()); - if (savedPosition != alignedPosition) - setPosition(alignedPosition); - } - return is64bit() ? readLong() : readUnsignedInt32(); + if (aligned) alignPosition(pointerSize()); + return readPointer(); } /**