Skip to content

Commit e6963be

Browse files
author
George Rimar
committedMar 25, 2019
[llvm-objcopy] - Refactor the code. NFC.
The idea of the patch is about to move out the code to a new helper static functions (to reduce the size of 'handleArgs' and to isolate the parts of it's logic). Differential revision: https://reviews.llvm.org/D59762 llvm-svn: 356889
1 parent 948e37c commit e6963be

File tree

1 file changed

+106
-96
lines changed

1 file changed

+106
-96
lines changed
 

‎llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp

+106-96
Original file line numberDiff line numberDiff line change
@@ -298,110 +298,94 @@ static bool isUnneededSymbol(const Symbol &Sym) {
298298
Sym.Type != STT_FILE && Sym.Type != STT_SECTION;
299299
}
300300

301-
// This function handles the high level operations of GNU objcopy including
302-
// handling command line options. It's important to outline certain properties
303-
// we expect to hold of the command line operations. Any operation that "keeps"
304-
// should keep regardless of a remove. Additionally any removal should respect
305-
// any previous removals. Lastly whether or not something is removed shouldn't
306-
// depend a) on the order the options occur in or b) on some opaque priority
307-
// system. The only priority is that keeps/copies overrule removes.
308-
static Error handleArgs(const CopyConfig &Config, Object &Obj,
309-
const Reader &Reader, ElfType OutputElfType) {
310-
311-
if (!Config.SplitDWO.empty())
312-
if (Error E =
313-
splitDWOToFile(Config, Reader, Config.SplitDWO, OutputElfType))
314-
return E;
315-
316-
if (Config.OutputArch) {
317-
Obj.Machine = Config.OutputArch.getValue().EMachine;
318-
Obj.OSABI = Config.OutputArch.getValue().OSABI;
319-
}
320-
301+
static Error updateAndRemoveSymbols(const CopyConfig &Config, Object &Obj) {
321302
// TODO: update or remove symbols only if there is an option that affects
322303
// them.
323-
if (Obj.SymbolTable) {
324-
Obj.SymbolTable->updateSymbols([&](Symbol &Sym) {
325-
// Common and undefined symbols don't make sense as local symbols, and can
326-
// even cause crashes if we localize those, so skip them.
327-
if (!Sym.isCommon() && Sym.getShndx() != SHN_UNDEF &&
328-
((Config.LocalizeHidden &&
329-
(Sym.Visibility == STV_HIDDEN || Sym.Visibility == STV_INTERNAL)) ||
330-
is_contained(Config.SymbolsToLocalize, Sym.Name)))
331-
Sym.Binding = STB_LOCAL;
332-
333-
// Note: these two globalize flags have very similar names but different
334-
// meanings:
335-
//
336-
// --globalize-symbol: promote a symbol to global
337-
// --keep-global-symbol: all symbols except for these should be made local
338-
//
339-
// If --globalize-symbol is specified for a given symbol, it will be
340-
// global in the output file even if it is not included via
341-
// --keep-global-symbol. Because of that, make sure to check
342-
// --globalize-symbol second.
343-
if (!Config.SymbolsToKeepGlobal.empty() &&
344-
!is_contained(Config.SymbolsToKeepGlobal, Sym.Name) &&
345-
Sym.getShndx() != SHN_UNDEF)
346-
Sym.Binding = STB_LOCAL;
347-
348-
if (is_contained(Config.SymbolsToGlobalize, Sym.Name) &&
349-
Sym.getShndx() != SHN_UNDEF)
350-
Sym.Binding = STB_GLOBAL;
351-
352-
if (is_contained(Config.SymbolsToWeaken, Sym.Name) &&
353-
Sym.Binding == STB_GLOBAL)
354-
Sym.Binding = STB_WEAK;
355-
356-
if (Config.Weaken && Sym.Binding == STB_GLOBAL &&
357-
Sym.getShndx() != SHN_UNDEF)
358-
Sym.Binding = STB_WEAK;
359-
360-
const auto I = Config.SymbolsToRename.find(Sym.Name);
361-
if (I != Config.SymbolsToRename.end())
362-
Sym.Name = I->getValue();
363-
364-
if (!Config.SymbolsPrefix.empty() && Sym.Type != STT_SECTION)
365-
Sym.Name = (Config.SymbolsPrefix + Sym.Name).str();
366-
});
367-
368-
// The purpose of this loop is to mark symbols referenced by sections
369-
// (like GroupSection or RelocationSection). This way, we know which
370-
// symbols are still 'needed' and which are not.
371-
if (Config.StripUnneeded || !Config.UnneededSymbolsToRemove.empty()) {
372-
for (auto &Section : Obj.sections())
373-
Section.markSymbols();
374-
}
304+
if (!Obj.SymbolTable)
305+
return Error::success();
306+
307+
Obj.SymbolTable->updateSymbols([&](Symbol &Sym) {
308+
// Common and undefined symbols don't make sense as local symbols, and can
309+
// even cause crashes if we localize those, so skip them.
310+
if (!Sym.isCommon() && Sym.getShndx() != SHN_UNDEF &&
311+
((Config.LocalizeHidden &&
312+
(Sym.Visibility == STV_HIDDEN || Sym.Visibility == STV_INTERNAL)) ||
313+
is_contained(Config.SymbolsToLocalize, Sym.Name)))
314+
Sym.Binding = STB_LOCAL;
315+
316+
// Note: these two globalize flags have very similar names but different
317+
// meanings:
318+
//
319+
// --globalize-symbol: promote a symbol to global
320+
// --keep-global-symbol: all symbols except for these should be made local
321+
//
322+
// If --globalize-symbol is specified for a given symbol, it will be
323+
// global in the output file even if it is not included via
324+
// --keep-global-symbol. Because of that, make sure to check
325+
// --globalize-symbol second.
326+
if (!Config.SymbolsToKeepGlobal.empty() &&
327+
!is_contained(Config.SymbolsToKeepGlobal, Sym.Name) &&
328+
Sym.getShndx() != SHN_UNDEF)
329+
Sym.Binding = STB_LOCAL;
330+
331+
if (is_contained(Config.SymbolsToGlobalize, Sym.Name) &&
332+
Sym.getShndx() != SHN_UNDEF)
333+
Sym.Binding = STB_GLOBAL;
334+
335+
if (is_contained(Config.SymbolsToWeaken, Sym.Name) &&
336+
Sym.Binding == STB_GLOBAL)
337+
Sym.Binding = STB_WEAK;
338+
339+
if (Config.Weaken && Sym.Binding == STB_GLOBAL &&
340+
Sym.getShndx() != SHN_UNDEF)
341+
Sym.Binding = STB_WEAK;
342+
343+
const auto I = Config.SymbolsToRename.find(Sym.Name);
344+
if (I != Config.SymbolsToRename.end())
345+
Sym.Name = I->getValue();
346+
347+
if (!Config.SymbolsPrefix.empty() && Sym.Type != STT_SECTION)
348+
Sym.Name = (Config.SymbolsPrefix + Sym.Name).str();
349+
});
350+
351+
// The purpose of this loop is to mark symbols referenced by sections
352+
// (like GroupSection or RelocationSection). This way, we know which
353+
// symbols are still 'needed' and which are not.
354+
if (Config.StripUnneeded || !Config.UnneededSymbolsToRemove.empty()) {
355+
for (auto &Section : Obj.sections())
356+
Section.markSymbols();
357+
}
375358

376-
auto RemoveSymbolsPred = [&](const Symbol &Sym) {
377-
if (is_contained(Config.SymbolsToKeep, Sym.Name) ||
378-
(Config.KeepFileSymbols && Sym.Type == STT_FILE))
379-
return false;
359+
auto RemoveSymbolsPred = [&](const Symbol &Sym) {
360+
if (is_contained(Config.SymbolsToKeep, Sym.Name) ||
361+
(Config.KeepFileSymbols && Sym.Type == STT_FILE))
362+
return false;
380363

381-
if ((Config.DiscardMode == DiscardType::All ||
382-
(Config.DiscardMode == DiscardType::Locals &&
383-
StringRef(Sym.Name).startswith(".L"))) &&
384-
Sym.Binding == STB_LOCAL && Sym.getShndx() != SHN_UNDEF &&
385-
Sym.Type != STT_FILE && Sym.Type != STT_SECTION)
386-
return true;
364+
if ((Config.DiscardMode == DiscardType::All ||
365+
(Config.DiscardMode == DiscardType::Locals &&
366+
StringRef(Sym.Name).startswith(".L"))) &&
367+
Sym.Binding == STB_LOCAL && Sym.getShndx() != SHN_UNDEF &&
368+
Sym.Type != STT_FILE && Sym.Type != STT_SECTION)
369+
return true;
387370

388-
if (Config.StripAll || Config.StripAllGNU)
389-
return true;
371+
if (Config.StripAll || Config.StripAllGNU)
372+
return true;
390373

391-
if (is_contained(Config.SymbolsToRemove, Sym.Name))
392-
return true;
374+
if (is_contained(Config.SymbolsToRemove, Sym.Name))
375+
return true;
393376

394-
if ((Config.StripUnneeded ||
395-
is_contained(Config.UnneededSymbolsToRemove, Sym.Name)) &&
396-
isUnneededSymbol(Sym))
397-
return true;
377+
if ((Config.StripUnneeded ||
378+
is_contained(Config.UnneededSymbolsToRemove, Sym.Name)) &&
379+
isUnneededSymbol(Sym))
380+
return true;
398381

399-
return false;
400-
};
401-
if (Error E = Obj.removeSymbols(RemoveSymbolsPred))
402-
return E;
403-
}
382+
return false;
383+
};
384+
385+
return Obj.removeSymbols(RemoveSymbolsPred);
386+
}
404387

388+
static Error replaceAndRemoveSections(const CopyConfig &Config, Object &Obj) {
405389
SectionPred RemovePred = [](const SectionBase &) { return false; };
406390

407391
// Removes:
@@ -535,7 +519,33 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj,
535519
return &Obj.addSection<DecompressedSection>(*CS);
536520
});
537521

538-
if (Error E = Obj.removeSections(RemovePred))
522+
return Obj.removeSections(RemovePred);
523+
}
524+
525+
// This function handles the high level operations of GNU objcopy including
526+
// handling command line options. It's important to outline certain properties
527+
// we expect to hold of the command line operations. Any operation that "keeps"
528+
// should keep regardless of a remove. Additionally any removal should respect
529+
// any previous removals. Lastly whether or not something is removed shouldn't
530+
// depend a) on the order the options occur in or b) on some opaque priority
531+
// system. The only priority is that keeps/copies overrule removes.
532+
static Error handleArgs(const CopyConfig &Config, Object &Obj,
533+
const Reader &Reader, ElfType OutputElfType) {
534+
535+
if (!Config.SplitDWO.empty())
536+
if (Error E =
537+
splitDWOToFile(Config, Reader, Config.SplitDWO, OutputElfType))
538+
return E;
539+
540+
if (Config.OutputArch) {
541+
Obj.Machine = Config.OutputArch.getValue().EMachine;
542+
Obj.OSABI = Config.OutputArch.getValue().OSABI;
543+
}
544+
545+
if (Error E = updateAndRemoveSymbols(Config, Obj))
546+
return E;
547+
548+
if (Error E = replaceAndRemoveSections(Config, Obj))
539549
return E;
540550

541551
if (!Config.SectionsToRename.empty()) {

0 commit comments

Comments
 (0)
Please sign in to comment.