PJK / libcbor

CBOR protocol implementation for C
MIT License
334 stars 95 forks source link

AArch32 compatiblity issues #184

Open pietrotedeschi opened 3 years ago

pietrotedeschi commented 3 years ago

Describe the bug When I try to preallocate the map structure as cbor_item_t* root = cbor_new_definite_map(2); I receive the following error:

lto1: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-9/README.Bugs> for instructions.
lto-wrapper: fatal error: arm-linux-gnueabihf-gcc returned 1 exit status
compilation terminated.
/usr/lib/gcc-cross/arm-linux-gnueabihf/9/../../../../arm-linux-gnueabihf/bin/ld: error: lto-wrapper failed
collect2: error: ld returned 1 exit status

To Reproduce Compiler: arm-linux-gnueabihf-gcc Compile the library for ARM. cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.armhf .

After the compile an example such as create_items.c with arm-linux-gnueabihf-gcc.

Expected behavior No errors.

Environment libcbor 0.8.0

The content of toolchain.armhf is the following:

SET (CMAKE_SYSTEM_NAME Linux)
SET (CMAKE_SYSTEM_PROCESSOR armhf)

SET (CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)

SET (CMAKE_FIND_ROOT_PATH /usr/arm-linux-gnueabihf)
SET (ONLY_CMAKE_FIND_ROOT_PATH TRUE)
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

IF (CMAKE_CROSSCOMPILING)
  MESSAGE("CROSS COMPILING for ")
  INCLUDE_DIRECTORIES(BEFORE /include)
ENDIF (CMAKE_CROSSCOMPILING)
PJK commented 3 years ago

Do I understand it correctly that the compiler is crashing?

pietrotedeschi commented 3 years ago

Do I understand it correctly that the compiler is crashing?

Yes. It doesn't happen when I just print the CBOR_VERSION (it means that the library is compiled). The platform is a Cortex A9.

---UPDATE--- If I try to recompile again with the same syntax posted in the previous post I receive also a warning like this: Your size_t is less than 8 bytes. Long items with 64b length specifiers might not work as expected. Make sure to run the tests!

pietrotedeschi commented 3 years ago

Now, I have the following problem that probably is due the size_t. Indeed, when I try do a simple operation like this:

    /* Preallocate the map structure */
    cbor_item_t* root = cbor_new_definite_map(2);
    // /* Add the content */
    cbor_map_add(root, (struct cbor_pair) {
        .key = cbor_move(cbor_build_string("1")),
        .value = cbor_move(cbor_build_string("1"))
    });
    cbor_map_add(root, (struct cbor_pair) {
        .key = cbor_move(cbor_build_string("1")),
        .value = cbor_move(cbor_build_string("1"))
    });

I receive in output a malformed string: �a1a1a1a1

---SOLUTION FOR THE FIRST ISSUE--- I solved by using the following toolchain:

# **********************************************************
# Copyright (c) 2014-2017 Google, Inc.    All rights reserved.
# **********************************************************
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
#   this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
#   this list of conditions and the following disclaimer in the documentation
#   and/or other materials provided with the distribution.
#
# * Neither the name of Google, Inc. nor the names of its contributors may be
#   used to endorse or promote products derived from this software without
#   specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE, INC. OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
# For cross compiling on 32-bit arm Linux using gcc-arm-linux-gnueabihf package:
# - install arm-linux-gnueabi-gcc package:
#   $ sudo apt-get install gcc-arm-linux-gnueabihf binutils-arm-linux-gnueabihf g++-arm-linux-gnueabihf
# - cross-compiling config
#   $ cmake -DCMAKE_TOOLCHAIN_FILE=../dynamorio/make/toolchain-arm32.cmake ../dynamorio
# You may have to set CMAKE_FIND_ROOT_PATH to point to the target enviroment, e.g.
# by passing -DCMAKE_FIND_ROOT_PATH=/usr/arm-linux-gnueabihf on Debian-like systems.
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
# If using a different target, set -DTARGET_ABI=<abi> on the command line.
# Some of our pre-built libraries (such as libelftc) assume gnueabihf.
# To support both arm-linux-gnueabi and arm-linux-gnueabi, we rely on
# CMAKE_C_LIBRARY_ARCHITECTURE for libelftc libraries selection.
# If CMAKE_C_LIBRARY_ARCHITECTURE is not set, users need manually set it
# to gnueabi for using gnueabi build of libelftc libraries.
if (NOT DEFINED TARGET_ABI)
  set(TARGET_ABI "linux-gnueabihf")
endif ()
# specify the cross compiler
SET(CMAKE_C_COMPILER   arm-${TARGET_ABI}-gcc)
SET(CMAKE_CXX_COMPILER arm-${TARGET_ABI}-g++)
# To build the tests, we need to set where the target environment containing
# the required library is. On Debian-like systems, this is
# /usr/arm-linux-gnueabihf/.
SET(CMAKE_FIND_ROOT_PATH "/usr/arm-${TARGET_ABI}")
# search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# Set additional variables.
# If we don't set some of these, CMake will end up using the host version.
# We want the full path, however, so we can pass EXISTS and other checks in
# the our CMake code.
find_program(GCC_FULL_PATH arm-${TARGET_ABI}-gcc)
if (NOT GCC_FULL_PATH)
  message(FATAL_ERROR "Cross-compiler arm-${TARGET_ABI}-gcc not found")
endif ()
get_filename_component(GCC_DIR ${GCC_FULL_PATH} PATH)
SET(CMAKE_LINKER        ${GCC_DIR}/arm-${TARGET_ABI}-ld       CACHE FILEPATH "linker")
SET(CMAKE_ASM_COMPILER  ${GCC_DIR}/arm-${TARGET_ABI}-as       CACHE FILEPATH "assembler")
SET(CMAKE_OBJCOPY       ${GCC_DIR}/arm-${TARGET_ABI}-objcopy  CACHE FILEPATH "objcopy")
SET(CMAKE_STRIP         ${GCC_DIR}/arm-${TARGET_ABI}-strip    CACHE FILEPATH "strip")
SET(CMAKE_CPP           ${GCC_DIR}/arm-${TARGET_ABI}-cpp      CACHE FILEPATH "cpp")
PJK commented 3 years ago

Do I understand it correctly that the compiler is crashing?

Yes. It doesn't happen when I just print the CBOR_VERSION (it means that the library is compiled). The platform is a Cortex A9.

---UPDATE--- If I try to recompile again with the same syntax posted in the previous post I receive also a warning like this: Your size_t is less than 8 bytes. Long items with 64b length specifiers might not work as expected. Make sure to run the tests!

Thanks for the update, I guess this is kind of working as intended, but in retrospect it seems pretty dumb that we are tied to 8B size_t... Let me see if we can just swap it for int64_t.

PJK commented 3 years ago

Ok, now I remember, size_t is sometimes used to represent the number of items (say in an array), not just bytes, under the assumption that since every item is at least 1B, size_t is guaranteed to fit the size of anything we can have in memory. This is not ideal because this could still work correctly in e.g. streaming mode decoding.

But anyway, I think that is not the issue you are running into with your example.

I receive in output a malformed string: �a1a1a1a1

Why is that string malformed? It should be 0xa1 0x61 0x31 0x61 0x31 0x61 0x31 0x61 0x31, which (modulo mangling of the first codepoint) seems to check out.