This is an archive of the discontinued LLVM Phabricator instance.

Consolidate global variables to a single place
Needs ReviewPublic

Authored by ruiu on Nov 26 2019, 11:14 PM.

Details

Summary

The aim of this patch is the same as https://reviews.llvm.org/D70421
but I took a different approach. I just moved all global variables
to Driver.cpp so that we don't forget to initialize them on startup.

Event Timeline

ruiu created this revision.Nov 26 2019, 11:14 PM
Herald added a project: Restricted Project. · View Herald Transcript

What about static variables?

Like:

struct Out {
  static uint8_t *bufferStart;
  static uint8_t first;
  static PhdrEntry *tlsPhdr;
  static OutputSection *elfHeader;
  static OutputSection *programHeaders;
  static OutputSection *preinitArray;
  static OutputSection *initArray;
  static OutputSection *finiArray;
};

or SharedFile::vernauxNum

or

struct ElfSym {
  // __bss_start
  static Defined *bss;

  // etext and _etext
  static Defined *etext1;
  static Defined *etext2;

or things like

static bool isInGroup;
static uint32_t nextGroupId;

I think would be good to get rid of all such statics.
For Out we should probably have Out out, just like for InStruct in.
Some others probably can be replaced with a global variables (or may be eliminated).

That's why I've suggested a separate file for them. I think it worth to push them out and
comment them well. We should probably only allow using statics for simple situations like

if (config->andFeatures & (GNU_PROPERTY_AARCH64_FEATURE_1_BTI |
                           GNU_PROPERTY_AARCH64_FEATURE_1_PAC)) {
  static AArch64BtiPac t;
  return &t;
}
static AArch64 t;
return &t;

and restrict them for everything else in favor of globals.
We'll continue to have a mess until isolate all things that requires re-initialization I believe.

There are a couple of downsides to putting all the globals in one place. I think the LLD codebase is probably small enough for them to not be too serious:

  • It couples pretty much every file to a single place. Touching this file means recompiling everything.
  • It can make the code harder to reason about as any file can see all the globals, and can potentially modify them. This is a possible argument for not promoting statics to globals as the scope of a static is much easier to reason about.

I don't have a strong opinion about which is best. I can see the above patch making it easier to remember to initialize globals, and I think that there is already enough global state via config to make this only a small impact to understanding the code.

There are some static variables and static data members. Moving them to a central place will change their linkage from internal to external, and thus increase their scope. An alternative is to declare initFoobar() for files that define variables with static storage duration and call all initFoobar() in a central place.