Sylvestre Ledru wrote:
FYI, as soon as Wheezy is released, I will upload version 3.2 or 3.3 of
clang and the llvm toolchain.
Now that the issue of finding a minimal fix for testing/unstable is out
of the way. I just took a look at the package in experimental. I noticed
the following.
You switched to bintutils-gold unconditionally. Since binutils-gold is
not available on all architectures this has made the package unbuildable
on a number of architectures where it was previously built successfully.
The armhf situation still needs attention. Specifically clang still
defaults to using a rediculously low CPU and once the correct CPU is
selected it still defaults to using all the vfp registers and neon.
The inappropriate use of altivec on powerpc that adam conrad pointed out
while I was working on the unstable package was still there.
Debdiff with fixes for the above issues is attached. Note that while I
have included a changelog entry I have no intention of NMUing this.
diff -Nru clang-3.2/debian/changelog clang-3.2/debian/changelog
--- clang-3.2/debian/changelog 2013-03-15 15:13:26.000000000 +0000
+++ clang-3.2/debian/changelog 2013-04-01 02:35:41.000000000 +0000
@@ -1,3 +1,13 @@
+clang (1:3.2-1~exp9) UNRELEASED; urgency=low
+
+ * Use binutils-gold only on architectures where it is actually available
+ * 33-armhf-defaults.diff Fix defaults to use correct CPU and FPU for
+ debian armhf (Closes: #704111)
+ * 34-powerpc-no-altivec.diff disable altivec by default on powerpc because
+ debian powerpc does not require altivec (patch cherry picked from ubuntu)
+
+ -- Peter Michael Green <plugw...@raspbian.org> Mon, 01 Apr 2013 01:37:38
+0000
+
clang (1:3.2-1~exp8) experimental; urgency=low
* Limit the dependency of clang-3.2 on compiler-rt to amd64 & i386
diff -Nru clang-3.2/debian/compiler-rt/usr/bin/asan_symbolize
clang-3.2/debian/compiler-rt/usr/bin/asan_symbolize
--- clang-3.2/debian/compiler-rt/usr/bin/asan_symbolize 1970-01-01
00:00:00.000000000 +0000
+++ clang-3.2/debian/compiler-rt/usr/bin/asan_symbolize 2013-04-01
07:14:17.000000000 +0000
@@ -0,0 +1,356 @@
+#!/usr/bin/env python
+#===- lib/asan/scripts/asan_symbolize.py
-----------------------------------===#
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+import bisect
+import os
+import re
+import subprocess
+import sys
+
+llvm_symbolizer = None
+symbolizers = {}
+filetypes = {}
+vmaddrs = {}
+DEBUG = False
+
+
+# FIXME: merge the code that calls fix_filename().
+def fix_filename(file_name):
+ for path_to_cut in sys.argv[1:]:
+ file_name = re.sub('.*' + path_to_cut, '', file_name)
+ file_name = re.sub('.*asan_[a-z_]*.cc:[0-9]*', '_asan_rtl_', file_name)
+ file_name = re.sub('.*crtstuff.c:0', '???:0', file_name)
+ return file_name
+
+
+class Symbolizer(object):
+ def __init__(self):
+ pass
+
+ def symbolize(self, addr, binary, offset):
+ """Symbolize the given address (pair of binary and offset).
+
+ Overriden in subclasses.
+ Args:
+ addr: virtual address of an instruction.
+ binary: path to executable/shared object containing this instruction.
+ offset: instruction offset in the @binary.
+ Returns:
+ list of strings (one string for each inlined frame) describing
+ the code locations for this instruction (that is, function name, file
+ name, line and column numbers).
+ """
+ return None
+
+
+class LLVMSymbolizer(Symbolizer):
+ def __init__(self, symbolizer_path):
+ super(LLVMSymbolizer, self).__init__()
+ self.symbolizer_path = symbolizer_path
+ self.pipe = self.open_llvm_symbolizer()
+
+ def open_llvm_symbolizer(self):
+ if not os.path.exists(self.symbolizer_path):
+ return None
+ cmd = [self.symbolizer_path,
+ '--use-symbol-table=true',
+ '--demangle=false',
+ '--functions=true',
+ '--inlining=true']
+ if DEBUG:
+ print ' '.join(cmd)
+ return subprocess.Popen(cmd, stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE)
+
+ def symbolize(self, addr, binary, offset):
+ """Overrides Symbolizer.symbolize."""
+ if not self.pipe:
+ return None
+ result = []
+ try:
+ symbolizer_input = '%s %s' % (binary, offset)
+ if DEBUG:
+ print symbolizer_input
+ print >> self.pipe.stdin, symbolizer_input
+ while True:
+ function_name = self.pipe.stdout.readline().rstrip()
+ if not function_name:
+ break
+ file_name = self.pipe.stdout.readline().rstrip()
+ file_name = fix_filename(file_name)
+ if (not function_name.startswith('??') and
+ not file_name.startswith('??')):
+ # Append only valid frames.
+ result.append('%s in %s %s' % (addr, function_name,
+ file_name))
+ except Exception:
+ result = []
+ if not result:
+ result = None
+ return result
+
+
+def LLVMSymbolizerFactory(system):
+ symbolizer_path = os.getenv('LLVM_SYMBOLIZER_PATH')
+ if not symbolizer_path:
+ # Assume llvm-symbolizer is in PATH.
+ symbolizer_path = 'llvm-symbolizer'
+ return LLVMSymbolizer(symbolizer_path)
+
+
+class Addr2LineSymbolizer(Symbolizer):
+ def __init__(self, binary):
+ super(Addr2LineSymbolizer, self).__init__()
+ self.binary = binary
+ self.pipe = self.open_addr2line()
+
+ def open_addr2line(self):
+ cmd = ['addr2line', '-f', '-e', self.binary]
+ if DEBUG:
+ print ' '.join(cmd)
+ return subprocess.Popen(cmd,
+ stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+
+ def symbolize(self, addr, binary, offset):
+ """Overrides Symbolizer.symbolize."""
+ if self.binary != binary:
+ return None
+ try:
+ print >> self.pipe.stdin, offset
+ function_name = self.pipe.stdout.readline().rstrip()
+ file_name = self.pipe.stdout.readline().rstrip()
+ except Exception:
+ function_name = ''
+ file_name = ''
+ file_name = fix_filename(file_name)
+ return ['%s in %s %s' % (addr, function_name, file_name)]
+
+
+class DarwinSymbolizer(Symbolizer):
+ def __init__(self, addr, binary):
+ super(DarwinSymbolizer, self).__init__()
+ self.binary = binary
+ # Guess which arch we're running. 10 = len('0x') + 8 hex digits.
+ if len(addr) > 10:
+ self.arch = 'x86_64'
+ else:
+ self.arch = 'i386'
+ self.vmaddr = None
+ self.pipe = None
+
+ def write_addr_to_pipe(self, offset):
+ print >> self.pipe.stdin, '0x%x' % int(offset, 16)
+
+ def open_atos(self):
+ if DEBUG:
+ print 'atos -o %s -arch %s' % (self.binary, self.arch)
+ cmdline = ['atos', '-o', self.binary, '-arch', self.arch]
+ self.pipe = subprocess.Popen(cmdline,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+
+ def symbolize(self, addr, binary, offset):
+ """Overrides Symbolizer.symbolize."""
+ if self.binary != binary:
+ return None
+ self.open_atos()
+ self.write_addr_to_pipe(offset)
+ self.pipe.stdin.close()
+ atos_line = self.pipe.stdout.readline().rstrip()
+ # A well-formed atos response looks like this:
+ # foo(type1, type2) (in object.name) (filename.cc:80)
+ match = re.match('^(.*) \(in (.*)\) \((.*:\d*)\)$', atos_line)
+ if DEBUG:
+ print 'atos_line: ', atos_line
+ if match:
+ function_name = match.group(1)
+ function_name = re.sub('\(.*?\)', '', function_name)
+ file_name = fix_filename(match.group(3))
+ return ['%s in %s %s' % (addr, function_name, file_name)]
+ else:
+ return ['%s in %s' % (addr, atos_line)]
+
+
+# Chain several symbolizers so that if one symbolizer fails, we fall back
+# to the next symbolizer in chain.
+class ChainSymbolizer(Symbolizer):
+ def __init__(self, symbolizer_list):
+ super(ChainSymbolizer, self).__init__()
+ self.symbolizer_list = symbolizer_list
+
+ def symbolize(self, addr, binary, offset):
+ """Overrides Symbolizer.symbolize."""
+ for symbolizer in self.symbolizer_list:
+ if symbolizer:
+ result = symbolizer.symbolize(addr, binary, offset)
+ if result:
+ return result
+ return None
+
+ def append_symbolizer(self, symbolizer):
+ self.symbolizer_list.append(symbolizer)
+
+
+def BreakpadSymbolizerFactory(binary):
+ suffix = os.getenv('BREAKPAD_SUFFIX')
+ if suffix:
+ filename = binary + suffix
+ if os.access(filename, os.F_OK):
+ return BreakpadSymbolizer(filename)
+ return None
+
+
+def SystemSymbolizerFactory(system, addr, binary):
+ if system == 'Darwin':
+ return DarwinSymbolizer(addr, binary)
+ elif system == 'Linux':
+ return Addr2LineSymbolizer(binary)
+
+
+class BreakpadSymbolizer(Symbolizer):
+ def __init__(self, filename):
+ super(BreakpadSymbolizer, self).__init__()
+ self.filename = filename
+ lines = file(filename).readlines()
+ self.files = []
+ self.symbols = {}
+ self.address_list = []
+ self.addresses = {}
+ # MODULE mac x86_64 A7001116478B33F18FF9BEDE9F615F190 t
+ fragments = lines[0].rstrip().split()
+ self.arch = fragments[2]
+ self.debug_id = fragments[3]
+ self.binary = ' '.join(fragments[4:])
+ self.parse_lines(lines[1:])
+
+ def parse_lines(self, lines):
+ cur_function_addr = ''
+ for line in lines:
+ fragments = line.split()
+ if fragments[0] == 'FILE':
+ assert int(fragments[1]) == len(self.files)
+ self.files.append(' '.join(fragments[2:]))
+ elif fragments[0] == 'PUBLIC':
+ self.symbols[int(fragments[1], 16)] = ' '.join(fragments[3:])
+ elif fragments[0] in ['CFI', 'STACK']:
+ pass
+ elif fragments[0] == 'FUNC':
+ cur_function_addr = int(fragments[1], 16)
+ if not cur_function_addr in self.symbols.keys():
+ self.symbols[cur_function_addr] = ' '.join(fragments[4:])
+ else:
+ # Line starting with an address.
+ addr = int(fragments[0], 16)
+ self.address_list.append(addr)
+ # Tuple of symbol address, size, line, file number.
+ self.addresses[addr] = (cur_function_addr,
+ int(fragments[1], 16),
+ int(fragments[2]),
+ int(fragments[3]))
+ self.address_list.sort()
+
+ def get_sym_file_line(self, addr):
+ key = None
+ if addr in self.addresses.keys():
+ key = addr
+ else:
+ index = bisect.bisect_left(self.address_list, addr)
+ if index == 0:
+ return None
+ else:
+ key = self.address_list[index - 1]
+ sym_id, size, line_no, file_no = self.addresses[key]
+ symbol = self.symbols[sym_id]
+ filename = self.files[file_no]
+ if addr < key + size:
+ return symbol, filename, line_no
+ else:
+ return None
+
+ def symbolize(self, addr, binary, offset):
+ if self.binary != binary:
+ return None
+ res = self.get_sym_file_line(int(offset, 16))
+ if res:
+ function_name, file_name, line_no = res
+ result = ['%s in %s %s:%d' % (
+ addr, function_name, file_name, line_no)]
+ print result
+ return result
+ else:
+ return None
+
+
+class SymbolizationLoop(object):
+ def __init__(self, binary_name_filter=None):
+ # Used by clients who may want to supply a different binary name.
+ # E.g. in Chrome several binaries may share a single .dSYM.
+ self.binary_name_filter = binary_name_filter
+ self.system = os.uname()[0]
+ if self.system in ['Linux', 'Darwin']:
+ self.llvm_symbolizer = LLVMSymbolizerFactory(self.system)
+ else:
+ raise Exception('Unknown system')
+
+ def symbolize_address(self, addr, binary, offset):
+ # Use the chain of symbolizers:
+ # Breakpad symbolizer -> LLVM symbolizer -> addr2line/atos
+ # (fall back to next symbolizer if the previous one fails).
+ if not binary in symbolizers:
+ symbolizers[binary] = ChainSymbolizer(
+ [BreakpadSymbolizerFactory(binary), self.llvm_symbolizer])
+ result = symbolizers[binary].symbolize(addr, binary, offset)
+ if result is None:
+ # Initialize system symbolizer only if other symbolizers failed.
+ symbolizers[binary].append_symbolizer(
+ SystemSymbolizerFactory(self.system, addr, binary))
+ result = symbolizers[binary].symbolize(addr, binary, offset)
+ # The system symbolizer must produce some result.
+ assert result
+ return result
+
+ def print_symbolized_lines(self, symbolized_lines):
+ if not symbolized_lines:
+ print self.current_line
+ else:
+ for symbolized_frame in symbolized_lines:
+ print ' #' + str(self.frame_no) + ' ' + symbolized_frame.rstrip()
+ self.frame_no += 1
+
+ def process_stdin(self):
+ self.frame_no = 0
+ for line in sys.stdin:
+ self.current_line = line.rstrip()
+ #0 0x7f6e35cf2e45 (/blah/foo.so+0x11fe45)
+ stack_trace_line_format = (
+ '^( *#([0-9]+) *)(0x[0-9a-f]+) *\((.*)\+(0x[0-9a-f]+)\)')
+ match = re.match(stack_trace_line_format, line)
+ if not match:
+ print self.current_line
+ continue
+ if DEBUG:
+ print line
+ _, frameno_str, addr, binary, offset = match.groups()
+ if frameno_str == '0':
+ # Assume that frame #0 is the first frame of new stack trace.
+ self.frame_no = 0
+ original_binary = binary
+ if self.binary_name_filter:
+ binary = self.binary_name_filter(binary)
+ symbolized_line = self.symbolize_address(addr, binary, offset)
+ if not symbolized_line:
+ if original_binary != binary:
+ symbolized_line = self.symbolize_address(addr, binary, offset)
+ self.print_symbolized_lines(symbolized_line)
+
+
+if __name__ == '__main__':
+ loop = SymbolizationLoop()
+ loop.process_stdin()
diff -Nru clang-3.2/debian/control clang-3.2/debian/control
--- clang-3.2/debian/control 2013-03-15 15:13:26.000000000 +0000
+++ clang-3.2/debian/control 2013-04-01 01:31:26.000000000 +0000
@@ -7,7 +7,8 @@
autoconf, automake1.9, perl, libtool, doxygen, chrpath, texinfo,
sharutils, autotools-dev (>= 20060702.1), libffi-dev (>= 3.0.9),
lsb-release, patchutils, diffstat, xz-utils, llvm-3.2-dev (>= 3.2),
- llvm-3.2-source (>= 3.2), chrpath, python, binutils-gold
+ llvm-3.2-source (>= 3.2), chrpath, python,
+ binutils-gold [amd64 armel armhf i386 powerpc powerpcspe ppc64 sparc
sparc64 x32]
Build-Conflicts: oprofile, ocaml
Standards-Version: 3.9.3
Homepage: http://clang.llvm.org/
diff -Nru clang-3.2/debian/patches/33-armhf-defaults.diff
clang-3.2/debian/patches/33-armhf-defaults.diff
--- clang-3.2/debian/patches/33-armhf-defaults.diff 1970-01-01
00:00:00.000000000 +0000
+++ clang-3.2/debian/patches/33-armhf-defaults.diff 2013-04-01
13:18:36.000000000 +0000
@@ -0,0 +1,53 @@
+Description: Fix defaults to use correct CPU and FPU on armhf
+ Clang was defaulting to a rediculously low CPU on armhf, furthermore when
+ The correct CPU is selected it defaults to incorrect FPU options for
+ debian. This patch sets the defaults to appropriate values.
+Author: Peter Michael Green <plugw...@raspbian.org>
+Bug-Debian: http://bugs.debian.org/704111
+
+---
+The information above should follow the Patch Tagging Guidelines, please
+checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
+are templates for supplementary fields that you might want to add:
+
+Origin: <vendor|upstream|other>, <url of original patch>
+Bug: <url in upstream bugtracker>
+Bug-Debian: http://bugs.debian.org/<bugnumber>
+Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
+Forwarded: <no|not-needed|url proving that it has been forwarded>
+Reviewed-By: <name and email of someone who approved the patch>
+Last-Update: <YYYY-MM-DD>
+
+--- clang-3.2.orig/tools/clang/lib/Driver/Tools.cpp
++++ clang-3.2/tools/clang/lib/Driver/Tools.cpp
+@@ -504,6 +504,9 @@ static std::string getARMTargetCPU(const
+ if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
+ // Otherwise, if we have -march= choose the base CPU for that arch.
+ MArch = A->getValue();
++ } else if (Triple.getEnvironment() == llvm::Triple::GNUEABIHF) {
++ // Use armv6 for armhf (raspbian version of patch)
++ MArch = "armv7-a";
+ } else {
+ // Otherwise, use the Arch from the triple.
+ MArch = Triple.getArchName();
+@@ -786,8 +789,19 @@ void Clang::AddARMTargetArgs(const ArgLi
+ }
+
+ // Honor -mfpu=.
+- if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ))
++ if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) {
+ addFPUArgs(D, A, Args, CmdArgs);
++ } else {
++ if (StringRef(CPUName).startswith("cortex-a")) {
++ //Debian armhf uses vfpv3-d16
++ CmdArgs.push_back("-target-feature");
++ CmdArgs.push_back("+vfp3");
++ CmdArgs.push_back("-target-feature");
++ CmdArgs.push_back("+d16");
++ CmdArgs.push_back("-target-feature");
++ CmdArgs.push_back("-neon");
++ }
++ }
+
+ // Honor -mfpmath=.
+ if (const Arg *A = Args.getLastArg(options::OPT_mfpmath_EQ))
diff -Nru clang-3.2/debian/patches/34-powerpc-no-altivec.diff
clang-3.2/debian/patches/34-powerpc-no-altivec.diff
--- clang-3.2/debian/patches/34-powerpc-no-altivec.diff 1970-01-01
00:00:00.000000000 +0000
+++ clang-3.2/debian/patches/34-powerpc-no-altivec.diff 2013-04-01
13:21:42.000000000 +0000
@@ -0,0 +1,24 @@
+Description: Make sure PowerPC doesn't default to altivec on
+Author: Adam Conrad <adcon...@ubuntu.com>
+Author: Peter Michael Green <plugw...@debian.org>
+Forwarded: no
+Reviewed-By: Colin Watson <cjwat...@ubuntu.com>
+
+Last-Update: 2013-04-01
+
+Index: clang-3.2.new/tools/clang/lib/Lex/Makefile
+===================================================================
+--- clang-3.2.new.orig/tools/clang/lib/Lex/Makefile 2013-04-01
02:32:35.000000000 +0000
++++ clang-3.2.new/tools/clang/lib/Lex/Makefile 2013-04-01 02:32:03.000000000
+0000
+@@ -16,11 +16,5 @@
+
+ LIBRARYNAME := clangLex
+
+-ifeq ($(ARCH),PowerPC)
+-ifneq ($(shell dpkg-architecture -qDEB_HOST_ARCH),powerpcspe)
+-CXX.Flags += -maltivec
+-endif
+-endif
+-
+ include $(CLANG_LEVEL)/Makefile
+
diff -Nru clang-3.2/debian/patches/series clang-3.2/debian/patches/series
--- clang-3.2/debian/patches/series 2013-03-15 15:59:31.000000000 +0000
+++ clang-3.2/debian/patches/series 2013-04-01 02:23:11.000000000 +0000
@@ -12,3 +12,5 @@
30-kfreebsd.diff
31-powerpcspe.diff
32-scan-build-path.diff
+33-armhf-defaults.diff
+34-powerpc-no-altivec.diff