Live data from Hacker News

The Journey Before main()

amit.prasad.me

101–110 of 145 posts

Re: The Journey Before main()

#101
post #37

Earlier quoted context omitted.

This is one of the cornerstones that guarantee Windows can easily upgrade the C runtime and make performance and security upgrades. Win32 APIs have a different function calling ABI too. So only part of that gets "bloated" is Win32 API itself (which is spread across multiple DLLs and don't actually bloat RAM usage). Most of the time even those functions and structures are carefully designed to have some future-proofne…

I'm sick of glibc compatibility problems. Are there any recommended replacements?

Glibc is half of GNU/Linux. You can of course use another libc, but it will be a different OS.

Re: The Journey Before main()

#102

Earlier quoted context omitted.

Almost freestanding. It still requires you to link against kernel32 and use the functions it provides. This is because issuing system calls directly to the Windows kernel is not supported. The kernel developers reserve the right to change things like system call numbers, so they can't be hardcoded into the application.

> Almost freestanding. It still requires you to link against kernel32 Nitpick: the phrase “link against kernel32” feels like a Linux-ism. If you’re only calling a few function you need to load kernel32.dll and call some functions in it. But that’s a slightly different operation than linking against it. At least how I’ve always used the term link. You’re not wrong in principle. But Linux and Windows do a lot of things…

Linker is short for Link Loader, so I don't now what your definition of linking is, if it doesn't include loading.

Re: The Journey Before main()

#103

Earlier quoted context omitted.

> But adult projects should support Windows imho and consider Windows support from the start. Hope whatever "adult" is working on the project this is getting paid handsomely. They'd certainly need to pay me big bucks to care about Windows support. In any case, Linux system call ABI is becoming a lingua franca of systems programming. BSDs have implemented Linux system calls. Windows has straight up included Linux in t…

> Windows has straight up included Linux in the system. It looks like simply targeting Linux can easily result in a binary that actually does run anywhere. Kind of. But not really. WSL2 is a thing. But most code isn’t running in WSL2 so if your thing “runs on windows” but requires running in a WSL2 context then oftentimes it might as well not exist. > They'd certainly need to pay me big bucks to care about Windows su…

There is also WSL1 and Cygwin and MinGW/MSYS2.

And no WSL2 is not a newer version of WSL1, they are entirely different products.

Re: The Journey Before main()

#104

Earlier quoted context omitted.

> That's not something that can be expressed in C. I've often made the argument that compilers should add builtins for Linux system calls. Just emit code in the right calling convention and the system call instruction, and return the result. Even high level dynamic languages could have their JIT compilers generate this code. I actually tried to hack a linux_system_call builtin into GCC at some point. Lost that work i…

> I've often made the argument that compilers should add builtins for Linux system calls. Just emit code in the right calling convention and the system call instruction, and return the result. Even high level dynamic languages could have their JIT compilers generate this code. You can only do that, when you compile for a specific machine. In general you are compiling for some abstract notion of an OS. JITs always com…

> You can only do that, when you compile for a specific machine.

You always compile for a specific machine. There is always a target instruction set architecture. It decides the calling convention used for Linux system calls. Compiler can even produce an error in case the target is not supported by Linux.

> In general you are compiling for some abstract notion of an OS.

This "abstract notion of an OS" boils down to the libc. Freestanding C gets rid of most of it. Making system calls is also perfectly valid in hosted C. Modern languages like Rust also have freestanding modes.

> In my experience there are often detailed explanation in the notes section.

That's the problem. Why is the Linux stuff just a bunch of footnotes in the Linux manual? It should be in the main section. The glibc specifics should be footnotes.

Re: The Journey Before main()

#105
From the title, I thought this was going to be about the parts of a program that run before the main function is entered. Static objects have to be constructed. Quite a bit of code can run. Order of initialization can be a problem. What happens if you try to do I/O from a static constructor? Does that even work?

Re: The Journey Before main()

#106

From the title, I thought this was going to be about the parts of a program that run before the main function is entered. Static objects have to be constructed. Quite a bit of code can run. Order of initialization can be a problem. What happens if you try to do I/O from a static constructor? Does that even work?

This is heavily language runtime dependent — there’s nothing that fundamentally stops you from doing anything during the phase between jumping to an entry point and the main()

Re: The Journey Before main()

#107

From the title, I thought this was going to be about the parts of a program that run before the main function is entered. Static objects have to be constructed. Quite a bit of code can run. Order of initialization can be a problem. What happens if you try to do I/O from a static constructor? Does that even work?

This is heavily language runtime dependent — there’s nothing that fundamentally stops you from doing anything during the phase between jumping to an entry point and the main()

Indeed the craziest among us occasionally abuse this fact, so long as the compiler implementation lets us.

Re: The Journey Before main()

#108

Earlier quoted context omitted.

So you use debuggers. Good. Then you can confirm that the program counter is incremented after each instruction, and that you read assembly from top to bottom. That means smaller addresses are at the top and larger addresses are at the bottom. This matches my layout, and it also matches what you see in the terminal in /proc/ /maps.

Incrementation direction is orthogonal to up/down. When I disassemble a program, the addresses are all over the place and not ordered. > That means smaller addresses are at the top and larger addresses are at the bottom. No, my mental model is the exact opposite and this matches the jargon out there. > also matches what you see in the terminal in /proc/ /maps I think of this as a sorted list, not as a display or desc…

Yeah this is sort of the same objection I had in https://news.ycombinator.com/item?id=45709016

Although thinking about it more, the fact that address indexing is now from top-to-bottom is actually consistent with how I imagine indexing for Nx1 array (or equivalently, how you index matrices in math).

Thinking about it more, I don't think there is any real convention, even diagrams are split. You are going to have to learn to "flip" things either way, the same way matrix indexing differs from cartesian plane indexing. Same way different graphical systems have different conventions for where the origin is. People colloquially say things like "high mem", and you'll have to translate this to your mental model.

It's why I suggested a horizontal, left-to-right visualization. I think everyone would agree that lower addresses on the left, higher addresses on right.

Also could you elaborate more on what you mean by debuggers showing it the opposite direction? If you do `info proc mappings` in gdb it is also lower addresses at top. This might be debugger specific though.

Re: The Journey Before main()

#109

Earlier quoted context omitted.

This is heavily language runtime dependent — there’s nothing that fundamentally stops you from doing anything during the phase between jumping to an entry point and the main()

Indeed the craziest among us occasionally abuse this fact, so long as the compiler implementation lets us.

Right. This tends to come up with packages, which just by virtue of being loaded, set up to do something such as log, print, catch errors, or phone home to something.

Re: The Journey Before main()

#110
post #37

Earlier quoted context omitted.

This is one of the cornerstones that guarantee Windows can easily upgrade the C runtime and make performance and security upgrades. Win32 APIs have a different function calling ABI too. So only part of that gets "bloated" is Win32 API itself (which is spread across multiple DLLs and don't actually bloat RAM usage). Most of the time even those functions and structures are carefully designed to have some future-proofne…

> Glibc broke certain games / Steam by removing some parts of their ELF implementation: https://sourceware.org/bugzilla/show_bug.cgi?id=32653 . They backed due to huge backlash from the community. It would be better if you specified which part was removed: support for executable code on stack. This is used in 99% cases by malware so it is better to break 1% of broken programs and have other 99% run safer.

The comments on that bug report mention several language runtimes getting broken. Preventing languages that are generally safer than C from working seems rather counterproductive to overall security.
Post reply on HN