Re: [PATCH] tell gcc optimizer to never introduce new data races
On Mon, 16 Jun 2014, Dan Carpenter wrote: > Adding "--param allow-store-data-races=0" to the GCC options for the > kernel breaks C=1 because Sparse isn't expecting a GCC option with that > format. > > It thinks allow-store-data-races=0 is the name of the file we are trying > to test. Try use Sparse on linux-next to see the problem. Alright, no word from gcc folks, so let's hope the undocumented format of the parameter works better ... sigh. Andrew, please use the updated one below. From: Jiri Kosina Subject: [PATCH] ./Makefile: tell gcc optimizer to never introduce new data races We have been chasing a memory corruption bug, which turned out to be caused by very old gcc (4.3.4), which happily turned conditional load into a non-conditional one, and that broke correctness (the condition was met only if lock was held) and corrupted memory. This particular problem with that particular code did not happen when never gccs were used. I've brought this up with our gcc folks, as I wanted to make sure that this can't really happen again, and it turns out it actually can. Quoting Martin Jambor : More current GCCs are more careful when it comes to replacing a conditional load with a non-conditional one, most notably they check that a store happens in each iteration of _a_ loop but they assume loops are executed. They also perform a simple check whether the store cannot trap which currently passes only for non-const variables. A simple testcase demonstrating it on an x86_64 is for example the following: $ cat cond_store.c int g_1 = 1; int g_2[1024] __attribute__((section ("safe_section"), aligned (4096))); int c = 4; int __attribute__ ((noinline)) foo (void) { int l; for (l = 0; (l != 4); l++) { if (g_1) return l; for (g_2[0] = 0; (g_2[0] >= 26); ++g_2[0]) ; } return 2; } int main (int argc, char* argv[]) { if (mprotect (g_2, sizeof(g_2), PROT_READ) == -1) { int e = errno; error (e, e, "mprotect error %i", e); } foo (); __builtin_printf("OK\n"); return 0; } /* EOF */ $ ~/gcc/trunk/inst/bin/gcc cond_store.c -O2 --param allow-store-data-races=0 $ ./a.out OK $ ~/gcc/trunk/inst/bin/gcc cond_store.c -O2 --param allow-store-data-races=1 $ ./a.out Segmentation fault The testcase fails the same at least with 4.9, 4.8 and 4.7. Therefore I would suggest building kernels with this parameter set to zero. I also agree with Jikos that the default should be changed for -O2. I have run most of the SPEC 2k6 CPU benchmarks (gamess and dealII failed, at -O2, not sure why) compiled with and without this option and did not see any real difference between respective run-times. Hopefully the default will be changed in newer gccs, but let's force it for kernel builds so that we are on a safe side even when older gcc are used. The code in question was out-of-tree printk-in-NMI (yeah, surprise suprise, once again) patch written by Petr Mladek, let me quote his comment from our internal bugzilla: === I have spent few days investigating inconsistent state of kernel ring buffer. It went out that it was caused by speculative store generated by gcc-4.3.4. The problem is in assembly generated for make_free_space(). The functions is called the following way: + vprintk_emit(); + log = MAIN_LOG; // with logbuf_lock or log = NMI_LOG; // with nmi_logbuf_lock cont_add(log, ...); + cont_flush(log, ...); + log_store(log, ...); + log_make_free_space(log, ...); If called with log = NMI_LOG then only nmi_log_* global variables are safe to modify but the generated code does store also into (main_)log_* global variables: : 55 push %rbp 89 f6 mov%esi,%esi 48 8b 05 03 99 51 01mov0x1519903(%rip),%rax # 82620868 44 8b 1d ec 98 51 01mov0x15198ec(%rip),%r11d # 82620858 8b 35 36 60 14 01 mov0x1146036(%rip),%esi # 8224cfa8 44 8b 35 33 60 14 01mov0x1146033(%rip),%r14d # 8224cfac 4c 8b 2d d0 98 51 01mov0x15198d0(%rip),%r13 # 82620850 4c 8b 25 11 61 14 01mov0x1146111(%rip),%r12 # 8224d098 49 89 c2mov%rax,%r10 48 21 c2and%rax,%rdx 48 8b 1d 0c 99 55 01mov0x155990c(%rip),%rbx # 826608a0 49 c1 ea 20 shr$0x20,%r10 48 89 55 d0 mov%rdx,-0x30(%rbp) 44 29 desub%r11d,%esi 45 29 d6sub%r10d,%r14d 4c 8b 0d 97 98 51 01mov0x1519897(%rip),%r9 # 82620840 eb 7e jmp81107029 [...] 85 ff test %edi,%edi # edi = 1 for NMI_LOG 4c 89 e8mov%r13,%rax 4c 89 ca
RE: Register Pressure guided Unroll and Jam in GCC !!
That is true. Early estimation of register pressure should be improved. Right now I am looking at an example IVOPTS produces too many induction variables and causes a lot of register spilling. Though ivopts pass called estimate_reg_pressure_cost function, results are not even close to real situation. Bingfeng -Original Message- From: gcc-ow...@gcc.gnu.org [mailto:gcc-ow...@gcc.gnu.org] On Behalf Of Vladimir Makarov Sent: 16 June 2014 19:37 To: Ajit Kumar Agarwal; gcc@gcc.gnu.org Cc: Michael Eager; Vinod Kathail; Shail Aditya Gupta; Vidhumouli Hunsigida; Nagaraju Mekala Subject: Re: Register Pressure guided Unroll and Jam in GCC !! On 2014-06-16, 10:14 AM, Ajit Kumar Agarwal wrote: > Hello All: > > I have worked on the Open64 compiler where the Register Pressure Guided > Unroll and Jam gave a good amount of performance improvement for the C and > C++ Spec Benchmark and also Fortran benchmarks. > > The Unroll and Jam increases the register pressure in the Unrolled Loop > leading to increase in the Spill and Fetch degrading the performance of the > Unrolled Loop. The Performance of Cache locality achieved through Unroll and > Jam is degraded with the presence of Spilling instruction due to increases in > register pressure Its better to do the decision of Unrolled Factor of the > Loop based on the Performance model of the register pressure. > > Most of the Loop Optimization Like Unroll and Jam is implemented in the High > Level IR. The register pressure based Unroll and Jam requires the calculation > of register pressure in the High Level IR which will be similar to register > pressure we calculate on Register Allocation. This makes the implementation > complex. > > To overcome this, the Open64 compiler does the decision of Unrolling to both > High Level IR and also at the Code Generation Level. Some of the decisions > way at the end of the Code Generation . The advantage of using this approach > like Open64 helps in using the register pressure information calculated by > the Register Allocator. This helps the implementation much simpler and less > complex. > > Can we have this approach in GCC of the Decisions of Unroll and Jam in the > High Level IR and also to defer some of the decision at the Code Generation > Level like Open64? > > Please let me know what do you think. > Most loop optimizations are a good target for register pressure sensitive algorithms as loops are usually program hot spots and any pressure decrease there would be harmful as any RA can not undo such complex transformations. So I guess your proposal could work. Right now we have only pressure-sensitive modulo scheduling (SMS) and loop-invariant motion (as I remember switching from loop-invariant motion based on some very inaccurate register-pressure evaluation to one based on RA pressure evaluation gave a nice improvement about 1% for SPECFP2000 on some targets).
Re: [GSoC] decision tree first steps
On Tue, Jun 17, 2014 at 12:21 AM, Prathamesh Kulkarni wrote: > On Mon, Jun 16, 2014 at 4:45 PM, Richard Biener > wrote: >> >> > * Patterns requiring GENERIC support like cond_expr >> > I am not sure about how to handle these patterns. I was thinking about >> > handling them after we have >> > GENERIC code generation in place. >> >> Yeah, though handling GENERIC for matching is as simple as >> emitting the code check twice, the 2nd check off the an else >> from the if (TREE_CODE (op) == SSA_NAME). That is, >> arrange for expr::gen_gimple_match_dt to emit >> >>if (TREE_CODE (...) == SSA_NAME) >> { >> gimple def_stmt = SSA_NAME_DEF_STMT (...); >> if (is_gimple_assign (def_stmt) && gimple_assign_rhs_code >> (def_stmt) == ) >> { >> >> } >>else (TREE_CODE (...) == ) >> { >> >> } >> >> which would require some refactoring in the generator. As for refactoring >> it I'd not hook the gen_gimple_match_dt off the AST operands but >> inline it in the decision tree traversal routine - that also makes the >> commoning above easier. > Thanks, I shall get started on this. Good. You also miss the special-casing of REALPART_EXPR, IMAGPART_EXPR, VIEW_CONVERT_EXPR and BIT_FIELD_REF operand extraction as you say below. >> >> Btw, I checked what we generate for (bogus) >> >> (match_and_simplify >> (MINUS_EXPR (PLUS_EXPR@2 @0 @1) @2) >> @1) >> >> and the DT looks like >> >> root, 1 >> |--operand: MINUS_EXPR, 1 >> |operand: true, 1 >> |--operand: PLUS_EXPR, 1 >> |operand: true, 1 >> |--operand: true, 1 >> |operand: match(1), 1 >> |--simplify_0, 0 >> >> though I expected >> >> root, 1 >> |--operand: MINUS_EXPR, 1 >> |operand: PLUS_EXPR, 1 >> |--operand: true, 1 >> |operand: true, 1 >> |--operand: match(1), 1 >> |simplify_0, 0 >> >> that is, I wonder where the extra "true" comes from. > Thanks, fixed it in the current patch. Thanks. >> >> >> For >> >> (match_and_simplify >> (MINUS_EXPR @2 (PLUS_EXPR@2 @0 @1)) >> @1) >> >> I get >> >> root, 1 >> |--operand: MINUS_EXPR, 1 >> |operand: true, 1 >> |--operand: match(1), 1 >> |operand: PLUS_EXPR, 1 >> |--operand: true, 1 >> |operand: true, 1 >> |--simplify_0, 0 >> >> which looks good to me. >> >> There is still a fallthru for all match failures but the DT should ensure >> that once any of the checks is false we can terminate - that is, >> we never have to backtrack. Sth simple like >> >> --- genmatch.c.orig 2014-06-16 12:57:38.401890454 +0200 >> +++ genmatch.c 2014-06-16 12:58:03.451888730 +0200 >> @@ -816,6 +816,7 @@ >>unsigned i; >>for (i = 0; i < kids.length (); ++i) >> kids[i]->gen_gimple (f); >> + fprintf (f, "return false;\n"); >> >> >>for (i = 0; i < n_braces; ++i) >> fprintf (f, "}\n"); >> >> So overall I think we are ok sofar and don't need major changes in >> the algorithm. >> >> I'd say add the missing call support and we're good to go ripping out >> the non-decision tree path. >> >> I'm happy to do some of the refactoring that I'd like to see myself >> so you can concentrate on pattern implementing for phase 2. But >> feel free to do some of it yourself. >> >> > Small point: I was wondering if it's a good idea to slightly change >> > the syntax of pattern to sth like: >> > match-expression -> transform ? >> > eg: >> > (minus (plus @0 @1) @1) -> @0 >> > Looks smaller -:) >> >> Well, I suppose we stay with what we have here. > The attached patch, adds support for built-in functions, and fixes > insertion bug in decision tree. > The insertion in decision tree is carried out during preorder traversal > of AST (insert_operand), so it avoids generating preorder traversal in > vector (removed walk_operand_preorder and > lower_capture). For now have put (parent, pos, preorder_level) in > separate struct operand_info, and added instance > of this struct to operand (struct operand_info opinfo). operand_info > is computed during preorder traversal > (insert_operand), so parsing routines are not concerned with it. > Eventually we should probably move > matching code on decision tree nodes. For convenience of tracking > patterns, I have numbered them in match.pd. Ok. > * Testing > Total patterns in match.pd - 58 > Total test cases: 4 (match-1.c), 32 (match-decision-tree.c), match-2.c > is screwed. How is it screwed? I see it all pass ... > Out of 22 remaining patterns: > Not supported yet (require GENERIC support or special handling): 31 > (convert), 33, 34, 35 (realpart/imagpart), 37 (cond) > Not able to write test-cases: 2, 16, 31, 38 Sth like char *foo (char *p) { int i = 0; return p + i; } for 2) and using -fdump-tree-ccp1-details and scanning the ccp1 dump for "Match-and-simplified definition of _4 to p_3(D)" (ok, that's a quite non-informative dump message and we should improve it ... ok, changed now to "Match-and-simplified p_3
Re: C++ interop issue due to non-null pointers
On 06/12/2014 12:04 PM, Jonathan Wakely wrote: What can we do about it? How common is it to use std::vector with qsort, rather than std::sort(vec.begin(), vec.end()), which does the right thing? Our very own vec::qsort has the same problem, so I'd wager that it's fairly common. We could make vector::data() guarantee a non-null pointer with _FORTIFY_SOURCE, but I'd rather not do so in "unfortified" code. Some users would object to the extra check needed. Or we could remove the nonnull attributes, so that the additional checks are not necessary. -- Florian Weimer / Red Hat Product Security Team
Re: C++ interop issue due to non-null pointers
On Tue, Jun 17, 2014 at 02:41:38PM +0200, Florian Weimer wrote: > On 06/12/2014 12:04 PM, Jonathan Wakely wrote: > > >> What can we do about it? > > > >How common is it to use std::vector with qsort, rather than > >std::sort(vec.begin(), vec.end()), which does the right thing? > > Our very own vec::qsort has the same problem, so I'd wager that it's fairly > common. template inline void vec::qsort (int (*cmp) (const void *, const void *)) { if (length () > 1) ::qsort (address (), length (), sizeof (T), cmp); } So I don't think it does. > >We could make vector::data() guarantee a non-null pointer with > >_FORTIFY_SOURCE, but I'd rather not do so in "unfortified" code. Some > >users would object to the extra check needed. > > Or we could remove the nonnull attributes, so that the additional checks are > not necessary. I'm not that familiar with the exact requirements of std::vector, could we use the same trick as http://mxr.mozilla.org/mozilla-central/source/xpcom/glue/nsTArray.h#275 that is instead of pointing at null point at a global header used for all empty vectors? Trev > > -- > Florian Weimer / Red Hat Product Security Team signature.asc Description: Digital signature
Re: C++ interop issue due to non-null pointers
On 06/17/2014 04:24 PM, Trevor Saunders wrote: On Tue, Jun 17, 2014 at 02:41:38PM +0200, Florian Weimer wrote: On 06/12/2014 12:04 PM, Jonathan Wakely wrote: What can we do about it? How common is it to use std::vector with qsort, rather than std::sort(vec.begin(), vec.end()), which does the right thing? Our very own vec::qsort has the same problem, so I'd wager that it's fairly common. template inline void vec::qsort (int (*cmp) (const void *, const void *)) { if (length () > 1) ::qsort (address (), length (), sizeof (T), cmp); } So I don't think it does. Ah, I looked at the wrong branch. It was fixed in r206709, apparently for performance reasons, see PR46590. We could make vector::data() guarantee a non-null pointer with _FORTIFY_SOURCE, but I'd rather not do so in "unfortified" code. Some users would object to the extra check needed. Or we could remove the nonnull attributes, so that the additional checks are not necessary. I'm not that familiar with the exact requirements of std::vector, could we use the same trick as http://mxr.mozilla.org/mozilla-central/source/xpcom/glue/nsTArray.h#275 that is instead of pointing at null point at a global header used for all empty vectors? For std::vector, we could use reinterpret_cast(alignof(T)) or reinterpret_cast(sizeof(T)) if those are sufficiently well-defined as far as GCC is concerned. The smaller constant is easier to load, and no relocation is required. -- Florian Weimer / Red Hat Product Security Team
Re: C++ interop issue due to non-null pointers
On Tue, Jun 17, 2014 at 04:34:16PM +0200, Florian Weimer wrote: > >I'm not that familiar with the exact requirements of std::vector, could > >we use the same trick as > >http://mxr.mozilla.org/mozilla-central/source/xpcom/glue/nsTArray.h#275 > >that is instead of pointing at null point at a global header used for > >all empty vectors? > > For std::vector, we could use reinterpret_cast(alignof(T)) or > reinterpret_cast(sizeof(T)) if those are sufficiently well-defined as > far as GCC is concerned. The smaller constant is easier to load, and no > relocation is required. If there is no object at those addresses, that is still undefined behavior. GCC will likely not optimize it away at this point, but having code with undefined behavior is just asking for future trouble. Just use "" instead? Jakub
Re: C++ interop issue due to non-null pointers
On 06/17/2014 04:39 PM, Jakub Jelinek wrote: On Tue, Jun 17, 2014 at 04:34:16PM +0200, Florian Weimer wrote: I'm not that familiar with the exact requirements of std::vector, could we use the same trick as http://mxr.mozilla.org/mozilla-central/source/xpcom/glue/nsTArray.h#275 that is instead of pointing at null point at a global header used for all empty vectors? For std::vector, we could use reinterpret_cast(alignof(T)) or reinterpret_cast(sizeof(T)) if those are sufficiently well-defined as far as GCC is concerned. The smaller constant is easier to load, and no relocation is required. If there is no object at those addresses, that is still undefined behavior. GCC is the implementation, so it could be made defined there. GCC will likely not optimize it away at this point, but having code with undefined behavior is just asking for future trouble. Just use "" instead? It's always const and may lack sufficient alignment. The former isn't a problem in C++ (I think), but the alignment is an issue. -- Florian Weimer / Red Hat Product Security Team
regs_used estimation in IVOPTS seriously flawed
Hi, I am looking at a performance regression in our code. A big loop produces and uses a lot of temporary variables inside the loop body. The problem appears that IVOPTS pass creates even more induction variables (from original 2 to 27). It causes a lot of register spilling later and performance take a severe hit. I looked into tree-ssa-loop-ivopts.c, it does call estimate_reg_pressure_cost function to take # of registers into consideration. The second parameter passed as data->regs_used is supposed to represent old register usage before IVOPTS. return size + estimate_reg_pressure_cost (size, data->regs_used, data->speed, data->body_includes_call); In this case, it is mere 2 by following calculation. Essentially, it only counts all loop invariant registers, ignoring all registers produced/used inside the loop. n = 0; for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); gsi_next (&psi)) { phi = gsi_stmt (psi); op = PHI_RESULT (phi); if (virtual_operand_p (op)) continue; if (get_iv (data, op)) continue; n++; } EXECUTE_IF_SET_IN_BITMAP (data->relevant, 0, j, bi) { struct version_info *info = ver_info (data, j); if (info->inv_id && info->has_nonlin_use) n++; } data->regs_used = n; I believe how regs_used is calculated is seriously flawed, or estimate_reg_pressure_cost is problematic if n_old is only supposed to be loop invariant registers. Either way, it affects how IVOPTS makes decision and could result in worse code. What do you think? Any idea on how to improve this? Thanks, Bingfeng
Re: C++ interop issue due to non-null pointers
On Tue, Jun 17, 2014 at 04:52:29PM +0200, Florian Weimer wrote: > On 06/17/2014 04:39 PM, Jakub Jelinek wrote: > >On Tue, Jun 17, 2014 at 04:34:16PM +0200, Florian Weimer wrote: > >>>I'm not that familiar with the exact requirements of std::vector, could > >>>we use the same trick as > >>>http://mxr.mozilla.org/mozilla-central/source/xpcom/glue/nsTArray.h#275 > >>>that is instead of pointing at null point at a global header used for > >>>all empty vectors? > >> > >>For std::vector, we could use reinterpret_cast(alignof(T)) or > >>reinterpret_cast(sizeof(T)) if those are sufficiently well-defined as > >>far as GCC is concerned. The smaller constant is easier to load, and no > >>relocation is required. > > > >If there is no object at those addresses, that is still undefined behavior. > > GCC is the implementation, so it could be made defined there. > > >GCC will likely not optimize it away at this point, but having code with > >undefined behavior is just asking for future trouble. Just use "" instead? > > It's always const and may lack sufficient alignment. The former isn't a > problem in C++ (I think), but the alignment is an issue. Alignment for what? You don't specify any alignment to the C qsort, only size, but even say size 8 can have just alignment of 1, consider say struct S { char c[8]; };. So, the only problem with alignment would be in the callback function where it could try to dereference the passed in const void * pointers, but if the array length is 0, the callback function is never called, so I don't see why alignment would be an issue. Jakub
Issue with attribute ((aligned)) ?
Hello, in comparing ABI conformance across compilers I ran across an issue where GCC's behavior does appear to deviate from the manual. In http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html, we have: aligned (alignment) This attribute specifies a minimum alignment for the variable or structure field, measured in bytes. [snip] When used on a struct, or struct member, the aligned attribute can only increase the alignment; in order to decrease it, the packed attribute must be specified as well. However, the following test case: struct test { int * __attribute__ ((aligned (2))) a; }; int main (void) { printf ("align: %d\n", (int)__alignof__(struct test)); } outputs an alignment of 2. Based on the above wording, I would have expected an alignment of 8 on a 64-bit machine. (And the latter is indeed what LLVM, for example, implements.) Note that this appears to happen only in the specific declaration above; things work as documented when using e.g. int __attribute__ ((aligned (2))) a; or even int *a __attribute__ ((aligned (2))); In fact, this also raises the question what the exact semantics of the above construct is; according to the manual in seems that int * __attribute__ ((aligned (2))) a; ought to define a (default-aligned) pointer to a 2-aligned int, in which case the above distinction would be moot and we'd expect __alignof__(struct test) to be 8 in any case. (see http://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html) That does't appear to be what's happening either; with struct test x; printf ("align: %d %d\n", (int)__alignof__(x.a), (int)__alignof__(*x.a)); I get 2 for __alignof__(x.a) and 4 for __alignof__(*x.a), so it does appear the alignment is being applied (if incorrectly) to the pointer, not the pointed-to data ... (LLVM actually also does it this way.) Is this a bug in GCC (or the documentation)? Bye, Ulrich -- Dr. Ulrich Weigand GNU/Linux compilers and toolchain ulrich.weig...@de.ibm.com
Re: Stamping Inquiry/Land Rover/Changdong Co., Ltd.
Dear Manager, Good Day. This is jewel from Changdong Stamping Die Co,.Ltd. We are one of leading manufacturer of Smping Dies(Press Tools), especially for the Jaguar & Land Rovert and Volkswagen cars projects, Progression dies,tranfer dies, process simulation and other technical are all available. Product catalog and company profile will send to you by second email,while receive your reply. Best regards, Jewel gwfmy4s
Cross-compiler GCC 4.8.3 for AArch64 port (aarch64-linux-gnu) - successfully built and installed
Dear GCC Team, I would like to report that cross-compiler GCC 4.8.3 for AArch64 port (aarch64-linux-gnu) is successfully built and installed on Ubuntu 12.04.3 LTS Buildstat Info: user1@linux:~/aarch64-crossbuild-gcc4.8.3/gcc/gcc-4.8.3$ ./config.guess i686-pc-linux-gnu user1@linux:~/aarch64-crossbuild-gcc4.8.3/gcc/gcc-4.8.3$ ../../install/bin/aarch64-linux-gnu-gcc -v Using built-in specs. COLLECT_GCC=../../install/bin/aarch64-linux-gnu-gcc COLLECT_LTO_WRAPPER=/home/user1/aarch64-crossbuild-gcc4.8.3/install/libexec/gcc/aarch64-linux-gnu/4.8.3/lto-wrapper Target: aarch64-linux-gnu Configured with: ../gcc-4.8.3/configure --target=aarch64-linux-gnu --prefix=/home/user1/aarch64-crossbuild-gcc4.8.3/install/ --with-sysroot=/home/user1/aarch64-crossbuild-gcc4.8.3/sysroot/ --with-gmp=/usr/local --with-mpfr=/usr/local --with-mpc=/usr/local --disable-libssp --disable-libgomp --disable-libmudflap --disable-multilib --disable-libatomic --disable-libitm --disable-libsanitizer --disable-libquadmath --disable-target-libiberty --enable-languages=c Thread model: posix gcc version 4.8.3 (GCC) user1@linux:~/aarch64-crossbuild-gcc4.8.3/gcc/gcc-4.8.3$ uname -a Linux linux 3.8.0-29-generic #42~precise1-Ubuntu SMP Wed Aug 14 15:31:16 UTC 2013 i686 i686 i386 GNU/Linux user1@linux:~/aarch64-crossbuild-gcc4.8.3/gcc/gcc-4.8.3$ dpkg -l libc6 Name Version Description ==-==- libc6 2.15-0ubuntu10 Embedded GNU C Library: Shared libraries However, EGLIBC trunk, downloaded on 11th June 2014 was used for cross-compiling. Best Regards, Raghunath Lolur.
Ada and CFLAGS_FOR_TARGET
Hi I was updating the RTEMS scripts to build GNAT and it appears that passing CFLAGS_FOR_TARGET in to add a -I option to the build no longer works. We were using it so the Ada build could find the networking .h files. What's the current way of doing this? Thanks. -- Joel Sherrill, Ph.D. Director of Research & Development joel.sherr...@oarcorp.comOn-Line Applications Research Ask me about RTEMS: a free RTOS Huntsville AL 35805 Support Available(256) 722-9985