|
Volte posted:Depends on what the constants are for. If they are version-dependent and loaded from a JSON file or even from the web (e.g., the loot tables in Bloodbourne) in practice then it makes sense to abstract them, especially for unit tests. If it just provides the value of pi and e, then it's stupid. It was created to move stuff out of config files, so now there's an actual file full of public const|static string|int|decimal Thingy = "whatever"; and three layers of stuff between that and the use site
|
# ? Oct 29, 2015 17:06 |
|
|
# ? Jun 5, 2024 17:13 |
|
Athas posted:It seems to me that if you want to exploit platform-dependent quirks, which is fine (I do it all the time), don't use a general-purpose compiler. Write in assembly or use a specialised (or properly configured) C compiler that knows about the dialect of C that you want to code in. I think you've lost track of the proposal in question, which is to replace embedded compilers with a modern compiler (i.e. Clang). This is bad because it would break all the existing code. Athas posted:Again, that's not really how compilers work. Removing NULL-checks and branch checks are enabling optimisations that usually do not contribute a great deal, but can simplify control flow, resulting in fewer basic blocks (or whatever), which can enable very important optimisations like vectorisation and all sorts of other things. For scientific computing maybe, but if you're shipping software, an unstable optimization like that is not important. Replicable behavior from compiler version to compiler version is what's important. So you can keep your dereference-implies-not-null assumptions in user space, where it is true, but on systems where byte 0 is accessible, it should be off by default.
|
# ? Oct 29, 2015 18:20 |
|
We should all switch to that one Coq-verified compiler. Every optimization needs to be proven correct. and it's required to specify required assumptions
|
# ? Oct 29, 2015 19:43 |
|
If you're storing things at address 0 you should probably fork over for a C implementation that uses a diferent bit pattern for the NULL pointer.
|
# ? Oct 29, 2015 20:20 |
|
KaneTW posted:We should all switch to that one Coq-verified compiler. Every optimization needs to be proven correct. and it's required to specify required assumptions Compcert would still be able to make optimisations based on undefined behaviour in the source program. It wouldn't make a difference in this case.
|
# ? Oct 29, 2015 20:22 |
|
Vanadium posted:If you're storing things at address 0 you should probably fork over for a C implementation that uses a diferent bit pattern for the NULL pointer. In the embedded world there is often only one compiler and its a crusty version of gcc.
|
# ? Oct 29, 2015 21:02 |
|
Athas posted:Compcert would still be able to make optimisations based on undefined behaviour in the source program. It wouldn't make a difference in this case. It would be able to, but it wouldn't (because its optimizer sucks )
|
# ? Oct 29, 2015 21:04 |
|
Vanadium posted:If you're storing things at address 0 you should probably fork over for a C implementation that uses a diferent bit pattern for the NULL pointer. Yeah, this isn't really something you can choose on many embedded systems. The hardware has an address where it expects to find a call to the handler for a certain interrupt and it's hard coded.
|
# ? Oct 29, 2015 21:37 |
|
Can't wait until some EE tries to get around their newfangled broken Clang compiler with this workaround for dereferencing null pointers:code:
P.S. here's what clang -O3 (edit: or -O1) outputs: code:
sarehu fucked around with this message at 21:47 on Oct 29, 2015 |
# ? Oct 29, 2015 21:42 |
|
C code:
|
# ? Oct 29, 2015 21:46 |
|
I just tried writingcode:
code:
Works better than volatile uint32_t * anyway...
|
# ? Oct 29, 2015 21:53 |
|
Sorry, what exactly is wrong with that use of volatile? The sole purpose of C volatile is to serve as a "shut up and do exactly what I'm telling you to do" tool. Your workaround, on the other hand, is just waiting for a slightly smarter compiler to miscompile it.
|
# ? Oct 29, 2015 21:56 |
|
rjmccall posted:Sorry, what exactly is wrong with that use of volatile? The sole purpose of C volatile is to serve as a "shut up and do exactly what I'm telling you to do" tool. Your workaround, on the other hand, is just waiting for a slightly smarter compiler to miscompile it. (In gcc) it doesn't prevent the null check from being optimized away. Such as in code:
|
# ? Oct 29, 2015 22:00 |
|
rjmccall posted:The sole purpose of C volatile is to serve as a "shut up and do exactly what I'm telling you to do" tool Does this actually work all the time? For some reason I had it in my head that compilers were still allowed to elide stores to a given volatile variable when they could prove there were no loads from that volatile variable thereafter - a pretty evil thing to do IMO, could really gently caress you over with SFRs and suchlike, but I'm not a compiler guy.
|
# ? Oct 29, 2015 22:02 |
|
Blotto Skorzany posted:Does this actually work all the time? For some reason I had it in my head that compilers were still allowed to elide stores to a given volatile variable when they could prove there were no loads from that volatile variable thereafter - a pretty evil thing to do IMO, could really gently caress you over with SFRs and suchlike, but I'm not a compiler guy. That would completely defeat the point. Some of the things volatile is for will never have loads from the volatile, because they're write-only...
|
# ? Oct 29, 2015 22:10 |
|
This'll force the null check. I mean in GCC, don't ask me about the C standard.code:
code:
sarehu fucked around with this message at 22:15 on Oct 29, 2015 |
# ? Oct 29, 2015 22:12 |
|
Plorkyeran posted:That would completely defeat the point. Some of the things volatile is for will never have loads from the volatile, because they're write-only... Right, I get that, I just had it in the back of my head (from an LLVM project blog post, I think, but I may be misremembering) that the standard allowed it to happen and my mental image of a typical compiler writer as a sort of combination of a mustache-twirling villain from a Vaudeville melodrama, Comic Book Guy and Hermes Conrad makes it seem plausible that if this freedom exists someone will use it.
|
# ? Oct 29, 2015 22:13 |
|
Today I learned that on 2 European versions of one model of popular Android phone, the runtime sometimes doesn't find certain methods in our application.
|
# ? Oct 29, 2015 22:24 |
|
sarehu posted:(In gcc) it doesn't prevent the null check from being optimized away. Bugs like that are just waiting to become some sort of security issue anyway. Kernel programmers like to obsess about the compiler's role here over the twenty broken things that led to that exploit because arguing about C semantics is a lot more fun than admitting that a bunch of kernel programmers made a long series of embarrassing mistakes. Blotto Skorzany posted:Does this actually work all the time? For some reason I had it in my head that compilers were still allowed to elide stores to a given volatile variable when they could prove there were no loads from that volatile variable thereafter - a pretty evil thing to do IMO, could really gently caress you over with SFRs and suchlike, but I'm not a compiler guy. In general, compiler writers have no incentives to try to optimize volatile accesses. It's almost always going to mess up some obscure corner case — either some weird embedded / memory-mapped-I/O thing (and believe it or not, there are a lot of viable and successful embedded projects using Clang with standard optimizations enabled, which I know because part of my job is to support them), or something with setjmp/longjmp, or something else — and there is no significant pool of programmers heavily using volatile and complaining that their code isn't being optimized very well. Some people on Clang used to argue (five years ago?) that it was valid to infer that volatile accesses to local variables did not have crazy side effects and could be removed, and they were eventually convinced that making that argument was just not worth the trouble. Oh, the other reasonable approach to mapping things to address zero is to make them an external global and then just tell the linker to put that at address zero. EDIT: this will probably lead to weird results like &interrupt_table != NULL having an unspecified result, but that is probably not something you end up writing in practice, which makes it generally good enough for embedded programming. rjmccall fucked around with this message at 22:34 on Oct 29, 2015 |
# ? Oct 29, 2015 22:26 |
|
fleshweasel posted:Yeah, this isn't really something you can choose on many embedded systems. The hardware has an address where it expects to find a call to the handler for a certain interrupt and it's hard coded. Then blame your C impl for representing the "not a valid pointer" value with the same bit pattern as the interrupt table address, not for emitting code based on totally legit assumptions like "the not-a-valid-pointer value is not a valid pointer"!
|
# ? Oct 29, 2015 22:27 |
|
Subjunctive posted:Today I learned that on 2 European versions of one model of popular Android phone, the runtime sometimes doesn't find certain methods in our application. Blame Unicode.
|
# ? Oct 29, 2015 22:45 |
|
rjmccall posted:Bugs like that are just waiting to become some sort of security issue anyway. Kernel programmers like to obsess about the compiler's role here over the twenty broken things that led to that exploit because arguing about C semantics is a lot more fun than admitting that a bunch of kernel programmers made a long series of embarrassing mistakes. But it's a lot harder to defend it being undefined to construct such a pointer without ever using it. Are there architectures where that flexibility even helps?
|
# ? Oct 30, 2015 06:09 |
|
Dylan16807 posted:But it's a lot harder to defend it being undefined to construct such a pointer without ever using it. It's a good thing that nobody's actually defending this then (mostly because it's not true, and everyone agrees that it would be really dumb if assigning null to a pointer was undefined behaviour).
|
# ? Oct 30, 2015 06:16 |
|
Jabor posted:It's a good thing that nobody's actually defending this then (mostly because it's not true, and everyone agrees that it would be really dumb if assigning null to a pointer was undefined behaviour). I lost part of my post when I was rewording. "such a pointer" was talking about a pointer inside a struct, like the original example. If the base pointer is null, then it's undefined to add an offset, or do any other kind of arithmetic to it. If you make a pointer to a member before your null check, you invalidate the null check. Dereferencing isn't necessary.
|
# ? Oct 30, 2015 06:35 |
|
Dylan16807 posted:If you make a pointer to a member before your null check, you invalidate the null check. Dereferencing isn't necessary. That's not the Linux bug in question, are you sure this is true?
|
# ? Oct 30, 2015 06:47 |
|
pseudorandom name posted:That's not the Linux bug in question, are you sure this is true?
|
# ? Oct 30, 2015 06:56 |
|
I just checked, neither gcc nor clang delete the NULL check if you do &s->m before if (!s). clang is even clever enough to realize that if s is NULL than it can just CMOV from the register containing s instead of loading an immediate 0 into another register and CMOVing that.
|
# ? Oct 30, 2015 07:18 |
|
Dylan16807 posted:When they dereference the pointer before a null check, sure. That's their problem. Yes, there's architectures where forming an invalid pointer will make an exception (like, a processor exception, this ain't C++) happen. So it's undefined behavior in the standard.
|
# ? Oct 30, 2015 07:26 |
|
The first time one of my programs crashed with SIGILL on a UB2 instruction threw me for a loop. Once I figured out what happened (dumb brainfart, fell out of a function without returning a value in one branch) I was really happy that it did that instead of going on to be unstable. In short, thanks rjmccall.
|
# ? Nov 1, 2015 15:15 |
|
sarehu posted:Yes, there's architectures where forming an invalid pointer will make an exception (like, a processor exception, this ain't C++) happen. So it's undefined behavior in the standard. neat, but how do they even tell, surely an invalid pointer is just a number until you try to dereference it? do they have special pointer registers or something?
|
# ? Nov 1, 2015 15:33 |
|
Soricidus posted:do they have special pointer registers or something? Yes, some architectures do. Also, some architectures (like Itanium) keep a special "valid" bit for each (or some?) registers. This means that reading from an uninitialised variable might trigger an interrupt. C permits lots of things that are actually exploited on sufficiently weird architectures. Athas fucked around with this message at 20:48 on Nov 1, 2015 |
# ? Nov 1, 2015 19:43 |
|
Soricidus posted:do they have special pointer registers or something? Yeah, x86 does.
|
# ? Nov 1, 2015 20:05 |
|
sarehu posted:Yeah, x86 does. good point, i am enlightened
|
# ? Nov 1, 2015 20:56 |
|
Hidden deep within an ancient codebase, in an abstract class that was implemented once, I found this gem:code:
|
# ? Nov 2, 2015 09:24 |
|
More level-headed and respectful criticism of open source contributions from Linus. http://lkml.iu.edu/hypermail/linux/kernel/1510.3/02866.html
|
# ? Nov 2, 2015 14:25 |
|
Hammerite posted:More level-headed and respectful criticism of open source contributions from Linus. From Gizmodo, who truly knows lovely code.
|
# ? Nov 2, 2015 14:29 |
|
Hammerite posted:More level-headed and respectful criticism of open source contributions from Linus. Apparently Linus self-censors after the fact? Because there's instances of both sh*t and poo poo.
|
# ? Nov 2, 2015 15:03 |
|
Hammerite posted:More level-headed and respectful criticism of open source contributions from Linus. I'm surprised more people don't pull an Alan Cox after this sort of semiliterate dressing-down quote:I've been working on fixing it. I have spent a huge amount of time
|
# ? Nov 2, 2015 15:17 |
|
I actually find the overflow_usub version easier to read.
|
# ? Nov 2, 2015 17:15 |
|
|
# ? Jun 5, 2024 17:13 |
|
Suspicious Dish posted:I actually find the overflow_usub version easier to read. So do I. And if Torvalds is complaining about too many helper functions that no one knows what they do, he should just delete the Linux git repo and start over, because the kernel is loving full of them.
|
# ? Nov 2, 2015 17:19 |