unsigned _forceLoadArchives : 1;
unsigned _textRelocations : 1;
unsigned _relocatable : 1;
+ unsigned _mergeCommonStrings: 1;
private:
LinkerOptions(const LinkerOptions&) LLVM_DELETED_FUNCTION;
def noinhibit_exec : Flag<["-"], "noinhibit-exec">,
HelpText<"Retain the executable output file whenever it is still usable">;
+
+def merge_strings : Flag<["-"], "merge-strings">,
+ HelpText<"Merge common strings across mergeable sections">;
if (llvm::opt::Arg *A = _inputArgs->getLastArg(ld::OPT_noinhibit_exec))
newArgs->AddFlagArg(A, _core.getOption(core::OPT_noinhibit_exec));
+ if (llvm::opt::Arg *A = _inputArgs->getLastArg(ld::OPT_merge_strings))
+ newArgs->AddFlagArg(A, _core.getOption(core::OPT_merge_strings));
+
// Copy search paths.
for (llvm::opt::arg_iterator it = _inputArgs->filtered_begin(ld::OPT_L),
ie = _inputArgs->filtered_end();
ret._outputCommands = args.hasArg(core::OPT_OCTOTHORPE_OCTOTHORPE_OCTOTHORPE);
ret._outputYAML = args.hasArg(core::OPT_emit_yaml);
ret._noInhibitExec = args.hasArg(core::OPT_noinhibit_exec);
+ ret._mergeCommonStrings = args.hasArg(core::OPT_merge_strings);
return std::move(ret);
}
def noinhibit_exec : Flag<["--"], "noinhibit-exec">,
HelpText<"Retain the executable output file whenever it is still usable">;
+
+def merge_strings : Flag<["-"], "merge-strings">,
+ HelpText<"Merge common strings across mergeable sections">;
// Sections that have merge string property
std::vector<const Elf_Shdr *> mergeStringSections;
+ bool doStringsMerge = _elfTargetInfo.getLinkerOptions()._mergeCommonStrings;
+
// Handle: SHT_REL and SHT_RELA sections:
// Increment over the sections, when REL/RELA section types are found add
// the contents to the RelocationReferences map.
if (section->sh_size == 0)
continue;
- int64_t sectionFlags = section->sh_flags;
- sectionFlags &= ~llvm::ELF::SHF_ALLOC;
+ if (doStringsMerge) {
+ int64_t sectionFlags = section->sh_flags;
+ sectionFlags &= ~llvm::ELF::SHF_ALLOC;
- // If the section have mergeable strings, the linker would
- // need to split the section into multiple atoms and mark them
- // mergeByContent
- if ((section->sh_entsize < 2) &&
- (sectionFlags == (llvm::ELF::SHF_MERGE | llvm::ELF::SHF_STRINGS))) {
- mergeStringSections.push_back(section);
- continue;
+ // If the section have mergeable strings, the linker would
+ // need to split the section into multiple atoms and mark them
+ // mergeByContent
+ if ((section->sh_entsize < 2) &&
+ (sectionFlags == (llvm::ELF::SHF_MERGE | llvm::ELF::SHF_STRINGS))) {
+ mergeStringSections.push_back(section);
+ continue;
+ }
}
// Create a sectionSymbols entry for every progbits section.
// If its a merge section, the atoms have already
// been created, lets not create the atoms again
- int64_t sectionFlags = section->sh_flags;
- sectionFlags &= ~llvm::ELF::SHF_ALLOC;
- if ((section->sh_entsize < 2) &&
- (sectionFlags == (llvm::ELF::SHF_MERGE | llvm::ELF::SHF_STRINGS))) {
- continue;
+ if (doStringsMerge) {
+ int64_t sectionFlags = section->sh_flags;
+ sectionFlags &= ~llvm::ELF::SHF_ALLOC;
+ if ((section->sh_entsize < 2) &&
+ (sectionFlags == (llvm::ELF::SHF_MERGE | llvm::ELF::SHF_STRINGS))) {
+ continue;
+ }
}
StringRef symbolName;
// If the section has mergeable strings, then make the relocation
// refer to the MergeAtom to allow deduping
- if (shdr && (shdr->sh_entsize < 2) &&
+ if (doStringsMerge && shdr && (shdr->sh_entsize < 2) &&
(sectionFlags == (llvm::ELF::SHF_MERGE | llvm::ELF::SHF_STRINGS))) {
const MergeSectionKey ms(shdr, ri->addend());
if (_mergedSectionMap.find(ms) == _mergedSectionMap.end()) {
-RUN: lld-core -reader ELF -writer ELF -o %t1 %p/Inputs/foo.o.x86-64 \
-RUN: %p/Inputs/bar.o.x86-64
+RUN: lld-core -merge-strings=true -reader ELF -writer ELF \
+RUN: -o %t1 %p/Inputs/foo.o.x86-64 %p/Inputs/bar.o.x86-64
RUN: llvm-objdump -s %t1 | FileCheck -check-prefix=mergeAtoms %s
mergeAtoms: 1000 62617200 666f6f00 bar.foo.
-RUN: lld-core -reader ELF %p/Inputs/constants-merge.x86-64 | FileCheck -check-prefix=mergeAtoms %s
+RUN: lld-core -merge-strings=true -reader ELF %p/Inputs/constants-merge.x86-64 | FileCheck -check-prefix=mergeAtoms %s
mergeAtoms: - name: foo
mergeAtoms: scope: global
-RUN: lld-core -reader ELF %p/Inputs/reloc-test.elf-i386 | FileCheck %s -check-prefix ELF-i386
+RUN: lld-core -merge-strings=true -reader ELF %p/Inputs/reloc-test.elf-i386 | FileCheck %s -check-prefix ELF-i386
ELF-i386: defined-atoms:
ELF-i386: - ref-name: L000
llvm::cl::opt<bool>
cmdLineDoLayoutPass("layout-pass", llvm::cl::desc("Run pass to layout atoms"));
+llvm::cl::opt<bool>
+cmdLineDoMergeStrings(
+ "merge-strings",
+ llvm::cl::desc("make common strings merge possible"));
+
llvm::cl::opt<bool> cmdLineUndefinesIsError(
"undefines-are-errors",
llvm::cl::desc("Any undefined symbols at end is an error"));
lo._forceLoadArchives = cmdLineForceLoad;
lo._outputKind = OutputKind::Executable;
lo._entrySymbol = cmdLineEntryPoint;
+ lo._mergeCommonStrings = cmdLineDoMergeStrings;
switch (archSelected) {
case i386: