@@ -298,110 +298,94 @@ static bool isUnneededSymbol(const Symbol &Sym) {
298
298
Sym.Type != STT_FILE && Sym.Type != STT_SECTION;
299
299
}
300
300
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) {
321
302
// TODO: update or remove symbols only if there is an option that affects
322
303
// 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
+ }
375
358
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 ;
380
363
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 ;
387
370
388
- if (Config.StripAll || Config.StripAllGNU )
389
- return true ;
371
+ if (Config.StripAll || Config.StripAllGNU )
372
+ return true ;
390
373
391
- if (is_contained (Config.SymbolsToRemove , Sym.Name ))
392
- return true ;
374
+ if (is_contained (Config.SymbolsToRemove , Sym.Name ))
375
+ return true ;
393
376
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 ;
398
381
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
+ }
404
387
388
+ static Error replaceAndRemoveSections (const CopyConfig &Config, Object &Obj) {
405
389
SectionPred RemovePred = [](const SectionBase &) { return false ; };
406
390
407
391
// Removes:
@@ -535,7 +519,33 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj,
535
519
return &Obj.addSection <DecompressedSection>(*CS);
536
520
});
537
521
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))
539
549
return E;
540
550
541
551
if (!Config.SectionsToRename .empty ()) {
0 commit comments