RWMA Welding Electrodes of Copper Chromium Zirconium, Beryllium Copper, Tungsten Copper, Nickel Copper
Namaste, We are importers and stockiest of RWMA Resistance Welding Electrodes like COPPER CHROMIUM ZIRCONIUM / CuCrZr / C18150 /CuCr1Zr / CW106C - in Rounds and Flats Characteristics: CuCrZr alloy that can be hardened by cold forming and by precipitation of CuCrZr - phases during a heat treatment. It has good bendability, excellent hot and cold forming properties, a high strength and a good corrosion resistance. Due to the CrZr-precipitations the relaxation properties, even at temperatures up to 250°C are excellent. The electrical and thermal conductivity is excellent. Welding, soldering and brazing properties are good too. Main ApplicationsResistance Welding in Low Carbon Steel and Galvanised Steel, Refrigerator Parts, Seam Welding, Nozzles. Automotive & Electrical Switches and Relays, Contacts, Connectors, Terminals, Press fits, Components for the electrical industry, Stamped parts,Semiconductor Components, Junction Boxes, Photovoltaic Systems. Other Equivalent Standards are C18160, C18400, C18200 TUNGSTEN COPPER / WCu is a mixture of Tungsten and Copper, where the Tungsten ranges from 50% to 90% with balance Copper. Characteristics: Good Thermal and Electrical Conductivity, Low Thermal Expansion, Resistance to Erosion from arcing Main Applications: Electrodes in EDM - electric spark erosion cutting machines, Heat Sinks for passive cooling of electronics devices, Electrodes for Resistance Welding, Arc and Vaccum Contacts for High and Medium Voltage breakers and Vaccum Interrupters. Other Equivalent are Heavy Tungsten Alloys, We can also offer Molybdenum, Tantalum, TZM Molybdenum, Pure Tungsten. BERYLLIUM COPPER WELDING ELECTRODES - C17510, C17500, CCNB, CuCo1Ni1Be, C17200 Depending upon the application requirements, copper beryllium alloys are available in two alloy classes: High Strength (C17000, C17200, C17300) and High Conductivity (C17410, C17460, C17500, C17510). Both alloy classes are strengthened by thermal treatments. Main application:Electrodes for medical purposes, such as EEG, ECG, ECT, defibrillator, electrophysiology techniques in biomedical researchelectroplating, welding, Flat Welding dies, projection welding electrode, electrical componentsAlso used in Robotic welding machines, MIG & MAG Welding industryPlasma And laser cutting nozzles, Electrodes for cathodic protectionElectrodes for groundingElectrodes for chemical analysis using electrochemical methodsInert electrodes for electrolysis (made of platinum)Membrane electrode assembly Other than that COPPER ZIRCONIUM [C15000], COPPER NICKEL SILICON CHROMIUM [C18000] can be arranged as per your requirements. Please send us your complete requirements immediately and oblige. With Best Regards, Ms Pragati Sanap, 8928403611, sa...@domadia.com Mr.Rohan Kamble, 8928403617, b...@domadia.com DALI ELECTRONICS, Mumbai, India.
RWMA Welding Electrodes of Copper Chromium Zirconium, Beryllium Copper, Tungsten Copper, Nickel Copper
Namaste, We are importers and stockiest of RWMA Resistance Welding Electrodes like COPPER CHROMIUM ZIRCONIUM / CuCrZr / C18150 /CuCr1Zr / CW106C - in Rounds and Flats Characteristics: CuCrZr alloy that can be hardened by cold forming and by precipitation of CuCrZr - phases during a heat treatment. It has good bendability, excellent hot and cold forming properties, a high strength and a good corrosion resistance. Due to the CrZr-precipitations the relaxation properties, even at temperatures up to 250°C are excellent. The electrical and thermal conductivity is excellent. Welding, soldering and brazing properties are good too. Main ApplicationsResistance Welding in Low Carbon Steel and Galvanised Steel, Refrigerator Parts, Seam Welding, Nozzles. Automotive & Electrical Switches and Relays, Contacts, Connectors, Terminals, Press fits, Components for the electrical industry, Stamped parts,Semiconductor Components, Junction Boxes, Photovoltaic Systems. Other Equivalent Standards are C18160, C18400, C18200 TUNGSTEN COPPER / WCu is a mixture of Tungsten and Copper, where the Tungsten ranges from 50% to 90% with balance Copper. Characteristics: Good Thermal and Electrical Conductivity, Low Thermal Expansion, Resistance to Erosion from arcing Main Applications: Electrodes in EDM - electric spark erosion cutting machines, Heat Sinks for passive cooling of electronics devices, Electrodes for Resistance Welding, Arc and Vaccum Contacts for High and Medium Voltage breakers and Vaccum Interrupters. Other Equivalent are Heavy Tungsten Alloys, We can also offer Molybdenum, Tantalum, TZM Molybdenum, Pure Tungsten. BERYLLIUM COPPER WELDING ELECTRODES - C17510, C17500, CCNB, CuCo1Ni1Be, C17200 Depending upon the application requirements, copper beryllium alloys are available in two alloy classes: High Strength (C17000, C17200, C17300) and High Conductivity (C17410, C17460, C17500, C17510). Both alloy classes are strengthened by thermal treatments. Main application:Electrodes for medical purposes, such as EEG, ECG, ECT, defibrillator, electrophysiology techniques in biomedical researchelectroplating, welding, Flat Welding dies, projection welding electrode, electrical componentsAlso used in Robotic welding machines, MIG & MAG Welding industryPlasma And laser cutting nozzles, Electrodes for cathodic protectionElectrodes for groundingElectrodes for chemical analysis using electrochemical methodsInert electrodes for electrolysis (made of platinum)Membrane electrode assembly Other than that COPPER ZIRCONIUM [C15000], COPPER NICKEL SILICON CHROMIUM [C18000] can be arranged as per your requirements. Please send us your complete requirements immediately and oblige. With Best Regards, Ms Pragati Sanap, 8928403611, sa...@domadia.com Mr.Rohan Kamble, 8928403617, b...@domadia.com DALI ELECTRONICS, Mumbai, India.
Re: How to insert reference to external symbol in RTL properly?
On Wed, May 29, 2019 at 11:50 PM Arslan Khan wrote: > > Are you suggesting that i insert an extern at source level? Wouldn't > that decrease the usability of the safe stack drastically? Currently > all user has to do is provide an address where we intend to place > shadow stack, but if he has to place extern symbols in all using files > that would be cumbersome. > Besides that even i do that, is there a symbol table maintained by GCC > that i can use to access this in an RTL pass? I'm not suggesting to declare it at source level but you have to create and assemble it, see how tree-profile.c uses build_decl. Richard. > Thanks, > Arslan > > On Wed, May 29, 2019 at 3:17 AM Richard Biener > wrote: > > > > On Tue, May 28, 2019 at 1:01 AM Arslan Khan wrote: > > > > > > Hi, > > > I am a beginner to GCC and am trying to implement safe stack using a > > > GCC Plugin for embedded systems. I am using a cross compiler, with GCC > > > version: > > > > > > arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors > > > 6-2018-q4-major) 6.3.1 20170620 (release) [ARM/embedded-6-branch > > > revision 249437] > > > > > > The shadow stack is placed on a different RAM chip and is protected > > > using software fault isolation (SFI). For SFI i have used a GIMPLE > > > pass, but to save the Link Register in the protected memory i had to > > > use an RTL pass, because FWIU GIMPLE has no notion of registers. Anyhow i > > > am able to generate insn(s) for saving stack pointer to a symbol > > > "shadowStack", created by RTL pass (currently > > > there is no indexing, wanted to start simple). Here's the insn > > > generated for the prologue: > > > > > > (insn 21 2 20 2 (set (reg/f:SI 110) > > > (symbol_ref:SI ("shadowStack") [flags 0x2])) ./test.c:35 -1 > > > (nil)) > > > (insn 20 21 5 2 (set (mem/c:SI (reg/f:SI 110) [0 S4 A32]) > > > (reg:SI 14 lr)) ./test.c:35 -1 > > > (nil)) > > > > > > I have tried to copy what cc1 actually generated for an external > > > reference. The one thing that is different is that there is no > > > information about the variable declaration ins symbol_ref as > > > shadowStack is not defined in source and is purely introduced by the > > > RTL pass. My plan is to provide shadowStack using a library (which in > > > the end version would be an array). I did something similar for GIMPLE > > > pass to call functions in an external library and it worked for me. > > > However when i run it i get the following error message: > > > > > > ./test.c: In function 'iowrite_example': > > > ./test.c:40:1: error: insn does not satisfy its constraints: > > > } > > > ^ > > > (insn 21 2 20 (set (reg/f:SI 110) > > > (symbol_ref:SI ("shadowStack") [flags 0x2])) ./test.c:35 172 > > > {*arm_movsi_insn} > > > (nil)) > > > *** WARNING *** there are active plugins, do not report this as a bug > > > unless you can reproduce it without enabling any plugins. > > > Event| Plugins > > > PLUGIN_ATTRIBUTES | plugin > > > PLUGIN_START_UNIT | plugin > > > PLUGIN_ALL_IPA_PASSES_START | plugin > > > ./test.c:40:1: internal compiler error: in extract_constrain_insn, at > > > recog.c:2190 > > > 0xc8ff4c _fatal_insn(char const*, rtx_def const*, char const*, int, char > > > const*) > > > > > > /home/build/toolchain/gcc-arm-none-eabi-6-2017-q2-update/src/gcc/gcc/rtl-error.c:108 > > > 0xc8ffac _fatal_insn_not_found(rtx_def const*, char const*, int, char > > > const*) > > > > > > /home/build/toolchain/gcc-arm-none-eabi-6-2017-q2-update/src/gcc/gcc/rtl-error.c:119 > > > 0xc3b8e0 extract_constrain_insn(rtx_insn*) > > > > > > /home/build/toolchain/gcc-arm-none-eabi-6-2017-q2-update/src/gcc/gcc/recog.c:2190 > > > 0x104dad2 note_invalid_constants > > > > > > /home/build/toolchain/gcc-arm-none-eabi-6-2017-q2-update/src/gcc/gcc/config/arm/arm.c:17555 > > > 0x104fab3 arm_reorg > > > > > > /home/build/toolchain/gcc-arm-none-eabi-6-2017-q2-update/src/gcc/gcc/config/arm/arm.c:18413 > > > 0xc8a5e6 execute > > > > > > /home/build/toolchain/gcc-arm-none-eabi-6-2017-q2-update/src/gcc/gcc/reorg.c:3952 > > > > > > FWIU these instruction generated are accepted by some RTL templates > > > but the constraints on operands are not satisfied. I tried to debug > > > the constrain_operands function, and is turns out we are trying to > > > match constraints for arm_movsi_insn pattern. So the constraints were: > > > > > > constraints[0]const char *0x1a76cf3 "=rk,r,r,r,rk,m" > > > constraints[1]const char *0x1a76d02 "rk,I,K,j,mi,rk" > > > > > > My guess was that it should've matched second last alternative but it > > > didn't, but i am pretty sure there is nothing wrong with > > > constrain_operands, but something is wrong with the way i generated > > > the reference. Is there any place i can look for on how to do this > > > properly? if required i can share the code here as well for the pass > > > (basically i
Re: About GSOC.
On Thu, May 30 2019, Segher Boessenkool wrote: > On Thu, May 30, 2019 at 07:08:45PM +0200, Martin Jambor wrote: >> Interesting, I was also puzzled for a moment. But notice that: >> >> int main () >> { >> _Float128 x = 18446744073709551617.5f128; >> _Float128 y = __builtin_roundf128 (x); >> } >> >> behaves as expected... the difference is of course the suffix pegged to >> the literal constant (see >> https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Floating-Types.html). >> >> I would also expect GCC to use a larger type if a constant does not fit >> into a double, but apparently that does not happen. I would have to >> check but it is probably the right behavior according to the standard. > > 6.4.4.2/4: "An unsuffixed floating constant has type double." I don't > think your suggestion would be okay? Sorry if I was not clear but I was definitely not suggesting that we change this (or anything). I wrote that I was also surprised but believed that GCC was doing the correct thing. Thanks for pointing out where exactly the standard says what has to be done though. Martin
Re: About GSOC.
Hello. The f128 suffix worked. Based on all the corrections you all pointed out, I have created another patch. I think I took most of the things under consideration but please mention if I missed anything. The following test cases were inspected with this patch. I am not sure if the second test case is supposed to be carried out like I did. Thanks, -Tejas /* { dg-do link } */ extern int link_error (int); #define TEST(FN, VALUE, RESULT) \ if (__builtin_##FN (VALUE) != RESULT) link_error (__LINE__); int main (void) { TEST(roundeven, 0, 0); TEST(roundeven, 0.5, 0); TEST(roundeven, -0.5, 0); TEST(roundeven, 6, 6); TEST(roundeven, -8, -8); TEST(roundeven, 2.5, 2); TEST(roundeven, 3.5, 4); TEST(roundeven, -1.5, -2); TEST(roundeven, 3.499, 3); TEST(roundeven, 3.501, 4); return 0; } second test case : /* { dg-do link } */ /* { dg-add-options float128 } */ /* { dg-require-effective-target float128 } */ extern int link_error (int); #define TEST(FN, VALUE, RESULT) \ if (__builtin_##FN (VALUE) != RESULT) link_error (__LINE__); int main (void) { TEST(roundevenf128, (0x1p64+0.5), (0x1p64)); return 0; } On Fri, 31 May 2019 at 15:41, Martin Jambor wrote: > > On Thu, May 30 2019, Segher Boessenkool wrote: > > On Thu, May 30, 2019 at 07:08:45PM +0200, Martin Jambor wrote: > >> Interesting, I was also puzzled for a moment. But notice that: > >> > >> int main () > >> { > >> _Float128 x = 18446744073709551617.5f128; > >> _Float128 y = __builtin_roundf128 (x); > >> } > >> > >> behaves as expected... the difference is of course the suffix pegged to > >> the literal constant (see > >> https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Floating-Types.html). > >> > >> I would also expect GCC to use a larger type if a constant does not fit > >> into a double, but apparently that does not happen. I would have to > >> check but it is probably the right behavior according to the standard. > > > > 6.4.4.2/4: "An unsuffixed floating constant has type double." I don't > > think your suggestion would be okay? > > Sorry if I was not clear but I was definitely not suggesting that we > change this (or anything). I wrote that I was also surprised but > believed that GCC was doing the correct thing. > > Thanks for pointing out where exactly the standard says what has to be > done though. > > Martin diff --git a/gcc/builtins.c b/gcc/builtins.c index 25e01e4092b..0b2d6bf82f9 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -2067,6 +2067,7 @@ mathfn_built_in_2 (tree type, combined_fn fn) CASE_MATHFN (REMQUO) CASE_MATHFN_FLOATN (RINT) CASE_MATHFN_FLOATN (ROUND) +CASE_MATHFN (ROUNDEVEN) CASE_MATHFN (SCALB) CASE_MATHFN (SCALBLN) CASE_MATHFN (SCALBN) diff --git a/gcc/builtins.def b/gcc/builtins.def index ef89729fd0c..f284a3eae3b 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -542,12 +542,18 @@ DEF_C99_BUILTIN(BUILT_IN_RINTL, "rintl", BT_FN_LONGDOUBLE_LONGDOUBLE, AT #define RINT_TYPE(F) BT_FN_##F##_##F DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_RINT, "rint", RINT_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST) #undef RINT_TYPE +DEF_EXT_LIB_BUILTIN(BUILT_IN_ROUNDEVEN, "roundeven", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN(BUILT_IN_ROUNDEVENF, "roundevenf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN(BUILT_IN_ROUNDEVENL, "roundevenl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) DEF_C99_BUILTIN(BUILT_IN_ROUND, "round", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) DEF_C99_BUILTIN(BUILT_IN_ROUNDF, "roundf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) DEF_C99_BUILTIN(BUILT_IN_ROUNDL, "roundl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) #define ROUND_TYPE(F) BT_FN_##F##_##F DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_ROUND, "round", ROUND_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST) #undef ROUND_TYPE +#define ROUNDEVEN_TYPE(F) BT_FN_##F##_##F +DEF_EXT_LIB_FLOATN_NX_BUILTINS (BUILT_IN_ROUNDEVEN, "roundeven", ROUNDEVEN_TYPE, ATTR_CONST_NOTHROW_LEAF_LIST) +#undef ROUNDEVEN_TYPE DEF_EXT_LIB_BUILTIN(BUILT_IN_SCALB, "scalb", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_EXT_LIB_BUILTIN(BUILT_IN_SCALBF, "scalbf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_EXT_LIB_BUILTIN(BUILT_IN_SCALBL, "scalbl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) diff --git a/gcc/fold-const-call.c b/gcc/fold-const-call.c index 06a420601c0..54315d057a2 100644 --- a/gcc/fold-const-call.c +++ b/gcc/fold-const-call.c @@ -792,6 +792,15 @@ fold_const_call_ss (real_value *result, combined_fn fn, } return false; +CASE_CFN_ROUNDEVEN: +CASE_CFN_ROUNDEVEN_FN: + if (!REAL_VALUE_ISNAN (*arg) || !flag_errno_math) + { +real_roundeven (result, format, arg); +return true; + } + return false; + CASE_CFN_LOGB: return fold_const_logb (result, arg, format);
Re: About GSOC.
On Fri, May 31, 2019 at 12:11:18PM +0200, Martin Jambor wrote: > On Thu, May 30 2019, Segher Boessenkool wrote: > > On Thu, May 30, 2019 at 07:08:45PM +0200, Martin Jambor wrote: > >> Interesting, I was also puzzled for a moment. But notice that: > >> > >> int main () > >> { > >> _Float128 x = 18446744073709551617.5f128; > >> _Float128 y = __builtin_roundf128 (x); > >> } > >> > >> behaves as expected... the difference is of course the suffix pegged to > >> the literal constant (see > >> https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Floating-Types.html). > >> > >> I would also expect GCC to use a larger type if a constant does not fit > >> into a double, but apparently that does not happen. I would have to > >> check but it is probably the right behavior according to the standard. > > > > 6.4.4.2/4: "An unsuffixed floating constant has type double." I don't > > think your suggestion would be okay? > > Sorry if I was not clear but I was definitely not suggesting that we > change this (or anything). I wrote that I was also surprised but > believed that GCC was doing the correct thing. Ah I see. Yeah it tricked me too :-) > Thanks for pointing out where exactly the standard says what has to be > done though. The text doesn't really leave room for extensions, either. Segher
Re: About GSOC.
On 5/30/19 5:38 PM, Segher Boessenkool wrote: On Thu, May 30, 2019 at 07:08:45PM +0200, Martin Jambor wrote: Interesting, I was also puzzled for a moment. But notice that: int main () { _Float128 x = 18446744073709551617.5f128; _Float128 y = __builtin_roundf128 (x); } behaves as expected... the difference is of course the suffix pegged to the literal constant (see https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Floating-Types.html). I would also expect GCC to use a larger type if a constant does not fit into a double, but apparently that does not happen. I would have to check but it is probably the right behavior according to the standard. 6.4.4.2/4: "An unsuffixed floating constant has type double." I don't think your suggestion would be okay? Not only that, but 1) there isn't a literal suffix to mean 'double', so one couldn't override that extended type. 2) how do you define 'doesn't fit'? decimal 0.1 has a recurring binary representation. Should that become the longest floating point type? nathan -- Nathan Sidwell
Re: About GSOC.
On 5/31/19, Nathan Sidwell wrote: > On 5/30/19 5:38 PM, Segher Boessenkool wrote: >> On Thu, May 30, 2019 at 07:08:45PM +0200, Martin Jambor wrote: >>> Interesting, I was also puzzled for a moment. But notice that: >>> >>> int main () >>> { >>> _Float128 x = 18446744073709551617.5f128; >>> _Float128 y = __builtin_roundf128 (x); >>> } >>> >>> behaves as expected... the difference is of course the suffix pegged to >>> the literal constant (see >>> https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Floating-Types.html). >>> >>> I would also expect GCC to use a larger type if a constant does not fit >>> into a double, but apparently that does not happen. I would have to >>> check but it is probably the right behavior according to the standard. >> >> 6.4.4.2/4: "An unsuffixed floating constant has type double." I don't >> think your suggestion would be okay? > > Not only that, but > > 1) there isn't a literal suffix to mean 'double', so one couldn't > override that extended type. There's not a standard one, but there is 'D' or 'd' as a GNU extension. The fact that it's nonstandard, though, is what causes some projects to ignore -Wunsuffixed-float-constants: https://lists.gnu.org/archive/html/bug-gzip/2011-11/msg00017.html > 2) how do you define 'doesn't fit'? decimal 0.1 has a recurring binary > representation. Should that become the longest floating point type? > > nathan > > -- > Nathan Sidwell >
Re: On-Demand range technology [3/5] - The Prototype
On 5/29/19 9:11 AM, Richard Biener wrote: On Tue, May 28, 2019 at 4:41 PM Jeff Law wrote: This aspect of symbolics would be handled by a relational/equivalence processing engine that would be follow on work. Using the same basic model as ranges, each tree code is taught to understand the relation between its operands, and then we can answer equivalency and relational accurately as well. It would be available for any pass to use independent of ranges. I will expound upon that a bit in the future directions section. While I agree that symbolic ranges are a complication and that most cases it currently handles are not "value-range" things I do not agree with the idea that we can simply remove handling them and deal with the fallout in some later point in the future. Eric may also be able to show you "real" symbolic value-range magic. Note that symbolic ranges are already restricted to PLUS_EXPR and MINUS_EXPR (and NEGATE_EXPR I think). There are also "symbolic" (non-integer constant) ranges like [&a, &a]. I've never seen [&a, &MEM[&a + 4]] but we wouldn't reject those I think. You may have noticed that EVRP does not use symbolic ranges. Btw, I probably misremembered this part - it is equivalences that EVRP doesn't use. equivalences are the "other half" of relations besides symbolic ranges. I do get confused by this assertion... From the EVRP dumps : Intersecting int [b_6(D), b_6(D)] EQUIVALENCES: { a_5(D) b_6(D) } (2 elements) and VARYING to int [b_6(D), b_6(D)] EQUIVALENCES: { a_5(D) b_6(D) } (2 elements) Intersecting int [a_5(D), a_5(D)] EQUIVALENCES: { a_5(D) b_6(D) } (2 elements) and VARYING and pushing new range for c_7(D): int [b_6(D), b_6(D)] EQUIVALENCES: { b_6(D) c_7(D) } (2 elements) Visiting stmt if (a_5(D) == c_7(D)) it certainly does seem to have symbolics in the range.. ( [b_6, b_6] ) and it does use equivalencies... presumably thats why its in the range, to help track them.. regardless, thats is how it gets cases we dont right now like if (a == b && b == c) if (a == c) It may not have symbolic expressions like [0, b_6 + 1] as end points like VRP does, or maybe it doesn't resolve them to anything other than varying, but it does appear to have symbolics? Perhaps it resolves them immediately, but it does appear to use some partial bits of the symbolic machinery. We'd like to make this consistent everywhere and track the equivalencies outside of the range via a separate mechanism. As already said I'd like to see VRP go but obstackles are symbolic ranges and jump-threading (with Jeff promising to handle the jump-threading part in the past). Right. FWIW, one of the follow-on items to this work is Aldy's improvements to backwards jump threading which utilizes the ranger framework -- the primary purpose of that work is to eliminate the need for jump threading in VRP. But without relations it won't catch most of the cases... Richard. its catching what it quite a few new things and the relations/equivalencies are coming... I haven't heard of any issues regarding equivalencies, but Aldy's the one that been working with it, so he can speak to it better. Andrew
Re: On-Demand range technology [2/5] - Major Components : How it works
On 5/29/19 7:15 AM, Richard Biener wrote: On Tue, May 28, 2019 at 4:17 PM Andrew MacLeod wrote: On 5/27/19 9:02 AM, Richard Biener wrote: On Fri, May 24, 2019 at 5:50 PM Andrew MacLeod wrote: The above suggests that iff this is done at all it is not in GORI because those are not conditional stmts or ranges from feeding those. The machinery doing the use-def walking from stmt context also cannot come along these so I have the suspicion that Ranger cannot handle telling us that for the stmt following above, for example if (_5 != 0) that _5 is not zero? Can you clarify? So there are 2 aspects to this.the range-ops code for DIV_EXPR, if asked for the range of op2 () would return ~[0,0] for _5. But you are also correct in that the walk backwards would not find this. This is similar functionality to how null_derefs are currently handled, and in fact could probably be done simultaneously using the same code base. I didn't bring null derefs up, but this is a good time :-) There is a separate class used by the gori-cache which tracks the non-nullness property at the block level.It has a single API: non_null_deref_p (name, bb)which determines whether the is a dereference in any BB for NAME, which indicates whether the range has an implicit ~[0,0] range in that basic block or not. So when we then have _1 = *_2; // after this _2 is non-NULL _3 = _1 + 1; // _3 is non-NULL _4 = *_3; ... when a on-demand user asks whether _3 is non-NULL at the point of _4 = *_3 we don't have this information? Since the per-BB caching will only say _1 is non-NULL after the BB. I'm also not sure whether _3 ever gets non-NULL during non-NULL processing of the block since walking immediate uses doesn't really help here? presumably _3 is globally non-null due to the definition being (pointer + x) ... ie, _3 has a global range o f ~[0,0] ? No, _3 is ~[0, 0] because it is derived from _1 which is ~[0, 0] and you cannot arrive at NULL by pointer arithmetic from a non-NULL pointer. I'm confused. _1 was loaded from _2 (thus asserting _2 is non-NULL). but we have no idea what the range of _1 is, so how do you assert _1 is [~0,0] ? The only way I see to determine _3 is non-NULL is through the _4 = *_3 statement. So this seems to be a fundamental limitation [to the caching scheme], not sure if it is bad in practice. Or am I missing something? Not missing anything The non-nullness property is maintains globally at the basic block level. both _1 and _3 are flagged as being non-null in the block. Upon exit, its a bit check. If the global information does not have the non-nullness property, then when a request is made for non-nullness and the def and the use are both within the same block, and its flagged as being non-null in that block, then the request is forced back to a quick walk between the def and the use to see if there is any non-nulless introduced in between. Yes, that makes it a linear walk, but its infrequent, and often short. to the best of our knowledge at this point anyway :-) So with the clarification above do we ever see that _3 is non-NULL? I suppose the worker processing _3 = _1 + 1 would ask for _1 non-nullness but we do not record any non-NULL-ness of _1 in this basic-block (but only at its end). Consider stmts _4 = (uintptr_t) _2; _5 = _6 / _4; _1 = *_2; ... here at _1 we know _2 is not NULL. But if we ask for non-NULLness of _2 at the definition of _4 we may not compute ~[0, 0] and thus conclude that _6 / _4 does not trap. EVRP must look backwards to figure this out since the forward walk will process _5 = _6 / _4 before it sees the dereference to _2... so how does it know that _4 is non-zero without looking backwards at things after it sees the dereference?? Does it actually do this? stmt-level tracking of ranges are sometimes important. This is something the machinery cannot provide - correct? At least not optimistically enough with ranges derived about uses. Maybe I'm the one missing something, but in the absence of statement level exception throwing via 'can_throw_non_call_exceptions' being true, any assertion made anywhere in the block to an ssa_name applies to the entire block does it not? ie it doesn't matter if the deference happens first thing in the block or last thing, its not going to change its value within the block.. its going to be non-null throughout the entire block. so if one statement in the block asserts that references to _2 are non-null, we can assert that all references to _2 in the block are non-null. Meaning we get all these cases by knowing that the specified name is non-zero through-out the block. This also means we could know things earlier in the block than a forward walk would provide. So with the 2 examples: _1 = *_2; // after this _2 is non-NULL _3 = _1 + 1; _4 = *_3; both _2 and _3 are flagged as non-null in the block due to the de-references. Im not sure what we know about _
Re: unrecognizable insn generated in plugin?
On Thu, May 30, 2019 at 9:26 PM Tycho Andersen wrote: > > Hi Andrew, > > On Thu, May 30, 2019 at 10:09:44AM -0700, Andrew Pinski wrote: > > On Thu, May 30, 2019 at 10:01 AM Tycho Andersen wrote: > > > > > > Hi all, > > > > > > I've been trying to implement an idea Andy suggested recently for > > > preventing some kinds of ROP attacks. The discussion of the idea is > > > here: > > > https://lore.kernel.org/linux-mm/dfa69954-3f0f-4b79-a9b5-893d33d87...@amacapital.net/ > > > Hi Tycho, I realise this is maybe not relevant to the topic of fixing the plugin; but I'm struggling to understand what this is intending to protect against. The idea seems to be to make sure that restored rbp, rsp values are "close" to the current rbp, rsp values? The only scenario I can see this providing any benefit is if an attacker can only corrupt a saved stack/frame pointer, which seems like such an unlikely situation that it's not really worth adding any complexity to defend against. An attacker who has control of rip can surely get a controlled value into rsp in various ways; a quick scan of the current Ubuntu 18.04 kernel image offers the following sequence (which shows up everywhere): lea rsp, qword ptr [r10 - 8] ret I'd assume that it's not tremendously difficult for an attacker to chain to this without needing to previously pivot out the stack pointer, assuming that at the point at which they gain control of rip they have control over some state somewhere. If you could explain the exact attack scenario that you have in mind then perhaps I could provide a better explanation of how one might bypass it. Regards, Mark smime.p7s Description: S/MIME Cryptographic Signature
Re: unrecognizable insn generated in plugin?
On Fri, May 31, 2019 at 05:43:44PM +0200, Mark Brand wrote: > On Thu, May 30, 2019 at 9:26 PM Tycho Andersen wrote: > > > > Hi Andrew, > > > > On Thu, May 30, 2019 at 10:09:44AM -0700, Andrew Pinski wrote: > > > On Thu, May 30, 2019 at 10:01 AM Tycho Andersen wrote: > > > > > > > > Hi all, > > > > > > > > I've been trying to implement an idea Andy suggested recently for > > > > preventing some kinds of ROP attacks. The discussion of the idea is > > > > here: > > > > https://lore.kernel.org/linux-mm/dfa69954-3f0f-4b79-a9b5-893d33d87...@amacapital.net/ > > > > > > > Hi Tycho, > > I realise this is maybe not relevant to the topic of fixing the > plugin; but I'm struggling to understand what this is intending to > protect against. > > The idea seems to be to make sure that restored rbp, rsp values are > "close" to the current rbp, rsp values? The only scenario I can see > this providing any benefit is if an attacker can only corrupt a saved > stack/frame pointer, which seems like such an unlikely situation that > it's not really worth adding any complexity to defend against. > An attacker who has control of rip can surely get a controlled value > into rsp in various ways; Yes, if you already have control of rip this doesn't help you. > a quick scan of the current Ubuntu 18.04 > kernel image offers the following sequence (which shows up > everywhere): > > lea rsp, qword ptr [r10 - 8] > ret > > I'd assume that it's not tremendously difficult for an attacker to > chain to this without needing to previously pivot out the stack > pointer, assuming that at the point at which they gain control of rip > they have control over some state somewhere. If you could explain the > exact attack scenario that you have in mind then perhaps I could > provide a better explanation of how one might bypass it. The core bit that's important here is the writes to rsp/rbp, not the fact that they're pop instructions. The insight is that we know how the thread's stack should be aligned, and so any value that's written to these registers outside of that alignment (during "normal" execution) is a bug. The idea is that a ROP attack requires a payload to be injected somewhere so that it can return to this payload and execute this attack. This is most probably done via some allocation elsewhere (add_key() or unreceived data or whatever) since as you note, the stack should be mostly well protected. So then, if we don't allow anyone to write anything that's not on the stack to rsp/rbp, in principle we should be safe from ROP attacks where the payload is elsewhere. As you note, preventing bad "pop rpb" instructions is not enough, nor is preventing bad "pop rsp", as Andy initially proposed. We need to prevent all bad writes to these registers, including the sequence you mentioned, and presumably others. So there would need to be a lot more matching and checks inserted, and maybe it would ultimately be slow. Right now I just wanted to play with it for a bit to see if I can get it to work at all even in one case :) Am I thinking about this wrong? Any discussion is welcome, thanks! Tycho
Re: On-Demand range technology [2/5] - Major Components : How it works
On 5/31/19 9:40 AM, Andrew MacLeod wrote: > On 5/29/19 7:15 AM, Richard Biener wrote: >> On Tue, May 28, 2019 at 4:17 PM Andrew MacLeod >> wrote: >>> On 5/27/19 9:02 AM, Richard Biener wrote: On Fri, May 24, 2019 at 5:50 PM Andrew MacLeod wrote: >> The above suggests that iff this is done at all it is not in GORI >> because >> those are not conditional stmts or ranges from feeding those. The >> machinery doing the use-def walking from stmt context also cannot >> come along these so I have the suspicion that Ranger cannot handle >> telling us that for the stmt following above, for example >> >> if (_5 != 0) >> >> that _5 is not zero? >> >> Can you clarify? > So there are 2 aspects to this. the range-ops code for DIV_EXPR, if > asked for the range of op2 () would return ~[0,0] for _5. > But you are also correct in that the walk backwards would not find > this. > > This is similar functionality to how null_derefs are currently > handled, > and in fact could probably be done simultaneously using the same code > base. I didn't bring null derefs up, but this is a good time :-) > > There is a separate class used by the gori-cache which tracks the > non-nullness property at the block level. It has a single API: > non_null_deref_p (name, bb) which determines whether the is a > dereference in any BB for NAME, which indicates whether the range > has an > implicit ~[0,0] range in that basic block or not. So when we then have _1 = *_2; // after this _2 is non-NULL _3 = _1 + 1; // _3 is non-NULL _4 = *_3; ... when a on-demand user asks whether _3 is non-NULL at the point of _4 = *_3 we don't have this information? Since the per-BB caching will only say _1 is non-NULL after the BB. I'm also not sure whether _3 ever gets non-NULL during non-NULL processing of the block since walking immediate uses doesn't really help here? >>> presumably _3 is globally non-null due to the definition being (pointer >>> + x) ... ie, _3 has a global range o f ~[0,0] ? >> No, _3 is ~[0, 0] because it is derived from _1 which is ~[0, 0] and >> you cannot arrive at NULL by pointer arithmetic from a non-NULL pointer. > > I'm confused. > > _1 was loaded from _2 (thus asserting _2 is non-NULL). but we have no > idea what the range of _1 is, so how do you assert _1 is [~0,0] ? > The only way I see to determine _3 is non-NULL is through the _4 = *_3 > statement. Likewise. I don't see how we get ~[0,0] for _1, except at the point after the dereference of _3. So this seems to be a fundamental limitation [to the caching scheme], not sure if it is bad in practice. Or am I missing something? >>> Not missing anything The non-nullness property is maintains globally at >>> the basic block level. both _1 and _3 are flagged as being non-null in >>> the block. Upon exit, its a bit check. If the global information does >>> not have the non-nullness property, then when a request is made for >>> non-nullness and the def and the use are both within the same block, >>> and its flagged as being non-null in that block, then the request is >>> forced back to a quick walk between the def and the use to see if there >>> is any non-nulless introduced in between. Yes, that makes it a linear >>> walk, but its infrequent, and often short. to the best of our knowledge >>> at this point anyway :-) >> So with the clarification above do we ever see that _3 is non-NULL? >> I suppose the worker processing _3 = _1 + 1 would ask for >> _1 non-nullness but we do not record any non-NULL-ness of _1 in >> this basic-block (but only at its end). Consider stmts >> >> _4 = (uintptr_t) _2; >> _5 = _6 / _4; >> _1 = *_2; >> ... >> >> here at _1 we know _2 is not NULL. But if we ask for non-NULLness >> of _2 at the definition of _4 we may not compute ~[0, 0] and thus >> conclude that _6 / _4 does not trap. > EVRP must look backwards to figure this out since the forward walk will > process _5 = _6 / _4 before it sees the dereference to _2... so how does > it know that _4 is non-zero without looking backwards at things after it > sees the dereference?? Does it actually do this? During the forward walk we process the assignment to _5, which is _6 / _4. We can infer that _4 is nonzero because division by zero is undefined behavior. But I'm not sure how EVRP would go back and then make a determination about _4 unless it's doing so via an equivalence. > >> >> stmt-level tracking of ranges are sometimes important. This is >> something the machinery cannot provide - correct? At least not >> optimistically enough with ranges derived about uses. > > Maybe I'm the one missing something, but in the absence of statement > level exception throwing via 'can_throw_non_call_exceptions' being true, > any assertion made anywhere in the bloc
Re: On-Demand range technology [2/5] - Major Components : How it works
On 5/31/19 2:16 PM, Jeff Law wrote: On 5/31/19 9:40 AM, Andrew MacLeod wrote: On 5/29/19 7:15 AM, Richard Biener wrote: On Tue, May 28, 2019 at 4:17 PM Andrew MacLeod wrote: On 5/27/19 9:02 AM, Richard Biener wrote: On Fri, May 24, 2019 at 5:50 PM Andrew MacLeod wrote: The above suggests that iff this is done at all it is not in GORI because those are not conditional stmts or ranges from feeding those. The machinery doing the use-def walking from stmt context also cannot come along these so I have the suspicion that Ranger cannot handle telling us that for the stmt following above, for example if (_5 != 0) that _5 is not zero? Can you clarify? So there are 2 aspects to this. the range-ops code for DIV_EXPR, if asked for the range of op2 () would return ~[0,0] for _5. But you are also correct in that the walk backwards would not find this. This is similar functionality to how null_derefs are currently handled, and in fact could probably be done simultaneously using the same code base. I didn't bring null derefs up, but this is a good time :-) There is a separate class used by the gori-cache which tracks the non-nullness property at the block level. It has a single API: non_null_deref_p (name, bb) which determines whether the is a dereference in any BB for NAME, which indicates whether the range has an implicit ~[0,0] range in that basic block or not. So when we then have _1 = *_2; // after this _2 is non-NULL _3 = _1 + 1; // _3 is non-NULL _4 = *_3; ... when a on-demand user asks whether _3 is non-NULL at the point of _4 = *_3 we don't have this information? Since the per-BB caching will only say _1 is non-NULL after the BB. I'm also not sure whether _3 ever gets non-NULL during non-NULL processing of the block since walking immediate uses doesn't really help here? presumably _3 is globally non-null due to the definition being (pointer + x) ... ie, _3 has a global range o f ~[0,0] ? No, _3 is ~[0, 0] because it is derived from _1 which is ~[0, 0] and you cannot arrive at NULL by pointer arithmetic from a non-NULL pointer. I'm confused. _1 was loaded from _2 (thus asserting _2 is non-NULL). but we have no idea what the range of _1 is, so how do you assert _1 is [~0,0] ? The only way I see to determine _3 is non-NULL is through the _4 = *_3 statement. Likewise. I don't see how we get ~[0,0] for _1, except at the point after the dereference of _3. So this seems to be a fundamental limitation [to the caching scheme], not sure if it is bad in practice. Or am I missing something? Not missing anything The non-nullness property is maintains globally at the basic block level. both _1 and _3 are flagged as being non-null in the block. Upon exit, its a bit check. If the global information does not have the non-nullness property, then when a request is made for non-nullness and the def and the use are both within the same block, and its flagged as being non-null in that block, then the request is forced back to a quick walk between the def and the use to see if there is any non-nulless introduced in between. Yes, that makes it a linear walk, but its infrequent, and often short. to the best of our knowledge at this point anyway :-) So with the clarification above do we ever see that _3 is non-NULL? I suppose the worker processing _3 = _1 + 1 would ask for _1 non-nullness but we do not record any non-NULL-ness of _1 in this basic-block (but only at its end). Consider stmts _4 = (uintptr_t) _2; _5 = _6 / _4; _1 = *_2; ... here at _1 we know _2 is not NULL. But if we ask for non-NULLness of _2 at the definition of _4 we may not compute ~[0, 0] and thus conclude that _6 / _4 does not trap. EVRP must look backwards to figure this out since the forward walk will process _5 = _6 / _4 before it sees the dereference to _2... so how does it know that _4 is non-zero without looking backwards at things after it sees the dereference?? Does it actually do this? During the forward walk we process the assignment to _5, which is _6 / _4. We can infer that _4 is nonzero because division by zero is undefined behavior. But I'm not sure how EVRP would go back and then make a determination about _4 unless it's doing so via an equivalence. stmt-level tracking of ranges are sometimes important. This is something the machinery cannot provide - correct? At least not optimistically enough with ranges derived about uses. Maybe I'm the one missing something, but in the absence of statement level exception throwing via 'can_throw_non_call_exceptions' being true, any assertion made anywhere in the block to an ssa_name applies to the entire block does it not? ie it doesn't matter if the deference happens first thing in the block or last thing, its not going to change its value within the block.. its going to be non-null throughout the entire block. No, I don't think it can hold for the entire block. Consider x = p ? 10 : 20; foo (x) *p = wh
Re: On-Demand range technology [2/5] - Major Components : How it works
On 5/31/19 2:26 PM, Andrew MacLeod wrote: > On 5/31/19 2:16 PM, Jeff Law wrote: >> On 5/31/19 9:40 AM, Andrew MacLeod wrote: stmt-level tracking of ranges are sometimes important. This is something the machinery cannot provide - correct? At least not optimistically enough with ranges derived about uses. >>> Maybe I'm the one missing something, but in the absence of statement >>> level exception throwing via 'can_throw_non_call_exceptions' being true, >>> any assertion made anywhere in the block to an ssa_name applies to the >>> entire block does it not? ie it doesn't matter if the deference >>> happens first thing in the block or last thing, its not going to change >>> its value within the block.. its going to be non-null throughout the >>> entire block. >> No, I don't think it can hold for the entire block. >> >> Consider >> >> x = p ? 10 : 20; >> foo (x) >> *p = whatever >> >> We don't know p is non-null because foo might not return. If by way of >> the dereference we were to assert p is non-null for the entire block, >> then we'd pass the wrong value to foo(). >> >> Jeff >> > > Interesting. I started wondering about calls when I was talking about > non-call exceptions, but couldn't think of an example off the top of my > head. > > OK, so the statement holds true for any section of code without calls in > it. If the block is marked as having a non-null deref in it, I need to > look at statement in between the relevant def and use to see if there is > an impact rather than just checking the flag. If the flag is false, we > need to do nothing else. What about in a multi-threaded application? No calls here x = p ? 10 : 20; sharedvar = x; [ bunch of straightline code] *p = Our thread gets preempted and for some reason never restarts? Another thread could read sharedvar and get the wrong value? But one might argue we have similar problems in other places where we "back propagate" non-nullness. I'm thinking about cases where the pointer is passed to a function in an argument slot marked as non-null. We mark the name as currently having a non-null value and it can get back propagated around in rather surprising ways and we've been called out on it. Dunno... Probably worth mulling over some more... Jeff
gcc-8-20190531 is now available
Snapshot gcc-8-20190531 is now available on ftp://gcc.gnu.org/pub/gcc/snapshots/8-20190531/ and on various mirrors, see http://gcc.gnu.org/mirrors.html for details. This snapshot has been generated from the GCC 8 SVN branch with the following options: svn://gcc.gnu.org/svn/gcc/branches/gcc-8-branch revision 271827 You'll find: gcc-8-20190531.tar.xzComplete GCC SHA256=aff01149570fb4c0616ce60487b4274b269934cb1f81ddc977e45e810bf2357e SHA1=fcceb0bb9274d9976aa1a20d2ffd47828dda3885 Diffs from 8-20190524 are available in the diffs/ subdirectory. When a particular snapshot is ready for public consumption the LATEST-8 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.
Re: On-Demand range technology [2/5] - Major Components : How it works
On 5/31/19 6:00 PM, Jeff Law wrote: On 5/31/19 2:26 PM, Andrew MacLeod wrote: On 5/31/19 2:16 PM, Jeff Law wrote: On 5/31/19 9:40 AM, Andrew MacLeod wrote: stmt-level tracking of ranges are sometimes important. This is something the machinery cannot provide - correct? At least not optimistically enough with ranges derived about uses. Maybe I'm the one missing something, but in the absence of statement level exception throwing via 'can_throw_non_call_exceptions' being true, any assertion made anywhere in the block to an ssa_name applies to the entire block does it not? ie it doesn't matter if the deference happens first thing in the block or last thing, its not going to change its value within the block.. its going to be non-null throughout the entire block. No, I don't think it can hold for the entire block. Consider x = p ? 10 : 20; foo (x) *p = whatever We don't know p is non-null because foo might not return. If by way of the dereference we were to assert p is non-null for the entire block, then we'd pass the wrong value to foo(). Jeff Interesting. I started wondering about calls when I was talking about non-call exceptions, but couldn't think of an example off the top of my head. OK, so the statement holds true for any section of code without calls in it. If the block is marked as having a non-null deref in it, I need to look at statement in between the relevant def and use to see if there is an impact rather than just checking the flag. If the flag is false, we need to do nothing else. What about in a multi-threaded application? No calls here x = p ? 10 : 20; sharedvar = x; [ bunch of straightline code] *p = Our thread gets preempted and for some reason never restarts? Another thread could read sharedvar and get the wrong value? oh we're getting into the weeds :-) the program dies if *p ever gets executed and p is NULL. so if we write shardedvar = 10 because we know this, does that make the program wrong if p is NULL? I dunno. maybe I suppose some other thread starts doing something when it sees 20 and knows this one is going to die.. and now it wont know its going to die. What a screwed up program :-). But one might argue we have similar problems in other places where we "back propagate" non-nullness. I'm thinking about cases where the pointer is passed to a function in an argument slot marked as non-null. We mark the name as currently having a non-null value and it can get back propagated around in rather surprising ways and we've been called out on it. Dunno... Probably worth mulling over some more... Jeff yeah, we may not be able to optimistically back propagate. I was thinking about it, and what happens if you tried to push that non-nullness back into previous blocks. you can get into trouble quickly :-) so it does seem like it might be important to maintain the temporal integrity of a range when any kind of inferred knowledge like *p or /x is applied to it. This is not a pressing issue yet since we arent trying to immediately integrate the on-demand engine. I'll mull it over some more, but we may be able to do some processing for blocks in which there is an issue with non-zeroness as needed.. And the fallback to fully enumerate and forward process any block affected should certainly work and not cost more than the current mechanism which does the same thing. Andrew