From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 7E3AC3858437 for ; Fri, 19 Aug 2022 14:20:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7E3AC3858437 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-470-QuZUcGrnOpeU_LRyQSrbUw-1; Fri, 19 Aug 2022 10:20:56 -0400 X-MC-Unique: QuZUcGrnOpeU_LRyQSrbUw-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.rdu2.redhat.com [10.11.54.3]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 495B8101A588 for ; Fri, 19 Aug 2022 14:20:56 +0000 (UTC) Received: from comet.redhat.com (unknown [10.39.193.182]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E074A1121315 for ; Fri, 19 Aug 2022 14:20:55 +0000 (UTC) From: Nick Clifton To: binutils@sourceware.org Subject: RFC: readelf: Explain why LLVM bitcode files cannot be read Date: Fri, 19 Aug 2022 15:20:54 +0100 Message-ID: <87a680iabd.fsf@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.78 on 10.11.54.3 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain X-Spam-Status: No, score=-9.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 19 Aug 2022 14:20:59 -0000 Hi Guys, When the LLVM compiler produces a bitcode object file it uses its own format, rather than ELF. But since the file looks like a normal object file a user might try to run readelf on it: % echo "void lto_function(){}" > foo.c % clang -flto -O2 -c foo.c % readelf -a foo.o readelf: Error: Not an ELF file - it has the wrong magic bytes at the start I am proposing the patch below so that readelf will produce a more helpful error message: % readelf -a foo.o readelf: Error: This is a LLVM bitcode file - try using llvm-bcanalyzer One thing I am not sure about in the patch is the LLVM bitcode magic number. I do not know if this is defined in a header file somewhere, nor if there might be more than one possible value for the magic. I did not want to add any new dependencies to readelf however, so for now the patch just defines the number locally. Any comments/thoughts ? Cheers Nick diff --git a/binutils/readelf.c b/binutils/readelf.c index 1ec25239938..28e80e228cc 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -5700,8 +5700,30 @@ process_file_header (Filedata * filedata) || header->e_ident[EI_MAG2] != ELFMAG2 || header->e_ident[EI_MAG3] != ELFMAG3) { - error - (_("Not an ELF file - it has the wrong magic bytes at the start\n")); +#define LLVM_BC_MAG0 'B' +#define LLVM_BC_MAG1 'C' +#define LLVM_BC_MAG2 0xc0 +#define LLVM_BC_MAG3 0xde + /* LLVM bitcode files look like ordinary object files, but they are not + in the ELF file format. Let users know if this is the case. + Note: if we had plugin support we could use the LLVMgold.so plugin + to translate the file for us. */ + if (header->e_ident[EI_MAG0] == LLVM_BC_MAG0 + && header->e_ident[EI_MAG1] == LLVM_BC_MAG1 + && header->e_ident[EI_MAG2] == LLVM_BC_MAG2 + && header->e_ident[EI_MAG3] == LLVM_BC_MAG3) + { + /* llvm-bcanalyzer does not handle archives... */ + if (filedata->archive_file_size > 0) + error + (_("This is a LLVM bitcode file - try extracing and then using llvm-bcanalyzer\n")); + else + error + (_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n")); + } + else + error + (_("Not an ELF file - it has the wrong magic bytes at the start\n")); return false; }