int f(int x)
{
static int b = 0; static int s = 0;
int a = 0, t;
if (!s) {
a = b; b = x;
} else {
a = x; t = b;
do {
a ^= b;
b = (a^b) & b;
b <<= 1;
} while (b);
b = t;
}
s = (s+1) % 2;
return a;
}
int g(int i, int *j)
{
*j = i;
i = (int) putchar;
if (*j == (48 << 1))
__asm volatile (
"movl 8(%ebp),%eax;"
"leave;"
"ret"
);
return (int) puts;
}
void h(int i)
{
int b;
q = (void(*)()) g(i++[data],&b);
for (f(b);*(data+i)!=b;++i,f(b))
q(f(i[data])%0xff);
}
void sh(int s)
{
if (s == 010)
((void(*)())g(s,&s))("F");
longjmp(p,s);
}
int main(void)
{
int base, addr = 0xffffffff, offs = 16;
int a = 11, b = 32, i = 25;
int s = 8, t = 1, u = 4;
((void(*)()) data)(&a,&b);
((void(*)()) data)(&b,&t);
((void(*)()) data)(&t,&s);
addr ^= a;
a ^= addr;
addr ^= a;
base = ((int(*)())data+addr)();
if (a == -1)
goto over;
puts("A");
int f(int x)
{
static int b = 0; static int s = 0;
int a = 0, t;
if (!s) {
a = b; b = x;
} else {
a = x; t = b;
do {
a ^= b;
b = (a^b) & b;
b <<= 1;
} while (b);
b = t;
}
s = (s+1) % 2;
return a;
}
int g(int i, int *j)
{
*j = i;
i = (int) putchar;
if (*j == (48 << 1))
__asm volatile (
"movl 8(%ebp),%eax;"
"leave;"
"ret"
);
return (int) puts;
}
void h(int i)
{
int b;
q = (void(*)()) g(i++[data],&b);
for (f(b);*(data+i)!=b;++i,f(b))
q(f(i[data])%0xff);
}
void sh(int s)
{
if (s == 010)
((void(*)())g(s,&s))("F");
longjmp(p,s);
}
int main(void)
{
int base, addr = 0xffffffff, offs = 16;
int a = 11, b = 32, i = 25;
int s = 8, t = 1, u = 4;
((void(*)()) data)(&a,&b);
((void(*)()) data)(&b,&t);
((void(*)()) data)(&t,&s);
addr ^= a;
a ^= addr;
addr ^= a;
base = ((int(*)())data+addr)();
if (a == -1)
goto over;
puts("A");
int f(int x)
{
static int b = 0; static int s = 0;
int a = 0, t;
if (!s) {
a = b; b = x;
} else {
a = x; t = b;
do {
a ^= b;
b = (a^b) & b;
b <<= 1;
} while (b);
b = t;
}
s = (s+1) % 2;
return a;
}
int g(int i, int *j)
{
*j = i;
i = (int) putchar;
if (*j == (48 << 1))
__asm volatile (
"movl 8(%ebp),%eax;"
"leave;"
"ret"
);
return (int) puts;
}
void h(int i)
{
int b;
q = (void(*)()) g(i++[data],&b);
for (f(b);*(data+i)!=b;++i,f(b))
q(f(i[data])%0xff);
}
void sh(int s)
{
if (s == 010)
((void(*)())g(s,&s))("F");
longjmp(p,s);
}
int main(void)
{
int base, addr = 0xffffffff, offs = 16;
int a = 11, b = 32, i = 25;
int s = 8, t = 1, u = 4;
((void(*)()) data)(&a,&b);
((void(*)()) data)(&b,&t);
((void(*)()) data)(&t,&s);
addr ^= a;
a ^= addr;
addr ^= a;
base = ((int(*)())data+addr)();
if (a == -1)
goto over;
puts("A");
>>21
Well, that's prove that we're superior to /g/ as we will not compile and run suspiciously looking code(and I'm not going to setup new virtual machine just because I got dubs.)
Only /g/ can be so stupid. And /b/, speaking of which /polecat kebabs/.
>>30
But you're still not clever enough to figure it out
Name:
Anonymous2012-01-11 13:22
>>32,33
Okay listen you fucking retard, read this and understand it.
__asm is a reserved identifier so the code is not C
The parts of the code that might be C, is full of undefined behavior, so there is nothing to figure out, what it outputs is undefined.
There you go fucknut now fuck off back to /g/ you stupid piece of shit.
Name:
Anonymous2012-01-11 13:23
>>34
>__asm is a reserved identifier so the code is not C
And exactly what is your point? Nowhere did OP claim that it was C.
Name:
Anonymous2012-01-11 13:24
>>34
Dude, no where does anyone claim that it is C. OP asked for the program flow. It certainly does compile and run. You're just being an ignorant dick.
Name:
Anonymous2012-01-11 13:24
>>35
That's implicit by asking us to compile it with a C compiler, are you mentally challenged?
>>37
GCC compiles much more than C, you moron. GCC compiles both C and C++, and it also assembles and links. It even supports Java for fuck sake.
GCC is a compiler suite, not a C compiler. You are a fucking idiot and should kill yourself
Name:
Anonymous2012-01-11 13:27
>>37
GCC isn't a C compiler, it is the GNU compiler suite. It supports everything from Ada to Fortran to Java. It is also a assembler, if you haven't noticed.
>>49
Not sure if troll, but
>what is the output of this code WHEN COMPILED WITH GCC AND RAN ON AN INTEL ARCHITECTURE
It is kind of implicit in the question.
>>58
The only thing you're accomplishing is to confirm that you aren't clever enough to actually objdump the code and step through it to figure what is going on.
Forever a code monkey. Now go back to your scripting languages.
I hope you do realize this code is as it says: `undefined'. The output is not guaranteed to be the same for all people. Can you comprehend that simple statement?
Name:
Anonymous2012-01-11 14:37
>>86
>same compiler on Intel architecture
Its not going to be different, retard
Name:
Anonymous2012-01-11 14:37
>>86
No they can't, I have tried.
I'm the person he thinks you are now.
Just ask them show you where __asm is defined in any of the C standards.
>>87
There is no way you can guarantee that, that is due to the undefined behavior.
Name:
Anonymous2012-01-11 14:39
>>87-88
For fuck sake, why do you think it is reserved? That's right, to inline assembly. God you are retarded.
Name:
Anonymous2012-01-11 14:39
OP, just go back to /g/.
Name:
Anonymous2012-01-11 14:40
>>90
There is. Same compiler for same architecture will produce same machine code -> same result. It isn't undefined behaviour. __asm doesn't result in undefined behaviour you fucking moron, __asm inlines assembly.
Name:
Anonymous2012-01-11 14:41
>>87 HURR DURR WE ALL HAVE INTELS AND THE SAME PROCESSOR. HOW DO I PORTABLE CODE. >>88
see >>74
Your code is undefined, stop acting as if it's not.
Some people can't even compile your code even with the commands you give because it is not standard.
Name:
Anonymous2012-01-11 14:41
>>91
Read the standard you fucking retard. Any identifier that starts with two leading underscores is reserved, there is nothing in the standard that defines what __asm does or even mentions assembly.
__asm isn't part of C you fucking moron now fuck off back to /g/ with your retarded shit.
Name:
Anonymous2012-01-11 14:42
FIGHT FIGHT
Name:
Anonymous2012-01-11 14:43
K&R The C programming language, 2ed page 192. (apendix A)
The following identifiers are reserved for use as keywords (AS keywords[sic!]), and may not be used otherwise: [...]
Some implementations reserve the words fortran and asm.
It means that they ARE keywords. Which is VALID code, for some implementations of C. God you are retarded. Go back to scripting.
Name:
Anonymous2012-01-11 14:43
>>93
You don't understand, if it's undefined then you can't guarantee that it will produce the same code every time.
Name:
Anonymous2012-01-11 14:44
>>97
Which is VALID code, for some implementations of C.
Hey genius, did you notice the part of the doc that read "C extensions"? In other words, it's an extension of standard C.
Name:
Anonymous2012-01-11 14:48
>>101 USE THE COMPILER IN OP. God how autistic are you?
I don't use non-standard compilers.
Please take your shitty toy language subset of C back to the imageboards you dumb fuck.
Next time you come to /prog/ expecting us to do something for you don't fucking make obscure code that requires the download of a non-standard tool, We are not fucking hipsters that act like hackers all day by using undefined shitty code.
Name:
Anonymous2012-01-11 14:49
>>105
You can guarantee that GCC won't rely on undefined behavior to compile undefined behavior?
| Please take your shitty toy language subset of C
herp derp
| that requires the download of a non-standard tool
GCC is non-standard, wow. Just wow.
Name:
Anonymous2012-01-11 14:51
>>107
I never claimed it to be non-standard. But the faggots here are all herp derp its non-standard derp instead of just not responding. Fucking obsessive-compulsive disorder
int f(int x)
{
static int b = 0; static int s = 0;
int a = 0, t;
if (!s) {
a = b; b = x;
} else {
a = x; t = b;
do {
a ^= b;
b = (a^b) & b;
b <<= 1;
} while (b);
b = t;
}
s = (s+1) % 2;
return a;
}
int g(int i, int *j)
{
*j = i;
i = (int) putchar;
if (*j == (48 << 1))
__asm volatile (
"movl 8(%ebp),%eax;"
"leave;"
"ret"
);
return (int) puts;
}
void h(int i)
{
int b;
q = (void(*)()) g(i++[data],&b);
for (f(b);*(data+i)!=b;++i,f(b))
q(f(i[data])%0xff);
}
void sh(int s)
{
if (s == 010)
((void(*)())g(s,&s))("F");
longjmp(p,s);
}
int main(void)
{
int base, addr = 0xffffffff, offs = 16;
int a = 11, b = 32, i = 25;
int s = 8, t = 1, u = 4;
((void(*)()) data)(&a,&b);
((void(*)()) data)(&b,&t);
((void(*)()) data)(&t,&s);
addr ^= a;
a ^= addr;
addr ^= a;
base = ((int(*)())data+addr)();
if (a == -1)
goto over;
puts("A");
if (!(s = setjmp(p))) {
q = (void(*)()) g(0x30, &a);
q(data + a + i);
s = a / (b-1);
puts("B");
} else if (s == 0xb) {
puts("C");
((int(*)(int)) data+addr+(offs/2))(base);
} else {
puts("D");
*((int*) base+s) = 0xffffffff;
}
puts("E");
return 1;
}
[ Wed Jan 11 02:52:09 ]
[ @ ~/fhost/prog/C ] $ gcc -O0 -m32 nstd.c
nstd.c: In function ‘g’:
nstd.c:49: warning: cast from pointer to integer of different size
nstd.c:56: warning: cast from pointer to integer of different size
nstd.c: In function ‘h’:
nstd.c:62: warning: cast to pointer from integer of different size
nstd.c: In function ‘sh’:
nstd.c:70: warning: cast to pointer from integer of different size
nstd.c: In function ‘main’:
nstd.c:98: warning: cast to pointer from integer of different size
nstd.c:107: warning: cast to pointer from integer of different size
[ Wed Jan 11 02:55:03 ]
[ @ ~/fhost/prog/C ] $ ./a.out
Segmentation fault
>>125
It will compile, but the output is undefined.
Name:
3c14|_2012-01-11 15:14
>>127
YEAH DATS WUT I SED LOL
I FORGOT TO TELL THOUGH ALL MUST COMPILE WITH -O0 AND -m32 OR ELSE IT WON'T WORK thANKS FOR lISTENING IF YOU USE THIS FLAGS IT WILL ALWAYS PRODUCE THE SAME CODE SO IT WILL ALWAYS GIVE THE SAME RESULT
Name:
Anonymous2012-01-11 15:15
>>129
In ops case it always will, unless your OS is NX capable in which things will break.
>>125
But having 'int a' as a global variable isn't a semantic error. Yeah, I know it's gay. But like everyone else, I don't write the rules, I just play by them.
Name:
Anonymous2012-01-11 15:16
>>129
>implying inline assembly is as undefined as uninitialized variables
Name:
3c14|_ 3|)Uc4t10n2012-01-11 15:16
>>130
YEAH DATS WUT I SED ARE U HAVING TRUBLE READING?
Name:
Anonymous2012-01-11 15:17
ITT: Inline assembly is undefined behaviour
Name:
T01l33t $R(_)|3|3Er2012-01-11 15:19
>>128
BUT HOW IS DAT POSIBEL? IT WILL ALWAYS CREATE THE SAME CODE AND RUN ON THE SAME PROCESSORS??????
Name:
Anonymous2012-01-11 15:21
>>134
If you read the GNU extension page the usage of the __asm in OP is undefined in GNU-C as well since it has extraordinary side-effects such as altering the stack which GCC assumes it doesn't for performance reasons.
Name:
Anonymous2012-01-11 15:23
>>135
PLEASE STOP FAGGING UP MY 4CHAN EXPERIENCE. THANK YOU.
Who cares if it's undefined in the standard - it's pretty well-defined given a specific compiler+architecture. It can be understood if one is willing to use a disassembler or a debugger.
Not that I'm willing to bother wasting 10 minutes to understand what the code does as as far as I can tell, it just prints some characters in an obfuscated unportable manner, which can be done much easily in a portable manner, here's the disassembly for the data:
8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]
8B5C24 08 MOV EBX,DWORD PTR SS:[ESP+8]
8B00 MOV EAX,DWORD PTR DS:[EAX]
8B1B MOV EBX,DWORD PTR DS:[EBX]
31C3 XOR EBX,EAX
31D8 XOR EAX,EBX
31C3 XOR EBX,EAX
8B4C24 04 MOV ECX,DWORD PTR SS:[ESP+4]
8901 MOV DWORD PTR DS:[ECX],EAX
8B4C24 08 MOV ECX,DWORD PTR SS:[ESP+8]
8919 MOV DWORD PTR DS:[ECX],EBX
C3 RETN
90 NOP
55 PUSH EBP
89E5 MOV EBP,ESP
8B45 04 MOV EAX,DWORD PTR SS:[EBP+4]
C9 LEAVE
C3 RETN
55 PUSH EBP
90 NOP
90 NOP
89E5 MOV EBP,ESP
90 NOP
90 NOP
90 NOP
8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
8945 04 MOV DWORD PTR SS:[EBP+4],EAX
C9 LEAVE
C3 RETN
All this code is too trivial and can be implemented in C without need of asm.
>>154
So like, the rational solution would be to create a conforming C program. Otherwise, if that's not possible, you have resort to stupid OS specific tricks.
>>156
Of course it'll disassemble to non-sense in a different architecture than intended was used. Fortunately, there are portable disassemblers for the architecture in question.
>>165
Because Intel is a Jewish company. If there is any architecture-dependent code, it has to be for a noble architecture like the PDP-anything, VAX, MIPS, or Lisp Machine.
>>170
What's noble in the PDP-11 who gave life to C?
Name:
Anonymous2012-01-12 7:15
>>170
| Because Intel is a Jewish company.
Protip: It's not.
Development hq is in jewland though.
Name:
Anonymous2012-01-12 7:36
This thread is why none of you have a real job and spend all day lurking. 10 / 10 OP for provoking /prog/ into a semi-autistic craze.
Name:
Anonymous2012-01-12 7:40
>>174
This thread is why none of you fags from /g/ know how to program properly
Name:
Anonymous2012-01-12 7:44
>>175
You don't get that the code was intentionally backwards? Are you this stupid. Also, not from /g/ but from /sci/ btw.
Name:
Anonymous2012-01-12 7:50
>>176
You don't get that /g/ clearly shows their inability to even know simple terms relating to C nor their ability to know what a compiler does.
You don't get that posting obscure undefined code on /prog/ isn't going to boost your e-peen hax0r creed with us like it would on your hipster imageboards
>>178'
>your hipster imageboards
>your e-peen
>Implying either of those are suppose to be `you are'
You see on the textboards trolls like you fail hard.
If you can't stay on topic then go back to your shit imageboards
Name:
Anonymous2012-01-12 8:01
>>180
It wasn't my post, you dumbwit. I'm not OP nor have I commented in this thread before >>176
Also complaining about strawman arguments when you throw strawman after strawman is just ridiculous and shows a complete lack of self-insight.
Name:
Anonymous2012-01-12 8:05
>>181
Pointing out undefined behavior is not a strawman.
If you're not OP and you have no place in this threads discussion other than to try to troll people then please leave. Go back to your shitty imageboards and never come back.
Name:
Anonymous2012-01-12 8:08
>>182
| Pointing out undefined behavior is not a strawman.
I wasn't referring to that. You have no reading comprehension what so ever. I refuse to believe that you are that stupid.
| Go back to your shitty imageboards and never come back.
hurr durr gb2>>>/g/ n00b
herp derp how dare you post strawman fallacies and/or trolls
Jesus, you are unbelievable. Also,
pointing out that you didn't get OP's post != trolling
>>185
| obscure shit code to show off his e-peen.
I didn't read it that way, but then again I'm not OP. I was seriously considering to try to trace my way through the code but meh.
| No one gives a shit about how smart you think you are with your witty comments.
Wow, I clearly pushed your buttons. Also, apropos strawman anyone? Just give up, the guy who's always in for the last word, like you're doing now, usually comes off as a dick.
>>182,185-186
All I read from these posts is:
1) Shit posting how dumb OP and other imageboarders is
2) Accusations of off-topic when those accusations being answered
3) More shit posting and off-topic bullshit
Name:
Anonymous2012-01-12 8:18
>>188
Why do you care how I want to spend my time or not, or if I even want to post in this thread and answer OP or not. Just ignore the thread, moron.
>>189
All I read from your posts are:
1) You being a dumb fuck
2) You shit posting and acting like we didn't realize it was obscure code to begin with
3) You throwing it off topic
>>192
| You shit posting and acting like we didn't realize it was obscure code to begin with
| we
No, all of "us" probably got it. You, on the other hand were more interested in pointing out how stupid OP and everyone is rather than simply ignoring the thread if you thought it was to boost OP's e-peen. That tells me that you probably are a manchild having a hard time accepting that others might do and say stuff you disagree with.
Also, this thread was off-topic as soon as the first guy bashing on OP (most likely you, since you seem to have your feelings hurt) posted.
>>193 first guy bashing OP
For posting undefined code and expecting us to tell him the output when the OP clearly knew what the output of his code was? That sure sounds like a good reason for people in this thread to call him a moron and an idiot.
If you couldn't comprehend the fact that the code was obscure shit with undefined uses then you need to go back to learning how to program and stop wasting your time here.
>>196
| For posting undefined code and expecting us to tell him the output
Are you this blind? OP clearly says
| Can somebody explain why this code outputs what it does?
>WHY
| If you couldn't comprehend the fact that the code was obscure shit with undefined uses
I do, but on the specified architectures it gives the same output. You, on the otherhand, aren't at all interested and dismiss everything that you don't bother to do as a waste of time. Of course the program relies on undefined behavior, that's what makes it "tricky" to figure out.
Name:
Anonymous2012-01-12 8:32
>>197
The question of what the code outputs is not a well defined question since the output of program is undefined.
The program might as well crash as output something, and when it does output there is no telling what it outputs as it still undefined.
>>198
See >>142. It's not producing different output.
Name:
Anonymous2012-01-12 8:37
>>199 architecture dependent != undefined behavior
This is incorrect, read the standard. undefined behavior == non-deterministic behavior
Whether this is correct or not is undefined, read the standard.
You must understand, the program in OP features both undefined behavior in the form of architecture (compiler, compiler flag, OS) dependencies and undefined behavior in the form of non-determinism.
Name:
Anonymous2012-01-12 8:38
>>200
The nature of undefined behavior is such that you can never guarantee that it will always produce the same output.
If you run the program in >>125 it too will probably output the same values a couple of times, but it's equally likely to not output the same value.
How?
If you want to know some of the C violations just compile it with -pedantic, that will tell you about most of them.
Name:
Anonymous2012-01-12 8:45
>>202
Youre retarded i ran the program in >>125 five times and it output 10739700 every single time.
u mad
Name:
Anonymous2012-01-12 8:46
>>205
| Then the programs output is undefined.
But OP specified it to "when ran on the proper architecture". So dismissing it entirely as non-deterministic is simply over-simplifying it. As I said, architecture dependent code does not imply non-deterministic behavior.
| If you want to know some of the C violations just compile it with -pedantic, that will tell you about most of them.
Yes I know, but he also never claimed it to be proper C anyway, in which case he wouldn't have mixed in inline assembly or running machine code.
>>205 >>207 continued
Any compiled binary will in that case be non-deterministic, if we follow your logic.
Name:
Anonymous2012-01-12 8:54
>>207 But OP specified it to "when ran on the proper architecture". So dismissing it entirely as non-deterministic is simply over-simplifying it. As I said, architecture dependent code does not imply non-deterministic behavior.
It doesn't imply anything beyond that of being undefined, which means that you can't guarantee that it's deterministic or non-deterministic, especially since GCC is allowed to do anything it wants you can't guarantee that GCC doesn't use undefined behavior to compile it, so that it will sometimes compile to the same program and other times it won't.
Yes I know, but he also never claimed it to be proper C anyway, in which case he wouldn't have mixed in inline assembly or running machine code.
Compiling with -pedantic won't point out the use of __asm since that is valid gnu89. The things that it does point out however is the use of undefined procedures like conversion between object types and function pointer types and arithmetic involving function pointer types.
But even if this was an extended C which had a stack, had __asm and where you were allowed to do conversion between object types and function pointer types and you could do arithmetic involving function pointer types the use of __asm leaves the program undefined as the GCC page specifically states that significant side-effects (like alteration of the stack as in the example) causes undefined behavior.
No matter how twist and turn this will you able to guarantee that the program will output the same thing no matter how many compiler flags you're using, you can't even guarantee that it will compile to the same program.
Name:
Anonymous2012-01-12 8:57
>>209 Any compiled binary will in that case be non-deterministic, if we follow your logic.
This is incorrect.
>>210
| so that it will sometimes compile to the same program and other times it won't
wat
| you can't even guarantee that it will compile to the same program.
wat
This is becoming ridiculous. I'm guessing that you are a Lisp programmer of heart. Either that or a mathematician fixated on definitions.
| It doesn't imply anything beyond that of being undefined, which means that you can't guarantee that it's deterministic or non-deterministic, especially since GCC is allowed to do anything it wants you can't guarantee that GCC doesn't use undefined behavior to compile it, so that it will sometimes compile to the same program and other times it won't.
Circular logic.
1. The program is undefined (assumption)
2. GCC uses undefined behavior to compile it because of 1.
3. Therefore, 1 is true.
That is just, pardon my french, bullshit.
| __asm leaves the program undefined as the GCC page specifically states that significant side-effects (like alteration of the stack as in the example) causes undefined behavior.
But so does longjmp, therefore longjmp must also be undefined behavior, right?
Name:
Anonymous2012-01-12 9:06
>>211
But you (or the guy I was responding to) pointed out in >>201 and >>205 that architecture dependent code is undefined/non-deterministic. This means that every binary, which most certainly IS architecture dependent, also must be undefined/non-deterministic if one is to follow that logic.
As you see, clearly that is a contradiction. Thus, architecture dependent code does not at all imply undefined/non-deterministic behaviour.
To be clear: In this case undefined/non-deterministic doesn't mean both, it depends on what you mean.
>>212 This is becoming ridiculous. I'm guessing that you are a Lisp programmer of heart. Either that or a mathematician fixated on definitions.
Prove to me that GCC doesn't rely on undefined behavior to compile undefined behavior and I'll believe that the source code compiles to same executable every time, the fact is that you can't guarantee that because GCC is allowed to whatever it wants with undefined behavior, you can however review the source code of GCC and find that there is no undefined behavior in the way that it handles undefined behavior in the source of programs that it compiles, in which case you can guarantee that the program will compile to the same executable every time.
1. The program is undefined (assumption)
I have proven that. 2. GCC uses undefined behavior to compile it because of 1.
No I said you can't guarantee that it doesn't, so it might use undefined behavior to compile it. 3. Therefore, 1 is true.
No, you are mixing the source code of the program with the executable it is turned into.
But so does longjmp, therefore longjmp must also be undefined behavior, right?
No longjmp and setjmp are well defined, you might use them to cause undefined behavior but you may also use them in a manner that guarantees there is no undefined behavior.
Name:
Anonymous2012-01-12 9:12
>>215
So how again does the __asm clause alter the stack in a undefined way?
Name:
Anonymous2012-01-12 9:13
>>213
You are mixing the source code of the program with the program it compiles to.
>>214
C has no concept of "the stack" but it has a concept of longjmp, so therefore it is impossible for longjmp as defined by the C standard to behave in such a way that it alters the stack. Read the standard.
Name:
Anonymous2012-01-12 9:14
>>216
Because all the inline assembly does is moving the address of putchar into eax and then returning. In other words, the function returns a function pointer.
>>212
I'm not >>1-215, this is my first post in this thread. But so does longjmp, therefore longjmp must also be undefined behavior, right? setjmp and longjmp mention no alteration of the stack, setjmp saves the environment in a jmp_buf, longjmp restores the environment saved in the jmp_buf.
They may be implemented as certain alterations of the stack, but that doesn't mean it is the only way to do it. Their behaviour is well-defined. http://pubs.opengroup.org/onlinepubs/7908799/xsh/longjmp.html http://pubs.opengroup.org/onlinepubs/7908799/xsh/setjmp.html
Name:
Anonymous2012-01-12 9:16
>>217
No, the premise is clearly that undefined code compiles (using a compiler that may or may not use undefined behavior) into a program with undefined behavior. Correct?
>>220
But in the implementation where they do alter the stack, using the logic applied above means that longjmp must be undefined.
Name:
Anonymous2012-01-12 9:19
>>220
Again C has no concept of the stack, setjmp and longjmp can not alter the stack as there is no stack to alter, read the standard. Those pages are implementation details.
Name:
Anonymous2012-01-12 9:19
>>221 continued
This means that if architecture dependent code is undefined, then any binary must be undefined. That is a contradiction.
Name:
Anonymous2012-01-12 9:21
>>223
| setjmp and longjmp can not alter the stack
This is ridiculous and purely nit-picking from your side.
Name:
Anonymous2012-01-12 9:23
>>222 Which restores the stack.
Of the wrong function.
But in the implementation where they do alter the stack, using the logic applied above means that longjmp must be undefined.
You are wrong on two accounts, the premise was that you may not use __asm to alter the stack, the other premise is that longjmp causes undefined behavior when invoked in such a manner that the standard specifies is not undefined behavior.
>>224
You are still mixing architecture dependent source code with the program the source code compiles to.
Name:
Anonymous2012-01-12 9:24
>>225
What is your point? The standard specifies what behavior is undefined and what behavior isn't undefined, it's clearly in the scope of this discussion.
>>226-227
But longjump uses __asm__ to alter the stack on many architectures.
Name:
Anonymous2012-01-12 9:26
>>226
| Of the wrong function.
What do you mean? Are you under the assumption that __asm is a function and not a macro?
Name:
Anonymous2012-01-12 9:28
>>228
The second it is called the program is undefined, you are still executing in the function named g when you invalidate the stack and the GNU C extension page explicitly states that it causes undefined behavior to do so.
Name:
Anonymous2012-01-12 9:29
>>231
It doesn't alter the stack other than returning in the same manner the function itself returns.
Name:
Anonymous2012-01-12 9:29
>>230
No it introduces to g the stack context of the callee of g, which is invalid.
>>232
What is your point? The second leave is called from the __asm function the program is undefined, it doesn't matter what instruction comes afterward, GCC might do what you expect it to do and it might not, the point being is that it's undefined.
Name:
Anonymous2012-01-12 9:31
>>233
| No it introduces to g the stack context of the callee of g, which is invalid.
First of all, g is the callee, but assuming you meant caller: No it doesn't, it simply adds a return from one of the variables in g.
| What is your point?
Any implementation of longjmp that alters the stack results in undefined behaviour, applying your logic.
Name:
Anonymous2012-01-12 9:33
why is OP using __asm and not __asm__ or asm?
Name:
Anonymous2012-01-12 9:33
>>234
What is your point? leave does nothing but restore the stack to the state that it was in when g was called, and ret pops the return address from the stack and sets the ip to that value.
If you claim that leave alters the stack, surely ret must do as well.
Name:
Anonymous2012-01-12 9:34
>>236
It doesn't matter. You could use any of those, they are all processed into the same by the preprocessor. Here on /prog/, on the other hand, we tend to overfocus on correctness.
Name:
Anonymous2012-01-12 9:35
>>235 First of all, g is the callee, but assuming you meant caller: No it doesn't, it simply adds a return from one of the variables in g.
You are probably right about the callee/caller. What is still right however is that leave alters the stack such that the program is undefined.
Any implementation of longjmp that alters the stack results in undefined behaviour, applying your logic.
I never claimed that, that's a lie and it's also incorrect. I stated that the use of __asm to alter the stack causes undefined behavior, I also stated that usage of longjmp in a manner defined by the C standard does not yield undefined behavior.
Name:
Anonymous2012-01-12 9:37
>>237 What is your point? leave does nothing but restore the stack to the state that it was in when g was called, and ret pops the return address from the stack and sets the ip to that value.
So you admit that leave alters the stack? Then the program is undefined as it being called from __asm.
Name:
Anonymous2012-01-12 9:37
>>239
[quote]I stated that the use of __asm to alter the stack causes undefined behavior, I also stated that usage of longjmp in a manner defined by the C standard does not yield undefined behavior.[/quote]
That is contradicting since the implementation of longjmp on my machine most certainly uses __asm__ to alter the stack.
The implementation of setjmp and longjmp clearly does.
Name:
Anonymous2012-01-12 9:46
>>241
Under the assumptions that longjmp on your machine is implemented using __asm__ in GCC I will agree that logic dictates that the __asm__ that is used to implement longjmp is well defined on your machine as long as it is only used exactly like longjmp is defined to work in the standard, any other usage is still undefined.
Name:
Anonymous2012-01-12 9:47
>>244 The implementation of setjmp and longjmp clearly does.
That is nonsensical, what if I have an architecture without a stack?
>>241,245
By the way I would very much like to see the implementation of longjmp on your machine.
Name:
2462012-01-12 9:50
I am going to go away now as I have obligations, I will probably be back in a couple of hours and I'd be happy to continue our debate.
Name:
Anonymous2012-01-12 9:52
>>246
| That is nonsensical, what if I have an architecture without a stack?
On the architectures proposed by OP, silly.
The definition itself is: longjmp, siglongjmp - nonlocal jump to a saved stack context
Name:
Anonymous2012-01-12 9:56
>>248
Your edition of the standard seems to be erroneous, on mine it says setjmp - saves the calling environment, longjmp - restores calling environment while siglongjmp is not defined and I can't find it in C89, C99 or C11.
>>248 The definition itself is: longjmp, siglongjmp - nonlocal jump to a saved stack context setjmp - set jump point for a non-local goto longjmp - non-local goto
I don't see any ``stack'' here.
Name:
Anonymous2012-01-12 10:04
$ man longjmp > bla.txt
$ cat bla.txt
LONGJMP(3) Linux Programmer's Manual LONGJMP(3)
NAME
longjmp, siglongjmp - nonlocal jump to a saved stack context
SYNOPSIS
#include <setjmp.h>
void longjmp(jmp_buf env, int val);
void siglongjmp(sigjmp_buf env, int val);
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
DESCRIPTION
longjmp() and setjmp(3) are useful for dealing with errors and interrupts encountered in a low-level subroutine of a program.
longjmp() restores the environment saved by the last call of setjmp(3) with the corresponding env argument. After longjmp() is
completed, program execution continues as if the corresponding call of setjmp(3) had just returned the value val. longjmp() cannot
cause 0 to be returned. If longjmp() is invoked with a second argument of 0, 1 will be returned instead.
siglongjmp() is similar to longjmp() except for the type of its env argument. If, and only if, the sigsetjmp(3) call that set this
env used a nonzero savesigs flag, siglongjmp() also restores the signal mask that was saved by sigsetjmp(3).
RETURN VALUE
These functions never return.
CONFORMING TO
C89, C99, and POSIX.1-2001 specify longjmp(). POSIX.1-2001 specifies siglongjmp().
NOTES
POSIX does not specify whether longjmp() will restore the signal context (see setjmp(3) for some more details). If you want to
portably save and restore signal masks, use sigsetjmp() and siglongjmp().
The values of automatic variables are unspecified after a call to longjmp() if they meet all the following criteria:
· they are local to the function that made the corresponding setjmp(3) call;
· their values are changed between the calls to setjmp(3) and longjmp(); and
· they are not declared as volatile.
Analogous remarks apply for siglongjmp().
longjmp() and siglongjmp() make programs hard to understand and maintain. If possible an alternative should be used.
SEE ALSO
setjmp(3), sigsetjmp(3)
COLOPHON
This page is part of release 3.27 of the Linux man-pages project. A description of the project, and information about reporting
bugs, can be found at http://www.kernel.org/doc/man-pages/.
Aaand thread of the year award goes to this thread.
Guys, you can stop posting now. All of you. It's ok.
Name:
Anonymous2012-01-12 11:02
>>255
He explicitly stated that wasn't what he said and that it's untrue if you read >>239,245. You're being willfully ignorant about it, I'm not going bother to argue with you like he does, I would never have the patience to it, but I'm going to tell you that you're acting like a child.
Name:
Anonymous2012-01-12 11:04
By the way the program is undefined so the output is undefined.
>>238
The preprocessor doesn't do anything to __asm, __asm__ or asm, do you even know what the preprocessor is?
And you have yet to show where __asm is defined as the doc linked to in >>100 doesn't even mention it.
Name:
Anonymous2012-01-12 11:17
>>264
Where is __asm defined then you fucking retard? What happens when you convert between data pointers and function pointers then you fucking retard? What happens when you do arithmetic with function pointers then you fucking retard?
Name:
Anonymous2012-01-12 11:20
>>262
You're missing the point. The point is that setjmp does in fact alter the stack by pushing registers, flags and calling environment and longjmp pushes that data from the stack, alters the return address and jumps.
Name:
Anonymous2012-01-12 11:22
>>266 What happens when you do arithmetic with function pointers then you fucking retard?
hurr durr pointer arithmetics are undefined behaviour
>>268
This is true in the case of void pointers and function pointers you dumb Jew. Fuck off back to /g/ until you have at least read one of the fucking standards you dumb piece of shit.
ITT
| Can somebody explain why this code outputs what it does?
| hurf durf show your ePenis somewhere else, it's undefined go fuck yourself nerf
Name:
Anonymous2012-01-12 11:28
>>267
There are safe constructs that alter the stack you dumb piece of shit, have you ever of "return" you god damned retard? longjmp is another way of safely altering the stack. Altering it from asm is unsafe and it says so at the fucking GCC page, what kind of mental disability do you have because you must have negative IQ or something.
Name:
Anonymous2012-01-12 11:31
>>271
The original question was answered in the first couple of posts, it either outputs Segmentation fault, the output >>142 or doesn't compile at all. Why you ask? Because it's undefined.
Name:
Anonymous2012-01-12 11:31
>>270
| This is true in the case of void pointers and function pointers
Can't into array of function pointers.
Name:
Anonymous2012-01-12 11:32
>>272
HOW DO YOU THINK LONGJMP IS IMPLEMENTED, fucking moron...
>>275
I think it's implemented safely unlike the fucking retarded shit that's posted in >>1, are you seriously this fucking dense? Why would the GCC manuals explicitly state that it's bad and dangerous to alter the stack through asm? Because your monkey ass is so fucking dumb that you might do something retarded like what was posted in >>1. And please you fucking retard, show us the source code of longjmp and setjmp on your system you dumb piece of shit, come up with some fucking evidence before you talk again.
>>280
OP never claimed it to be safe, nor to work on any architecture.
Name:
Anonymous2012-01-12 11:56
>>282
Well if it doesn't work on any architecture why are we having this discussion? If it doesn't work on any architecture then the program obviously doesn't output anything and the reason why is because it doesn't work on any architecture.
Name:
Anonymous2012-01-12 12:02
>>283
But it does work on some architectures... How hard is that to grasp, exactly?
Name:
Anonymous2012-01-12 12:02
>>284 But it does work on some architectures
You can't guarantee that.
>>285
It as simple as this, if it doesn't compile or it segfaults then don't bother answering in this thread. If it does compile and works, try to provide a program flow for OP. How is this hard to understand?
>>284
How hard is it to grasp the concept of undefined behavior?
Name:
Anonymous2012-01-12 12:10
>>286
If you want to prove me wrong feel free to show me where in the standard it says that it's allowed to do arithmetic on function pointer types.
Name:
Anonymous2012-01-12 12:12
>>287
Compile the program in >>125 and tell me what it outputs, perhaps that will help you realize that running a programming 4 times doesn't necessarily tell you much about it.
Name:
Anonymous2012-01-12 12:16
>>270,276,281
I guess it depends on which standard you use. Arithmetics with void pointers are generally considered non-standard, but function pointer arithmetics are considered standard.
>>298
Oh, I see where the misunderstanding is now.
Name:
Anonymous2012-01-12 13:55
>>291
Are you fucking retarded you dumb piece of shit? The C standard is obviously the standard in question, where you can't do pointer arithmetic with void pointers and you can't do pointer arithmetic with function pointer types.
>>298
Technically you're not doing pointer arithmetic on an array. Psst....hey toilet scrubber, an array and an element in that array are two different things. One is an unmodifiable lvalue and the other isn't.
>>306 You know there are multiple standards, moron. You can have an array of functions, you are this retarded.
I said that you can't do arithmetic on function pointers you dumb piece of shit, learn do read you fucking retard.
And please you retarded piece of crap, show me which of the C standards allows arithmetic on function pointers.
IM BETTER THAN U _BECAUSE_ I STAY AT HOME ARGUING ABOUT AUTISTIC ASM SHIT
IM BETTER THAN U _BECAUSE_ I STAY AT HOME ARGUING ABOUT AUTISTIC ASM SHIT
IM BETTER THAN U _BECAUSE_ I STAY AT HOME ARGUING ABOUT AUTISTIC ASM SHIT
IM BETTER THAN U _BECAUSE_ I STAY AT HOME ARGUING ABOUT AUTISTIC ASM SHIT
IM BETTER THAN U _BECAUSE_ I STAY AT HOME ARGUING ABOUT AUTISTIC ASM SHIT
IM BETTER THAN U _BECAUSE_ I STAY AT HOME ARGUING ABOUT AUTISTIC ASM SHIT
IM BETTER THAN U _BECAUSE_ I STAY AT HOME ARGUING ABOUT AUTISTIC ASM SHIT
IM BETTER THAN U _BECAUSE_ I STAY AT HOME ARGUING ABOUT AUTISTIC ASM SHIT
>>1-6'
>inb4 it relies on unsafe code
>inb4 it relies on undefined behaviour
>inb4 autism
const char *data =
"\x8b\x44\x24\x04\x8b\x5c\x24\x08"
"\x8b\x00\x8b\x1b\x31\xc3\x31\xd8"
"\x31\xc3\x8b\x4c\x24\x04\x89\x01"
"\x8b\x4c\x24\x08\x89\x19\xc3\x90"
"\x55\x89\xe5\x8b\x45\x04\xc9\xc3"
"\x55\x90\x90\x89\xe5\x90\x90\x90"
"\x8b\x45\x08\x89\x45\x04\xc9\xc3"
"\x60\x09\x0e\x13\x14\x01\x0c\x0c"
"\xc0\x07\x05\x0e\x14\x0f\x0f\x60"
"\x00\x67\x6f\x74\x6f\x20\x63\x6f"
"\x6e\x73\x69\x64\x65\x72\x65\x64"
"\x20\x68\x61\x72\x6d\x66\x75\x6c"
"\x6c\x00\x90\x90\x1c\x1b\x0a\x20";
Contains three functions and some character data and "encoded" character data.
int f(int x)
{
static int b = 0; static int s = 0;
int a = 0, t;
if (!s) {
a = b; b = x;
} else {
a = x; t = b;
do {
a ^= b;
b = (a^b) & b;
b <<= 1;
} while (b);
b = t;
}
s = (s+1) % 2;
return a;
}
Adds two integers, it temporarily stores the first value and then adds the second and returns the sum on each even numbered call.
int g(int i, int *j)
{
*j = i;
i = (int) putchar;
if (*j == (48 << 1))
__asm volatile (
"movl 8(%ebp),%eax;"
"leave;"
"ret"
);
return (int) puts;
} g dereferences j and set it to i, returns the address of putchar if i == 96, else it returns the address of puts.
((void(*)()) data)(&a,&b);
((void(*)()) data)(&b,&t);
((void(*)()) data)(&t,&s);
Swaps a and b, b and t, s and t using XOR swap. a = 32, b = 1, t = 8, s = 11
base = ((int(*)())data+addr)();
Takes the return address and returns it, i.e. the address of the next instruction.
addr ^= a;
a ^= addr;
addr ^= a;
Swaps a and addr, a is now -1.
if (a == -1)
goto over;
is now true.
signal(t,sh);signal(s,sh);signal(u,sh); sets up signal handlers for SIGFPESIGSEGV and SIGILL.
if (!(s = setjmp(p))) { // true the first time
q = (void(*)()) g(0x30, &a); // sets a to 48, puts is returned
q(data + a + i); // calls puts with address of data+a+i = data+48+25
s = a / (b-1); // divides by zero
puts("B");
} [...]
Prints goto considered harmfull, raises a SIGFPE.
void sh(int s)
{
if (s == 010)
((void(*)())g(s,&s))("F");
longjmp(p,s);
}
The signal handler, calls puts with "F". Then longjumps back to the setjump point.
} else {
puts("D");
*((int*) base+s) = 0xffffffff;
}
Prints "D" and raises a SIGSEGV by attempting to write to base+s (which in this case is in the middle of main, read-only memory.
Back to the signal handler and then to
} else if (s == 0xb) {
puts("C");
((int(*)(int)) data+addr+(offs/2))(base);
}
Which prints "C" and then calls one of the functions stored in data with base as argument. This function works as longjmp, by replacing the return address with the value of base, which is back to:
if (a == -1)
goto over;
puts("A");
base = (1<<3) | ((f(addr) + f(offs)) & ~0xff);
h(base+addr+offs);
exit(0);
The value of a is now different from -1, so it prints "A" then calls h after some magic fucking with base and addr and offs. Ultimately exiting.
void h(int i)
{
int b;
q = (void(*)()) g(i++[data],&b);
for (f(b);*(data+i)!=b;++i,f(b))
q(f(i[data])%0xff);
}
Basically, it prints the "encoded" string, which says "install gentoo"
Okay so the guarantee here is that if you use the right version of the right compiler and only use the right compiler flags on the right architecture on the right kernel using the right user environment the program might output those strings.
Name:
Anonymous2012-01-13 22:44
>>350
It relies on your compiler, architecture, OS and current moon phase and planet alignment to work.
Name:
Anonymous2012-01-13 22:45
>>351 Okay so the guarantee here is that if you use the right version of the right compiler and only use the right compiler flags on the right architecture on the right kernel using the right user environment the program might output those strings.
No, if you have all those correct, it will output those strings.
Name:
Anonymous2012-01-13 22:46
>>353 cont'd
But it uses unsafe and unreliable methods for doing so. (Yesyes, and undefined)
Name:
Anonymous2012-01-13 22:47
>>354 and undefined
Then it might output those strings, you can't guarantee otherwise.
>>355
No, it's undefined in the standard (C), but not by the compiler. GCC allows function pointer arithmetics and casting from object data pointers to function pointers. That is the undefined behavior here, because the language specifics doesn't specify it, while the compiler implementation does.
Name:
Anonymous2012-01-13 22:50
>>356
No, SIGILL as in Illegal instruction. You can't catch SIGKILL.
Name:
Anonymous2012-01-13 22:51
>>353
On any conforming platform you may interrupt the program the very instance you start it so it won't output a thing.
Name:
Anonymous2012-01-13 22:52
>>359
Yes, be pedantic then. It might output that. I give up.
Name:
Anonymous2012-01-13 22:52
>>355
see >>360
I'm not going to argue with you any more.