[Analyzer] Transform a region 't[i]' to its svalue form '&t + (i * element_size)'
Hi all, hi David, I am trying to use the analyzer API to transform an element_region (such as 't[1]') to a binop_svalue with an inner region_svalue (such as '&t + 4' in case of integers array) for analysis purpose. I managed to do it the other way around (i.e. from a binop_svalue to an element_region) using the analyzer API (code is in attached file offset_to_elm.cc). And everything is working as intended within the analyzer and my analysis. The problem I'm having here is probably due to a mistake I'm doing on some argument to a function call, but I cannot see it to be honest (code misbehaving is in elm_to_offset.cc). I attached a commented sample code I'd like to be able to analyze (test.c), alongside the commented GIMPLE code seen by the analyzer (test.c.075i.analyzer obtained through '-fdump-ipa-analyzer'). Feel free to ask question if needed of course. I manage to rebuild a binop_sval from an element_region (code is in attached file elm_to_offset.cc), but resulting object is not the same than the one already within the state_map of my state machine. To be clear, the svalue's pointer resulting from the code in elm_to_offset.cc is deifferent, though when they're logged with simple set to false, no difference seem to exist. And I really do have the intuition that the problem might be related to the call to region_model_manager::get_ptr_svalue on elm_to_offset.cc:17. I do think that the key is not find within region_model_manager::m_pointer_values_map is not found and the call to region_svalue constructor is performed within region_model_manager::get_ptr_svalue implementation. But still, I have no idea why. I did modified the analyzer state_map class to be able to also track regions states alongside svalues one (working on a patch, code is not respecting GCC's coding standard so far and most probably not optimized). Any idea on what I'm doing wrong here would really be appreciated. Beside this, I do think that enhancing the analyzer by allowing to track regions states could allow for a broader set of possible analysis. What do you think ? Thank you, Pierrick P.S.: @David, sorry for double send. I did a mistake in the gcc's mailing list address.const svalue *elm_to_offset(sm_context *sm_ctx, const region *reg, logger *logger) { const svalue* res = nullptr; if (logger) LOG_SCOPE(logger); auto model = sm_ctx->get_new_program_state()->m_region_model; auto mgr = model->get_manager(); bit_offset_t offset; const svalue *offset_sval = nullptr; if (reg->get_relative_concrete_offset(&offset)) { auto offset_byte = offset / BITS_PER_UNIT; offset_sval = mgr->get_or_create_constant_svalue(wide_int_to_tree(sizetype, offset_byte)); auto base = reg->get_base_region(); auto base_sval = mgr->get_ptr_svalue(TYPE_POINTER_TO(base->get_type()), base); res = mgr->get_or_create_binop(base->get_type(), POINTER_PLUS_EXPR, base_sval, offset_sval); } // TODO: symbolic offset else if (logger) logger->log("Offset is symbolic, not implemented."); if (logger) { logger->start_log_line(); logger->log_partial("res: %p | ", res); res ? res->dump_to_pp(logger->get_printer(), false) : logger->log_partial("nullptr"); logger->log_partial(" | "); res ? res->dump_to_pp(logger->get_printer(), true) : logger->log_partial("nullptr"); logger->end_log_line(); } return res; } const region *offset_to_elm(sm_context * sm_ctx, const svalue *sval, logger *logger) { const region * res = nullptr; if (logger) LOG_SCOPE(logger); auto model = sm_ctx->get_new_program_state()->m_region_model; if (const region *deref = model->deref_rvalue(sval, NULL_TREE, nullptr)) { if (logger) { logger->start_log_line(); logger->log_partial("deref: "); deref->dump_to_pp(logger->get_printer(), false); logger->end_log_line(); } auto base = deref->get_base_region(); bit_offset_t offset; bit_size_t size; if (deref->get_relative_concrete_offset(&offset) && deref->get_bit_size(&size)) { auto index = offset / size; auto model_mgr = model->get_manager(); auto index_sized = wide_int_to_tree(sizetype, index); auto sval_index_sized = model_mgr->get_or_create_constant_svalue(index_sized); res = model_mgr->get_element_region(base, TREE_TYPE(base->get_type()), sval_index_sized); } // TODO: symbolic offset else if (logger) logger->log("Offset is symbolic, not implemented."); } if (logger) { logger->start_log_line(); logger->log_partial("input: %p | ", sval); sval->dump_to_pp(logger->get_printer(), true); logger->log_partial(" | "); sval->dump_to_pp(logger->get_printer(), false); logger->end_log_line(); logger->start_log_line(); logger->log_partial("res: "); res ? res->dump_to_pp(logger->get_printer(), true) : logger->log_partial("nullptr"); logger->end_log_line(); } return res; } void some_func(void)
[ARM] unexpected sizeof() of a complex packed type
(The following sample is taken from my LKML post at https://lkml.org/lkml/2023/11/15/213) $ cat t-build-bug.c struct vring_tx_mac { unsigned int d[3]; unsigned int ucode_cmd; } __attribute__((packed)); struct vring_rx_mac { unsigned int d0; unsigned int d1; unsigned short w4; union { struct { unsigned short pn_15_0; unsigned int pn_47_16; } __attribute__((packed)); struct { unsigned short pn_15_0; unsigned int pn_47_16; } __attribute__((packed)) pn; }; } __attribute__((packed)); struct wil_ring_dma_addr { unsigned int addr_low; unsigned short addr_high; } __attribute__((packed)); struct vring_tx_dma { unsigned int d0; struct wil_ring_dma_addr addr; unsigned char ip_length; unsigned char b11; unsigned char error; unsigned char status; unsigned short length; } __attribute__((packed)); struct vring_tx_desc { struct vring_tx_mac mac; struct vring_tx_dma dma; } __attribute__((packed)); struct wil_ring_tx_enhanced_mac { unsigned int d[3]; unsigned short tso_mss; unsigned short scratchpad; } __attribute__((packed)); struct wil_ring_tx_enhanced_dma { unsigned char l4_hdr_len; unsigned char cmd; unsigned short w1; struct wil_ring_dma_addr addr; unsigned char ip_length; unsigned char b11; unsigned short addr_high_high; unsigned short length; } __attribute__((packed)); struct wil_tx_enhanced_desc { struct wil_ring_tx_enhanced_mac mac; struct wil_ring_tx_enhanced_dma dma; } __attribute__((packed)); union wil_tx_desc { struct vring_tx_desc legacy; struct wil_tx_enhanced_desc enhanced; } __attribute__((packed)); struct vring_rx_dma { unsigned int d0; struct wil_ring_dma_addr addr; unsigned char ip_length; unsigned char b11; unsigned char error; unsigned char status; unsigned short length; } __attribute__((packed)); struct vring_rx_desc { struct vring_rx_mac mac; struct vring_rx_dma dma; } __attribute__((packed)); struct wil_ring_rx_enhanced_mac { unsigned int d[3]; unsigned short buff_id; unsigned short reserved; } __attribute((packed)); struct wil_ring_rx_enhanced_dma { unsigned int d0; struct wil_ring_dma_addr addr; unsigned short w5; unsigned short addr_high_high; unsigned short length; } __attribute((packed)); struct wil_rx_enhanced_desc { struct wil_ring_rx_enhanced_mac mac; struct wil_ring_rx_enhanced_dma dma; } __attribute((packed)); union wil_rx_desc { struct vring_rx_desc legacy; struct wil_rx_enhanced_desc enhanced; } __attribute__((packed)); union wil_ring_desc { union wil_tx_desc tx; union wil_rx_desc rx; } __attribute__((packed)); int f (void) { return sizeof(union wil_ring_desc); } $ arm-linux-gnu-gcc -v Using built-in specs. COLLECT_GCC=arm-linux-gnu-gcc COLLECT_LTO_WRAPPER=/usr/libexec/gcc/arm-linux-gnueabi/13/lto-wrapper Target: arm-linux-gnueabi Configured with: ../gcc-13.2.1-20230728/configure --bindir=/usr/bin --build=x86_64-redhat-linux-gnu --datadir=/usr/share --disable-decimal-float --disable-dependency-tracking --disable-gold --disable-libgcj --disable-libgomp --disable-libmpx --disable-libquadmath --disable-libssp --disable-libunwind-exceptions --disable-shared --disable-silent-rules --disable-sjlj-exceptions --disable-threads --with-ld=/usr/bin/arm-linux-gnu-ld --enable-__cxa_atexit --enable-checking=release --enable-gnu-unique-object --enable-initfini-array --enable-languages=c,c++ --enable-linker-build-id --enable-lto --enable-nls --enable-obsolete --enable-plugin --enable-targets=all --exec-prefix=/usr --host=x86_64-redhat-linux-gnu --includedir=/usr/include --infodir=/usr/share/info --libexecdir=/usr/libexec --localstatedir=/var --mandir=/usr/share/man --prefix=/usr --program-prefix=arm-linux-gnu- --sbindir=/usr/sbin --sharedstatedir=/var/lib --sysconfdir=/etc --target=arm-linux-gnueabi --with-bugurl=http://bugzilla.redhat.com/bugzilla/ --with-gcc-major-version-only --with-isl --with-newlib --with-plugin-ld=/usr/bin/arm-linux-gnu-ld --with-sysroot=/usr/arm-linux-gnu/sys-root --with-system-libunwind --with-system-zlib --without-headers --with-tune=generic-armv7-a --with-arch=armv7-a --with-float=hard --with-fpu=vfpv3-d16 --with-abi=aapcs-linux --enable-gnu-indirect-function --with-linker-hash-style=gnu Thread model: single Supported LTO compression algorithms: zlib zstd gcc version 13.2.1 20230728 (Red Hat Cross 13.2.1-1) (GCC) $ arm-linux-gnu-gcc -Os -c t-build-bug.c $ arm-linux-gnu-objdump -j .text -D t-build-bug.o t-build-bug.o: file format elf32-littlearm Disassembly of section .text: : 0: e3a00020mov r0, #32 ;; As expected 4: e12ff
Re: Checks that autotools generated files were re-generated correctly
Hi, On Wed, Nov 15 2023, Mark Wielaard wrote: > Hi! (adding gdb and binutils to the CC) > > On Thu, Nov 09, 2023 at 12:30:59AM +0100, Mark Wielaard wrote: >> On Mon, Nov 06, 2023 at 06:04:48PM +0100, Martin Jambor wrote: >> > I have inherited Martin Liška's buildbot script that checks that all >> > sorts of autotools generated files, mainly configure scripts, were >> > re-generated correctly when appropriate. While the checks are hopefully >> > useful, they report issues surprisingly often and reporting them feels >> > especially unproductive. >> >> Cool! A small python script cannot replace him of course. But it is >> nice to get a small virtual mliska :) >> >> > Could such checks be added to our server side push hooks so that commits >> > introducing these breakages would get refused automatically. While the >> > check might be a bit expensive, it only needs to be run on files >> > touching the generated files and/or the files these are generated from. >> >> So this doesn't just need that script, but also an execution >> environment that contains the right versions of the autotools. We >> could install those of course, but running them from a git hook on >> checkin indeed seems a little expensive. >> >> Creating a container with the script and the right versions of all >> tools might be the best thing. Then the script can be run from a cron >> job or buildbot. Or even by someone hacking on the build/configure >> scripts to make sure they are generating with the right tools. >> >> builder.sourceware.org already contains various of such containers: >> https://sourceware.org/cgit/builder/tree/builder/containers >> https://sourceware.org/cgit/builder/tree/README_containers >> >> Friday is Sourceware Open Office hour (#overseers on irc.libera.chat >> at 18:00 UTC). We could hack something together then and see how to >> hook it up. > > So we did indeed discuss and hack something together. Wonderful, thanks to everyone working to improve the situation with these errors. Martin > > The container file is here: > https://sourceware.org/cgit/builder/tree/builder/containers/Containerfile-autotools > > The script is here: > https://sourceware.org/cgit/builder/tree/builder/containers/autoregen.py > > A buildbot can then use that container to run that script and then > check that git diff is empty on every commit to binutils-gdb.git and > gcc.git. If it finds an issue it will sent email with the diff. > > It already found issues in both gcc and binutils-gdb. All fixed now. > > Thanks to Arsen and Sam for testing, fixing and updating the script > (it now also runs aclocal). > > If you want to run this locally you can use the container file to > create an image and then run autoregen.py on your local tree by bind > mounting your git tree inside it. > > $ git clone https://sourceware.org/git/builder.git > $ cd builder/ > $ podman build -t autotools -f builder/containers/Containerfile-autotools \ > builder/containers > $ cd .. # assuming your binutils-gdb directory is here > $ podman run --privileged -u root -v $(pwd)/binutils-gdb:/binutils-gdb \ > -ti --entrypoint "/bin/bash" autotools > # then inside the container > cd /binutils-gdb > autoregen.py > > Change binutils-gdb to gcc if you are working on gcc. > You should also be able to do the above with docker instead of podman. > > Cheers, > > Mark
gcc-11-20231116 is now available
Snapshot gcc-11-20231116 is now available on https://gcc.gnu.org/pub/gcc/snapshots/11-20231116/ and on various mirrors, see https://gcc.gnu.org/mirrors.html for details. This snapshot has been generated from the GCC 11 git branch with the following options: git://gcc.gnu.org/git/gcc.git branch releases/gcc-11 revision 442a9f08d39eee53e1a8a598b95743e8a16681ab You'll find: gcc-11-20231116.tar.xz Complete GCC SHA256=4f7742239961cd038242f10eb7f38ed897ee700f6642bb5263f47955372f87a2 SHA1=36e9d9a8c6c23d1d298ae36e884f62e161193f73 Diffs from 11-20231109 are available in the diffs/ subdirectory. When a particular snapshot is ready for public consumption the LATEST-11 link is updated and a message is sent to the gcc list. Please do not use a snapshot before it has been announced that way.
[PATCH] C++: Introduce the extended attribute for asm declarations
Hi all, This is the beginning of a patch to introduce the extended attribute for asm declarations proposed in https://gcc.gnu.org/pipermail/gcc-patches/2023-November/636563.html. I will need some reviewer help in implementing this patch, as I am not very familiar with gcc's internals. The attribute in question looks as such (Example): [[gnu::extended([output] "=r" (output) [otheroutput] "=r" (otheroutput), [input] "r" (input) [otherinput] "r" (otherinput), "%rcx" "%rdx", label, volatile stack)]] asm (""); I would really appreciate any reviews, as well as help in implementing this patch best regards, Julian From a189f2820025315b5574d0e9384b96301c6ba7e8 Mon Sep 17 00:00:00 2001 From: TheShermanTanker Date: Fri, 17 Nov 2023 11:09:50 +0800 Subject: [PATCH] Introduce the extended attribute for asm declarations --- gcc/cp/parser.cc | 25 + gcc/cp/tree.cc | 11 +++ 2 files changed, 36 insertions(+) diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 5116bcb78f6..ecc5f2fabc1 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -15407,6 +15407,13 @@ cp_parser_block_declaration (cp_parser *parser, cp_parser_commit_to_tentative_parse (parser); cp_parser_asm_definition (parser); } + else if ((attr_idx = cp_parser_skip_std_attribute_spec_seq (parser, 1)) != 1 + && cp_lexer_nth_token_is_keyword (parser->lexer, attr_idx, RID_ASM)) +{ + if (statement_p) +cp_parser_commit_to_tentative_parse (parser); + cp_parser_asm_definition (parser); +} /* If the next keyword is `namespace', we have a namespace-alias-definition. */ else if (token1->keyword == RID_NAMESPACE) @@ -22397,6 +22404,23 @@ cp_parser_asm_definition (cp_parser* parser) bool invalid_inputs_p = false; bool invalid_outputs_p = false; required_token missing = RT_NONE; + + tree attrs = cp_parser_std_attribute_spec_seq (parser); + tree extended = error_mark_node; + + if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)) +{ + /* Error during attribute parsing that resulted in skipping + to next semicolon. */ + cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); + return; +} + + if (attrs != error_mark_node) +{ + extended = lookup_attribute ("gnu", "extended", attrs); +} + location_t asm_loc = cp_lexer_peek_token (parser->lexer)->location; /* Look for the `asm' keyword. */ @@ -22511,6 +22535,7 @@ cp_parser_asm_definition (cp_parser* parser) two `:' tokens. */ if (cp_parser_allow_gnu_extensions_p (parser) && parser->in_function_body + && extended == error_mark_node && (cp_lexer_next_token_is (parser->lexer, CPP_COLON) || cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))) { diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index 417c92ba76f..1f081b3dfd8 100644 --- a/gcc/cp/tree.cc +++ b/gcc/cp/tree.cc @@ -46,6 +46,7 @@ static tree verify_stmt_tree_r (tree *, int *, void *); static tree handle_init_priority_attribute (tree *, tree, tree, int, bool *); static tree handle_abi_tag_attribute (tree *, tree, tree, int, bool *); +static tree handle_extended_attribute (tree *, tree, tree, int, bool *); static tree handle_contract_attribute (tree *, tree, tree, int, bool *); /* If REF is an lvalue, returns the kind of lvalue that REF is. @@ -5080,6 +5081,8 @@ const struct attribute_spec cxx_attribute_table[] = handle_init_priority_attribute, NULL }, { "abi_tag", 1, -1, false, false, false, true, handle_abi_tag_attribute, NULL }, + { "extended", 0, 5, true, false, false, false, +handle_extended_attribute, NULL }, { NULL, 0, 0, false, false, false, false, NULL, NULL } }; @@ -5350,6 +5353,14 @@ handle_abi_tag_attribute (tree* node, tree name, tree args, return NULL_TREE; } +static tree +handle_extended_attribute (tree *node, tree name, tree args, int flags, bool *no_add_attrs) +{ + /* TODO What could be done here? */ + *no_add_attrs = true; + return NULL_TREE; +} + /* Perform checking for contract attributes. */ tree -- 2.41.0