Rewrite CommonInputSection as a synthetic input section.
A CommonInputSection is a section containing all common symbols. That was an input section but was abstracted in a different way than the synthetic input sections because it was written before the synthetic input section was invented. This patch rewrites CommonInputSection as a synthetic input section so that it behaves better with other sections. llvm-svn: 286053
This commit is contained in:
parent
9e0297b8bc
commit
e8a6102fa9
|
@ -825,31 +825,6 @@ bool MipsAbiFlagsInputSection<ELFT>::classof(const InputSectionData *S) {
|
||||||
return S->kind() == InputSectionBase<ELFT>::MipsAbiFlags;
|
return S->kind() == InputSectionBase<ELFT>::MipsAbiFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT>
|
|
||||||
InputSection<ELFT> InputSection<ELFT>::createCommonInputSection(
|
|
||||||
std::vector<DefinedCommon *> Syms) {
|
|
||||||
// Sort the common symbols by alignment as an heuristic to pack them better.
|
|
||||||
std::stable_sort(Syms.begin(), Syms.end(),
|
|
||||||
[](const DefinedCommon *A, const DefinedCommon *B) {
|
|
||||||
return A->Alignment > B->Alignment;
|
|
||||||
});
|
|
||||||
|
|
||||||
size_t Size = 0;
|
|
||||||
uintX_t Alignment = 1;
|
|
||||||
for (DefinedCommon *Sym : Syms) {
|
|
||||||
Alignment = std::max<uintX_t>(Alignment, Sym->Alignment);
|
|
||||||
Size = alignTo(Size, Sym->Alignment);
|
|
||||||
|
|
||||||
// Compute symbol offset relative to beginning of input section.
|
|
||||||
Sym->Offset = Size;
|
|
||||||
Size += Sym->Size;
|
|
||||||
}
|
|
||||||
ArrayRef<uint8_t> Data = makeArrayRef<uint8_t>(nullptr, Size);
|
|
||||||
InputSection Ret(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, Alignment, Data, "");
|
|
||||||
Ret.Live = true;
|
|
||||||
return Ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template class elf::InputSectionBase<ELF32LE>;
|
template class elf::InputSectionBase<ELF32LE>;
|
||||||
template class elf::InputSectionBase<ELF32BE>;
|
template class elf::InputSectionBase<ELF32BE>;
|
||||||
template class elf::InputSectionBase<ELF64LE>;
|
template class elf::InputSectionBase<ELF64LE>;
|
||||||
|
|
|
@ -273,14 +273,6 @@ public:
|
||||||
template <class RelTy>
|
template <class RelTy>
|
||||||
void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
|
void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
|
||||||
|
|
||||||
// Common symbols don't belong to any section. But it is easier for us
|
|
||||||
// to handle them as if they belong to some input section. So we defined
|
|
||||||
// this section that "contains" all common symbols.
|
|
||||||
static InputSection<ELFT> *CommonInputSection;
|
|
||||||
|
|
||||||
static InputSection<ELFT>
|
|
||||||
createCommonInputSection(std::vector<DefinedCommon *> Syms);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <class RelTy>
|
template <class RelTy>
|
||||||
void copyRelocations(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
|
void copyRelocations(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
|
||||||
|
@ -294,9 +286,6 @@ private:
|
||||||
llvm::TinyPtrVector<const Thunk<ELFT> *> Thunks;
|
llvm::TinyPtrVector<const Thunk<ELFT> *> Thunks;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class ELFT>
|
|
||||||
InputSection<ELFT> *InputSection<ELFT>::CommonInputSection;
|
|
||||||
|
|
||||||
// MIPS .reginfo section provides information on the registers used by the code
|
// MIPS .reginfo section provides information on the registers used by the code
|
||||||
// in the object file. Linker should collect this information and write a single
|
// in the object file. Linker should collect this information and write a single
|
||||||
// .reginfo section in the output file. The output section contains a union of
|
// .reginfo section in the output file. The output section contains a union of
|
||||||
|
|
|
@ -202,13 +202,9 @@ void LinkerScript<ELFT>::computeInputSections(InputSectionDescription *I) {
|
||||||
if (elf::ObjectFile<ELFT> *F = S->getFile())
|
if (elf::ObjectFile<ELFT> *F = S->getFile())
|
||||||
Filename = sys::path::filename(F->getName());
|
Filename = sys::path::filename(F->getName());
|
||||||
|
|
||||||
if (!I->FilePat.match(Filename) || Pat.ExcludedFilePat.match(Filename))
|
if (I->FilePat.match(Filename) && !Pat.ExcludedFilePat.match(Filename) &&
|
||||||
continue;
|
Pat.SectionPat.match(S->Name))
|
||||||
|
|
||||||
if (Pat.SectionPat.match(S->Name))
|
|
||||||
I->Sections.push_back(S);
|
I->Sections.push_back(S);
|
||||||
if (Pat.SectionPat.match("COMMON"))
|
|
||||||
I->Sections.push_back(InputSection<ELFT>::CommonInputSection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort sections as instructed by SORT-family commands and --sort-section
|
// Sort sections as instructed by SORT-family commands and --sort-section
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
#include "Strings.h"
|
#include "Strings.h"
|
||||||
#include "SymbolTable.h"
|
#include "SymbolTable.h"
|
||||||
|
#include "SyntheticSections.h"
|
||||||
#include "Target.h"
|
#include "Target.h"
|
||||||
#include "lld/Core/Parallel.h"
|
#include "lld/Core/Parallel.h"
|
||||||
#include "llvm/Support/Dwarf.h"
|
#include "llvm/Support/Dwarf.h"
|
||||||
|
@ -1556,7 +1557,7 @@ SymbolTableSection<ELFT>::getOutputSection(SymbolBody *Sym) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SymbolBody::DefinedCommonKind:
|
case SymbolBody::DefinedCommonKind:
|
||||||
return InputSection<ELFT>::CommonInputSection->OutSec;
|
return In<ELFT>::Common->OutSec;
|
||||||
case SymbolBody::SharedKind:
|
case SymbolBody::SharedKind:
|
||||||
if (cast<SharedSymbol<ELFT>>(Sym)->needsCopy())
|
if (cast<SharedSymbol<ELFT>>(Sym)->needsCopy())
|
||||||
return Out<ELFT>::Bss;
|
return Out<ELFT>::Bss;
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "InputFiles.h"
|
#include "InputFiles.h"
|
||||||
#include "InputSection.h"
|
#include "InputSection.h"
|
||||||
#include "OutputSections.h"
|
#include "OutputSections.h"
|
||||||
|
#include "SyntheticSections.h"
|
||||||
#include "Target.h"
|
#include "Target.h"
|
||||||
|
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
|
@ -69,8 +70,7 @@ static typename ELFT::uint getSymVA(const SymbolBody &Body,
|
||||||
return VA;
|
return VA;
|
||||||
}
|
}
|
||||||
case SymbolBody::DefinedCommonKind:
|
case SymbolBody::DefinedCommonKind:
|
||||||
return InputSection<ELFT>::CommonInputSection->OutSec->getVA() +
|
return In<ELFT>::Common->OutSec->getVA() + In<ELFT>::Common->OutSecOff +
|
||||||
InputSection<ELFT>::CommonInputSection->OutSecOff +
|
|
||||||
cast<DefinedCommon>(Body).Offset;
|
cast<DefinedCommon>(Body).Offset;
|
||||||
case SymbolBody::SharedKind: {
|
case SymbolBody::SharedKind: {
|
||||||
auto &SS = cast<SharedSymbol<ELFT>>(Body);
|
auto &SS = cast<SharedSymbol<ELFT>>(Body);
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "Memory.h"
|
#include "Memory.h"
|
||||||
#include "OutputSections.h"
|
#include "OutputSections.h"
|
||||||
#include "Strings.h"
|
#include "Strings.h"
|
||||||
|
#include "SymbolTable.h"
|
||||||
|
|
||||||
#include "llvm/Support/Endian.h"
|
#include "llvm/Support/Endian.h"
|
||||||
#include "llvm/Support/MD5.h"
|
#include "llvm/Support/MD5.h"
|
||||||
|
@ -37,6 +38,43 @@ using namespace llvm::support::endian;
|
||||||
using namespace lld;
|
using namespace lld;
|
||||||
using namespace lld::elf;
|
using namespace lld::elf;
|
||||||
|
|
||||||
|
template <class ELFT> static std::vector<DefinedCommon *> getCommonSymbols() {
|
||||||
|
std::vector<DefinedCommon *> V;
|
||||||
|
for (Symbol *S : Symtab<ELFT>::X->getSymbols())
|
||||||
|
if (auto *B = dyn_cast<DefinedCommon>(S->body()))
|
||||||
|
V.push_back(B);
|
||||||
|
return V;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find all common symbols and allocate space for them.
|
||||||
|
template <class ELFT>
|
||||||
|
CommonSection<ELFT>::CommonSection()
|
||||||
|
: InputSection<ELFT>(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, 1,
|
||||||
|
ArrayRef<uint8_t>(), "COMMON") {
|
||||||
|
this->Live = true;
|
||||||
|
|
||||||
|
// Sort the common symbols by alignment as an heuristic to pack them better.
|
||||||
|
std::vector<DefinedCommon *> Syms = getCommonSymbols<ELFT>();
|
||||||
|
std::stable_sort(Syms.begin(), Syms.end(),
|
||||||
|
[](const DefinedCommon *A, const DefinedCommon *B) {
|
||||||
|
return A->Alignment > B->Alignment;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assign offsets to symbols.
|
||||||
|
size_t Size = 0;
|
||||||
|
size_t Alignment = 1;
|
||||||
|
for (DefinedCommon *Sym : Syms) {
|
||||||
|
Alignment = std::max(Alignment, Sym->Alignment);
|
||||||
|
Size = alignTo(Size, Sym->Alignment);
|
||||||
|
|
||||||
|
// Compute symbol offset relative to beginning of input section.
|
||||||
|
Sym->Offset = Size;
|
||||||
|
Size += Sym->Size;
|
||||||
|
}
|
||||||
|
this->Alignment = Alignment;
|
||||||
|
this->Data = makeArrayRef<uint8_t>(nullptr, Size);
|
||||||
|
}
|
||||||
|
|
||||||
static ArrayRef<uint8_t> createInterp() {
|
static ArrayRef<uint8_t> createInterp() {
|
||||||
// StringSaver guarantees that the returned string ends with '\0'.
|
// StringSaver guarantees that the returned string ends with '\0'.
|
||||||
StringRef S = Saver.save(Config->DynamicLinker);
|
StringRef S = Saver.save(Config->DynamicLinker);
|
||||||
|
@ -111,6 +149,11 @@ void BuildIdHexstring<ELFT>::writeBuildId(MutableArrayRef<uint8_t> Buf) {
|
||||||
Config->BuildIdVector.size());
|
Config->BuildIdVector.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template class elf::CommonSection<ELF32LE>;
|
||||||
|
template class elf::CommonSection<ELF32BE>;
|
||||||
|
template class elf::CommonSection<ELF64LE>;
|
||||||
|
template class elf::CommonSection<ELF64BE>;
|
||||||
|
|
||||||
template class elf::InterpSection<ELF32LE>;
|
template class elf::InterpSection<ELF32LE>;
|
||||||
template class elf::InterpSection<ELF32BE>;
|
template class elf::InterpSection<ELF32BE>;
|
||||||
template class elf::InterpSection<ELF64LE>;
|
template class elf::InterpSection<ELF64LE>;
|
||||||
|
|
|
@ -15,11 +15,19 @@
|
||||||
namespace lld {
|
namespace lld {
|
||||||
namespace elf {
|
namespace elf {
|
||||||
|
|
||||||
|
// This class represents a BSS section containing all common symbols.
|
||||||
|
template <class ELFT> class CommonSection final : public InputSection<ELFT> {
|
||||||
|
public:
|
||||||
|
CommonSection();
|
||||||
|
};
|
||||||
|
|
||||||
|
// .interp section.
|
||||||
template <class ELFT> class InterpSection final : public InputSection<ELFT> {
|
template <class ELFT> class InterpSection final : public InputSection<ELFT> {
|
||||||
public:
|
public:
|
||||||
InterpSection();
|
InterpSection();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// .note.gnu.build-id section.
|
||||||
template <class ELFT> class BuildIdSection : public InputSection<ELFT> {
|
template <class ELFT> class BuildIdSection : public InputSection<ELFT> {
|
||||||
public:
|
public:
|
||||||
virtual void writeBuildId(llvm::MutableArrayRef<uint8_t> Buf) = 0;
|
virtual void writeBuildId(llvm::MutableArrayRef<uint8_t> Buf) = 0;
|
||||||
|
@ -67,13 +75,13 @@ public:
|
||||||
// Linker generated sections which can be used as inputs.
|
// Linker generated sections which can be used as inputs.
|
||||||
template <class ELFT> struct In {
|
template <class ELFT> struct In {
|
||||||
static BuildIdSection<ELFT> *BuildId;
|
static BuildIdSection<ELFT> *BuildId;
|
||||||
|
static CommonSection<ELFT> *Common;
|
||||||
static InterpSection<ELFT> *Interp;
|
static InterpSection<ELFT> *Interp;
|
||||||
static std::vector<InputSection<ELFT> *> Sections;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class ELFT> BuildIdSection<ELFT> *In<ELFT>::BuildId;
|
template <class ELFT> BuildIdSection<ELFT> *In<ELFT>::BuildId;
|
||||||
|
template <class ELFT> CommonSection<ELFT> *In<ELFT>::Common;
|
||||||
template <class ELFT> InterpSection<ELFT> *In<ELFT>::Interp;
|
template <class ELFT> InterpSection<ELFT> *In<ELFT>::Interp;
|
||||||
template <class ELFT> std::vector<InputSection<ELFT> *> In<ELFT>::Sections;
|
|
||||||
|
|
||||||
} // namespace elf
|
} // namespace elf
|
||||||
} // namespace lld
|
} // namespace lld
|
||||||
|
|
|
@ -105,6 +105,11 @@ StringRef elf::getOutputSectionName(StringRef Name) {
|
||||||
return Prefix;
|
return Prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CommonSection is identified as "COMMON" in linker scripts.
|
||||||
|
// By default, it should go to .bss section.
|
||||||
|
if (Name == "COMMON")
|
||||||
|
return ".bss";
|
||||||
|
|
||||||
// ".zdebug_" is a prefix for ZLIB-compressed sections.
|
// ".zdebug_" is a prefix for ZLIB-compressed sections.
|
||||||
// Because we decompressed input sections, we want to remove 'z'.
|
// Because we decompressed input sections, we want to remove 'z'.
|
||||||
if (Name.startswith(".zdebug_"))
|
if (Name.startswith(".zdebug_"))
|
||||||
|
@ -130,14 +135,6 @@ template <class ELFT> void elf::writeResult() {
|
||||||
Writer<ELFT>().run();
|
Writer<ELFT>().run();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> static std::vector<DefinedCommon *> getCommonSymbols() {
|
|
||||||
std::vector<DefinedCommon *> V;
|
|
||||||
for (Symbol *S : Symtab<ELFT>::X->getSymbols())
|
|
||||||
if (auto *B = dyn_cast<DefinedCommon>(S->body()))
|
|
||||||
V.push_back(B);
|
|
||||||
return V;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The main function of the writer.
|
// The main function of the writer.
|
||||||
template <class ELFT> void Writer<ELFT>::run() {
|
template <class ELFT> void Writer<ELFT>::run() {
|
||||||
createSyntheticSections();
|
createSyntheticSections();
|
||||||
|
@ -146,10 +143,6 @@ template <class ELFT> void Writer<ELFT>::run() {
|
||||||
if (Target->NeedsThunks)
|
if (Target->NeedsThunks)
|
||||||
forEachRelSec(createThunks<ELFT>);
|
forEachRelSec(createThunks<ELFT>);
|
||||||
|
|
||||||
InputSection<ELFT> Common =
|
|
||||||
InputSection<ELFT>::createCommonInputSection(getCommonSymbols<ELFT>());
|
|
||||||
InputSection<ELFT>::CommonInputSection = &Common;
|
|
||||||
|
|
||||||
Script<ELFT>::X->OutputSections = &OutputSections;
|
Script<ELFT>::X->OutputSections = &OutputSections;
|
||||||
if (ScriptConfig->HasSections) {
|
if (ScriptConfig->HasSections) {
|
||||||
Script<ELFT>::X->createSections(Factory);
|
Script<ELFT>::X->createSections(Factory);
|
||||||
|
@ -234,8 +227,12 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
|
||||||
Out<ELFT>::ProgramHeaders = make<OutputSectionBase<ELFT>>("", 0, SHF_ALLOC);
|
Out<ELFT>::ProgramHeaders = make<OutputSectionBase<ELFT>>("", 0, SHF_ALLOC);
|
||||||
Out<ELFT>::ProgramHeaders->updateAlignment(sizeof(uintX_t));
|
Out<ELFT>::ProgramHeaders->updateAlignment(sizeof(uintX_t));
|
||||||
|
|
||||||
if (needsInterpSection<ELFT>())
|
if (needsInterpSection<ELFT>()) {
|
||||||
In<ELFT>::Interp = make<InterpSection<ELFT>>();
|
In<ELFT>::Interp = make<InterpSection<ELFT>>();
|
||||||
|
Symtab<ELFT>::X->Sections.push_back(In<ELFT>::Interp);
|
||||||
|
} else {
|
||||||
|
In<ELFT>::Interp = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (!Symtab<ELFT>::X->getSharedFiles().empty() || Config->Pic) {
|
if (!Symtab<ELFT>::X->getSharedFiles().empty() || Config->Pic) {
|
||||||
Out<ELFT>::DynSymTab =
|
Out<ELFT>::DynSymTab =
|
||||||
|
@ -284,8 +281,17 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
|
||||||
In<ELFT>::BuildId = make<BuildIdUuid<ELFT>>();
|
In<ELFT>::BuildId = make<BuildIdUuid<ELFT>>();
|
||||||
else if (Config->BuildId == BuildIdKind::Hexstring)
|
else if (Config->BuildId == BuildIdKind::Hexstring)
|
||||||
In<ELFT>::BuildId = make<BuildIdHexstring<ELFT>>();
|
In<ELFT>::BuildId = make<BuildIdHexstring<ELFT>>();
|
||||||
|
else
|
||||||
|
In<ELFT>::BuildId = nullptr;
|
||||||
|
|
||||||
In<ELFT>::Sections = {In<ELFT>::BuildId, In<ELFT>::Interp};
|
if (In<ELFT>::BuildId)
|
||||||
|
Symtab<ELFT>::X->Sections.push_back(In<ELFT>::BuildId);
|
||||||
|
|
||||||
|
CommonSection<ELFT> *Common = make<CommonSection<ELFT>>();
|
||||||
|
if (!Common->Data.empty()) {
|
||||||
|
In<ELFT>::Common = Common;
|
||||||
|
Symtab<ELFT>::X->Sections.push_back(Common);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT>
|
template <class ELFT>
|
||||||
|
@ -803,22 +809,10 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
||||||
if (HasError)
|
if (HasError)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// If linker script processor hasn't added common symbol section yet,
|
|
||||||
// then add it to .bss now.
|
|
||||||
if (!InputSection<ELFT>::CommonInputSection->OutSec) {
|
|
||||||
Out<ELFT>::Bss->addSection(InputSection<ELFT>::CommonInputSection);
|
|
||||||
Out<ELFT>::Bss->assignOffsets();
|
|
||||||
}
|
|
||||||
|
|
||||||
// So far we have added sections from input object files.
|
// So far we have added sections from input object files.
|
||||||
// This function adds linker-created Out<ELFT>::* sections.
|
// This function adds linker-created Out<ELFT>::* sections.
|
||||||
addPredefinedSections();
|
addPredefinedSections();
|
||||||
|
|
||||||
// Adds linker generated input sections to
|
|
||||||
// corresponding output sections.
|
|
||||||
for (InputSection<ELFT> *S : In<ELFT>::Sections)
|
|
||||||
addInputSec(S);
|
|
||||||
|
|
||||||
sortSections();
|
sortSections();
|
||||||
|
|
||||||
unsigned I = 1;
|
unsigned I = 1;
|
||||||
|
@ -827,11 +821,6 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
||||||
Sec->setSHName(Out<ELFT>::ShStrTab->addString(Sec->getName()));
|
Sec->setSHName(Out<ELFT>::ShStrTab->addString(Sec->getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finalize linker generated sections.
|
|
||||||
for (InputSection<ELFT> *S : In<ELFT>::Sections)
|
|
||||||
if (S && S->OutSec)
|
|
||||||
S->OutSec->assignOffsets();
|
|
||||||
|
|
||||||
// Finalizers fix each section's size.
|
// Finalizers fix each section's size.
|
||||||
// .dynsym is finalized early since that may fill up .gnu.hash.
|
// .dynsym is finalized early since that may fill up .gnu.hash.
|
||||||
if (Out<ELFT>::DynSymTab)
|
if (Out<ELFT>::DynSymTab)
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
# REQUIRES: x86
|
# REQUIRES: x86
|
||||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
|
||||||
# RUN: echo "SECTIONS { . = SIZEOF_HEADERS; .text : { *(.text*) } }" > %t.script
|
# RUN: echo "SECTIONS { . = SIZEOF_HEADERS; " > %t.script
|
||||||
|
# RUN: echo ".text : { *(.text*) }" >> %t.script
|
||||||
|
# RUN: echo ".bss1 : { *(.bss) }" >> %t.script
|
||||||
|
# RUN: echo ".bss2 : { *(COMMON) }" >> %t.script
|
||||||
|
# RUN: echo "}" >> %t.script
|
||||||
|
|
||||||
# RUN: ld.lld -o %t1 --script %t.script %t
|
# RUN: ld.lld -o %t1 --script %t.script %t
|
||||||
# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
|
# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
|
||||||
# CHECK: .bss 00000004 0000000000000122 BSS
|
# CHECK: .bss1 00000004 0000000000000122 BSS
|
||||||
# CHECK-NEXT: .bss 00000080 0000000000000128 BSS
|
# CHECK-NEXT: .bss2 00000080 0000000000000128 BSS
|
||||||
|
|
||||||
.globl _start
|
.globl _start
|
||||||
_start:
|
_start:
|
||||||
|
|
Loading…
Reference in New Issue