Skip to content

Commit

Permalink
Patch wrong tls alignment for Android Q compatibility (fixes #370) (#374
Browse files Browse the repository at this point in the history
)

* Patch go wrong tls alignment for Android Q compatibility (fixes #370)

* Remove wrong x86 patch

* Incorporate @kvaster's Android Q patch into build script (fixes #370)

Thanks for the contributon!

* Update build script for Python 2 compatibility

* Second attempt for python 2
  • Loading branch information
Catfriend1 committed Mar 17, 2019
1 parent 2486612 commit 3a188d4
Showing 1 changed file with 62 additions and 1 deletion.
63 changes: 62 additions & 1 deletion syncthing/build-syncthing.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@
'goarch': 'arm',
'jni_dir': 'armeabi',
'cc': 'arm-linux-androideabi-clang',
'patch_underaligned_tls': 'yes',
},
{
'arch': 'arm64',
'goarch': 'arm64',
'jni_dir': 'arm64-v8a',
'cc': 'aarch64-linux-android-clang',
'patch_underaligned_tls': 'yes',
'min_sdk': 21,
},
{
Expand Down Expand Up @@ -247,6 +249,55 @@ def install_ndk():
os.environ["ANDROID_NDK_HOME"] = ndk_home_path


def artifact_patch_underaligned_tls(artifact_fullfn):
import struct

with open(artifact_fullfn, 'r+b') as f:
f.seek(0)
hdr = struct.unpack('16c', f.read(16))
if hdr[0] != b'\x7f' or hdr[1] != b'E' or hdr[2] != b'L' or hdr[3] != b'F':
print('artifact_patch_underaligned_tls: Not an ELF file')
return None

if hdr[4] == b'\x01':
# 32 bit code
f.seek(28)
offset = struct.unpack('<I', f.read(4))[0]
f.seek(42)
phsize = struct.unpack('<H', f.read(2))[0]
phnum = struct.unpack('<H', f.read(2))[0]
for i in range(0, phnum):
f.seek(offset + i * phsize)
t = struct.unpack('<I', f.read(4))[0]
if t == 7:
f.seek(28 - 4, 1)
align = struct.unpack('<I', f.read(4))[0]
if (align < 32):
print('artifact_patch_underaligned_tls: Patching underaligned TLS segment from ' + str(align) + ' to 32')
f.seek(-4, 1)
f.write(struct.pack('<I', 32))

elif hdr[4] == b'\x02':
# 64 bit code
f.seek(32)
offset = struct.unpack('<Q', f.read(8))[0]
f.seek(54)
phsize = struct.unpack('<H', f.read(2))[0]
phnum = struct.unpack('<H', f.read(2))[0]
for i in range(0, phnum):
f.seek(offset + i * phsize)
t = struct.unpack('<I', f.read(4))[0]
if t == 7:
f.seek(48 - 4, 1)
align = struct.unpack('<Q', f.read(8))[0]
if (align < 64):
print('artifact_patch_underaligned_tls: Patching underaligned TLS segment from ' + str(align) + ' to 64')
f.seek(-8, 1)
f.write(struct.pack('<H', 64))

else:
print('artifact_patch_underaligned_tls: Unknown ELF file class')


#
# BUILD SCRIPT MAIN.
Expand Down Expand Up @@ -313,6 +364,7 @@ def install_ndk():
'--always'
]).strip();
syncthingVersion = syncthingVersion.decode().replace("rc", "preview");
print('Building syncthing version', syncthingVersion);

for target in BUILD_TARGETS:
target_min_sdk = str(target.get('min_sdk', min_sdk))
Expand Down Expand Up @@ -349,14 +401,23 @@ def install_ndk():
'CGO_ENABLED': '1',
})

print('Building syncthing version', syncthingVersion);
subprocess.check_call([go_bin, 'mod', 'download'], cwd=syncthing_dir)
subprocess.check_call([
go_bin, 'run', 'build.go', '-goos', 'android', '-goarch', target['goarch'],
'-cc', os.path.join(standalone_ndk_dir, 'bin', target['cc']),
'-version', syncthingVersion
] + pkg_argument + ['-no-upgrade', 'build'], env=environ, cwd=syncthing_dir)

# Determine path of source artifact
source_artifact = os.path.join(syncthing_dir, 'syncthing')

# Patch artifact to work around golang bug.
# See issues:
# - https://github.com/Catfriend1/syncthing-android/issues/370
# - https://github.com/golang/go/issues/29674
if 'patch_underaligned_tls' in target:
artifact_patch_underaligned_tls(source_artifact)

# Copy compiled binary to jniLibs folder
target_dir = os.path.join(project_dir, 'app', 'src', 'main', 'jniLibs', target['jni_dir'])
if not os.path.isdir(target_dir):
Expand Down

0 comments on commit 3a188d4

Please sign in to comment.