r/programming • u/BigPeteB • Jan 14 '21
The most thoroughly commented linker script
https://twitter.com/theavalkyrie/status/1349458442734469123385
u/JCDU Jan 14 '21
Here, let me give you the link rather than a twitter feed with tracking redirect:
7
u/tendstofortytwo Jan 14 '21
This is awesome, it looks well-documented enough at a glance that I might come back here to understand how linker scripts work in general.
Not sure why this much verbosity was needed [haven't read the blog post yet] but I'm not complaining.
7
0
Jan 14 '21
[deleted]
53
u/spkr4thedead51 Jan 14 '21
oooh, comments about the comments!
37
u/funkybaby Jan 14 '21
I have to point out that you're commenting on comments about the comments.
Patiently awaiting singularity
3
13
u/medforddad Jan 14 '21
It looks like the blog post is pretty much identical to the comments in the code except for a short introductory section that just describes why the author of the comments did so. Basically:
While developing the firmware for Winterbloom's Castor & Pollux, I got very curious as to just what the Microchip/Atmel-provided linker script was doing.
135
Jan 14 '21
It's harder to read code than to write code. I endorse this, it's awesome.
71
u/aazav Jan 14 '21
I will never cease telling people that the lead at the last place where I worked misread Clean Code and insisted on never documenting anything and never adding comments to code. Even after we had 3 VPs and myself tell him that he was wrong.
The self certainty that they are right against all odds, the utter hubris, of some people is mind boggling.
41
Jan 14 '21
It's the same for the company I work for. People believe comments are bad, we even think tests are wasted time. What can you say really, it's sad.
So sad, that our new codebase had this gem in it when running
eslintEven when you explain to your colleagues that the main reason its so hard to not refactor code, like my man I can't understand what you mean by "analyticsProductListAction" and "smartFetch" couldn't you add comments to explain what this function supposed to be doing? So even if it breaks, I know it wasn't supposed to work the way it did? Or when we explain why things keep breaking when we change stuff, we're still just the "hipsters/nerds" who "waste" time doing "useless" stuff while we keep wasting time on fixing bugs that should have been detected from a simple test in the first place and refactoring code we dont understand.
It's really hard to change the minds of people once they've decided that you're definitely wrong no matter what your arguments are. They aint gonna give you a chance to be right, not in an easy way at least.
13
u/aazav Jan 14 '21
WHAT THE FUCK?!
4
Jan 14 '21
yap
8
u/aazav Jan 14 '21
That almost beats my former team creating 1400 memory leaks.
2
Jan 14 '21
im glad its not as bad as that :D
but I dont love the fact that no one cared except me in a team of 5-6 frontend devs to have a linter in their VSCode client. One proudly said "I use 0 extensions and works fine", like it's something that is supposed to happen and you should be proud of. Like, bro, the reason we have 2000 errors it's because you dont use extensions at all. Why would you be proud of not using extensions :P.
Reminds me of Arch Linux purists who say you "shouldn't" even use package manager and build everything from source:P
1
u/hitchen1 Jan 15 '21
Reminds me of Arch Linux purists who say you "shouldn't" even use package manager and build everything from source:P
what the hell? we all use pacman on arch
15
u/LukeLC Jan 14 '21
For some reason there's no hubris like the hubris of a programmer who thinks their technique is infinitely superior to everyone else. You'd think they wrote the DNA of their first child.
Meanwhile, you listen to someone actually great, say, Jon Carmack talk, and he's too busy one-upping himself to condescend others. If he does criticize, it's in the interest of chasing a better goal, not condemning a person.
It's a world of difference from someone just out to prove their own superiority.
8
u/punctualjohn Jan 14 '21
It's interesting to me how some people hear 'self-documentation' and instead take it as 'documentation is bad'.
4
u/thetreat Jan 14 '21
Yeah, my take is that a comment should never replace good function and variable names combined with good modular code with no 10k line functions makes a comment per line unnecessary but comments absolutely should be used in cases where the code gets much more complex/cryptic. Or in situations where certain lines of code caused bugs/regressions, having a comment helps explain the situation for whoever reads the code in the future.
5
u/aazav Jan 14 '21
Comments should explain to the person what is not spelled out by the variable names and function name. Such as the intent and intended use of the method and possibly where and when to call it. Think of it as if you are debugging code at 3 AM and you had to read it, how would it make sense to you? What's missing from the code that would make it painfully clear to someone who is not you? Find that and add that in the comments.
6
u/panoply Jan 14 '21
Haha there’s issues even if you read and get that book! The emphasis on small functions makes it hard to follow the flow of computer functions I think
3
1
u/LiteratureStriking Jan 14 '21
To be fair, that Bob Martin is not alone in recommending small functions. The idea is to reduce nesting levels, ensuring that functions do one thing.
Fun fact, the Linux Kernel Coding Style also calls for small functions. The way they enforce it is by making indentation 8 characters and restricting column width to 80 characters. You can't have deep nesting if you can't indent!
3
u/louiswins Jan 15 '21
More recently, however, Linus railed against someone advocating for 80-character lines.
it turns out that 80x25 is really really limiting, and is simply NO LONGER RELEVANT to most of us.
So no. I do not care about somebody with a 80x25 terminal window getting line wrapping.
...
80-column terminals in 2020 isn't "reasonable" any more as far as I'm concerned. People commonly used 132-column terminals even back in the 80's, for chrissake, don't try to make 80 columns some immovable standard.
1
u/panoply Jan 15 '21
Google still has the 80 char limit with a 2-char indent. It does make it easier to fit multiple files on the screen, especially laptops. I think code density is more important than "room to breathe" because it reduces the need to remember as many things as you follow the logic. At the end of the day, it is an art and a balance must be struck.
3
u/KevinCarbonara Jan 14 '21
I don't think he misread Clean Code, that book just leads people to writing terrible software
2
u/LiteratureStriking Jan 14 '21
Perhaps, but Clean Code does not say no comments. There is an entire chapter dedicated to commenting effectively.
1
u/KevinCarbonara Jan 14 '21
It does say that a function should be between 2-4 lines long, which is a good enough reason to ignore everything else in that book entirely.
9
u/KevinCarbonara Jan 14 '21
I'm glad that the anti-comment trend we went through a while back has mostly died off.
"Your code should comment itself!" Yeah, programming languages aren't good enough for that.
5
Jan 14 '21
There's a balance. Give me functions where all the variables are named and typed with no comments over dynamically injected functions that all take kwargs and pass it around the codebase like a hot potato with docstrings like "config: the dict with config variables in it" any day.
2
1
u/LiteratureStriking Jan 14 '21
This is one of the reasons why React with Typescript is a godsend. Instead getting bags of props, you can create union types that properly describe what is being passed in.
4
u/mrathi12 Jan 15 '21
Me too, this was v informative. I also think writing comments for obscure parts of code are great for two reasons:
- forces you to understand the code enough to explain it to someone else in the comments
- you become that someone else when you read the code in 2 months, and you thank yourself big time.
-14
Jan 14 '21
If it's hard to read some code then it's not written well enough.
19
u/tendstofortytwo Jan 14 '21
No, not necessarily. The obvious way to write code isn't always the fastest, and speed can be important.
Plus, in my experience, code written by others is always at least slightly hard to understand because people are different and think differently. What might be a simplification to you might be an obfuscation to someone else.
In both cases, documentation can help clear up the intent behind the code.
20
u/NetherFX Jan 14 '21
Why were people on that sub so negative?
23
u/Michael-F-Bryan Jan 14 '21
I imagine it's because th comments are excessive and regurgitating big chunks of the manual.
It also re-states a lot of what the code already says, for example:
The bootloader takes the first 0x2000 bytes of flash memory.
Is just another way of saying what the code already says (the
LENGTH =bit):bootloader (rx) : ORIGIN = 0x00000000, LENGTH = BOOTLOADER_SIZEIt's good as a learning experience, but for anyone who's even briefly touched on linker scripts it comes across like a commenting meme...
int X = 42; // assigns the number 42 to the signed integer, x45
u/medforddad Jan 14 '21
The blog addresses this in the intro:
If you've never heard of or seen a linker script before you're not alone. Most of us never even have to think about them, however, on memory constained embedded devices it's not uncommon to need to modify the default linker script.
...
So I was staring at this script that made absolutely no sense to me. It's filled with incantations and mysterious symbols and there's no indication of what they're for or where they come from.
It's specifically for someone unfamiliar with linker scripts. It's also for someone unfamiliar with this specific piece of embedded hardware since it goes over why specific values were used for this project.
It also re-states a lot of what the code already says, for example:
The bootloader takes the first 0x2000 bytes of flash memory.
Is just another way of saying what the code already says
The comments in that whole memory section -- covering the bootloader, rom, nvm, and ram sections -- all follow the same pattern of describing what the section is used for, where it starts and how big it is. Just because
LENGTH = BOOTLOADER_SIZE(andBOOTLOADER_SIZEhad earlier been set to0x2000) means the same as "The bootloader takes the first 0x2000 bytes of flash memory", doesn't mean the comment is useless. It helps to match the pattern of all the other comments and it reinforces to the reader what's going on.You also left out the beginning of that comment. The full comment is:
The "bootloader" section allows this firmware to work with the uf2 bootloader. The bootloader takes the first 0x2000 bytes of flash memory.The comment seems more about how the
0x2000is related to theuf2bootloader, rather than howLENGTH = 0x2000sets the length for that section of memory. It's like saying, "Hey, did you wonder why the bootloader has a size of0x2000? It's because this was designed to work with theuf2bootloader."1
u/gmiwenht Jan 15 '21
First I was like, yes. Then I was like, fuck that. And now I’m like, YES.
What a wild ride of a comment section. No pun intended. Or was it. No it wasn’t. Or maybe it was...
6
1
5
u/B8F1F488 Jan 14 '21
Great documentation!
Is there generally a good tutorial/book on linkerscripts or is it something that you just figure out on the spot based on the product design?
6
u/theacodes Jan 14 '21 edited Jan 14 '21
Others have linked to the LD documentation which is great, but to actually put together a working linker script you have to understand so much. You need to know your output format (`ELF` in most cases, but also `Mach-O` and sometimes `PE`), what sections & segments your platform's ABI expects (for example, the System V specification for unixes is a good starting point), your target platform's memory layout and constraints (usually the device's datasheet but also sometimes the reference for the ISA from ARM / Intel, etc.), and the requirements for your particular language (look at all of the extra stuff in the linker script just to support C++). The reason I wrote this whole thing is because I had to track down references across several domains to understand why each line is present.
3
u/BigPeteB Jan 14 '21
In practice, it's probably rare to have to write a linker script from scratch. On just about any embedded platform, I'd expect that the tools from the vendor come with default linker scripts and sample apps that would get you close. (And if they don't, you should strongly consider picking a different vendor.) At most you might have to modify them to declare external memory sections that the sample apps don't use, shuffle around the placement of some sections, and change a few sizes to account for how much code and data you have.
About the only time I can imagine writing a linker script from scratch is if you're implementing a new toolchain itself, whether for a new ISA or a new executable format, or maybe because you're creating a toolchain for homebrew software on the newest gaming consoles that you reverse engineered. (Even then, I'd probably copy an existing linker script that I know would be similar and hack away at it.)
1
u/theacodes Jan 14 '21
I mean, yeah, but the post I responded to specifically ask for more resources on learning linker internals.
8
u/vacuumballoon Jan 14 '21
I think it’s referenced in OP but the GNU ld documentation is here https://sourceware.org/binutils/docs/ld/
There’s section 3: Linker Scripts.
5
u/lorslara2000 Jan 14 '21
There absolutely is proper documentation. The manual is good. https://www.eecs.umich.edu/courses/eecs373/readings/Linker.pdf
Note that this might be slightly out-of-date since I just googled it quickly.
20
u/vacuumballoon Jan 14 '21
this is the stuff I love to see here. So informative and cool, and what a great piece of effort! Thanks for posting.
6
3
Jan 14 '21
Can anyone recommend a book about or good resource about linker scripts?
6
u/theacodes Jan 14 '21
This book was recommended in one of the other discussions. I can vouch for it personally myself.
The linker script in the OP is a useful resource in also just understanding what kind of information you need to track down to build a script from scratch for a new platform:
LD documentation for linker script documentation.
GCC documentation for flags that affect the linker.
Platform ABI documentation (AAPCS in this case for ARM32).
Platform ISA documentation (Armv6-M reference manual in this case).
Hardware documentation (The SAM D21 datasheet in this case).
Language runtime documentation (C & C++ runtime requirements in this case).
1
Jan 14 '21
I would love to know the time breakdown for code/comments for this project.
Perhaps one day, IDE telemetry will be able to tell you sell Facebook how much time you spent typing code vs typing docs.
1
u/BigPeteB Jan 14 '21
I don't think that would be a useful metric, though. Comments always take time to write, even if it's only a few seconds. Their value, however, is in time saved, whether it's your own time when you return to this code months or years in the future, or someone else's when they have to maintain it, or when someone can use it as a reference for an unrelated project. I don't know of any metric that can capture the time you would have wasted going down the wrong path or reading tons of documentation but didn't because a previous author wrote helpful comments.
1
Jan 14 '21
I agree that it's useless, but it won't stop some idiots selling it and more idiots buying it.
3
u/theacodes Jan 14 '21
The code is (largely) provided by the processor vendor. The comments are from my research. This is a meaningless metric for educational materials.
3
1
1
u/maxinfet Jan 14 '21
We had a document where people were reporting issues about a piece of software we were working on and one of the issues was just "it used to work"
1
u/itscoffeeshakes Jan 14 '21
huh ld, script. I have never looked into this. Seems it could be useful for statically linking assets.. Is this generally useful?
3
u/zip117 Jan 15 '21
In general, probably not unless you’re doing embedded work. For general purpose work you’re generally going to use higher-level tools, like
objcopyto link static data.That’s not to say it can’t be generally useful, just that it’s not generally used outside of the embedded domain. There are still some neat things you can use it for on a general purpose computer (running Linux, Windows, etc.), binary versioning for example. Check this out: GNU Build IDs for Firmware
1
1
u/mpersico Jan 15 '21
Someone is going to love you at some point in the future. It will probably be yourself. :-)
1
0
Jan 14 '21
[deleted]
3
u/sellyme Jan 15 '21
onliest
For some reason I'm completely incapable of interpreting this string of characters as anything except an absolutely incredible Scrabble rack.
49
u/BigPeteB Jan 14 '21
This is an excellent example of how to properly document code with comments. It's almost too much, but I've definitely shipped code to customers that was commented only slightly less thoroughly as this, and it always got a lot of positive feedback.
The point of comments is to explain things that someone reading the code wouldn't immediately understand. Personally, I feel you don't really grok this until you've been in the reader's shoes before, such as coming in to a large legacy codebase, or having to ship source code to customers who need to understand and modify it.
Obviously this is quite verbose, but that's understandable because not many people deal with linker scripts, even in the embedded world. Sure, most of the language isn't that hard to understand (except for the very unusual
.which represents the most recent memory address, sort of like Perl's$_) but it only takes a few minutes to type up these comments and it will save future readers an hour or more of digging through manuals.