forked from OSchip/llvm-project
[ELF] Allows setting section for common symbols in linker script
llvm-svn: 277023
This commit is contained in:
parent
1415cb9cbe
commit
3e6b027705
|
|
@ -14,6 +14,7 @@
|
|||
#include "InputFiles.h"
|
||||
#include "LinkerScript.h"
|
||||
#include "OutputSections.h"
|
||||
#include "SymbolTable.h"
|
||||
#include "Target.h"
|
||||
#include "Thunks.h"
|
||||
|
||||
|
|
@ -666,6 +667,44 @@ bool MipsOptionsInputSection<ELFT>::classof(const InputSectionBase<ELFT> *S) {
|
|||
return S->SectionKind == InputSectionBase<ELFT>::MipsOptions;
|
||||
}
|
||||
|
||||
// Due to initialization order in C++ memberwise initialization or
|
||||
// construction is invoked after base class construction. This helper
|
||||
// function is needed to zero initialize Elf_Shdr, before passing it
|
||||
// to InputSection<ELFT> constructor
|
||||
template <class T> static T *zero(T *Val) {
|
||||
return static_cast<T *>(memset(Val, 0, sizeof(*Val)));
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
CommonInputSection<ELFT>::CommonInputSection()
|
||||
: InputSection<ELFT>(nullptr, zero(&Hdr)) {
|
||||
std::vector<DefinedCommon<ELFT> *> Symbols;
|
||||
Hdr.sh_size = 0;
|
||||
Hdr.sh_type = SHT_NOBITS;
|
||||
Hdr.sh_flags = SHF_ALLOC | SHF_WRITE;
|
||||
this->Live = true;
|
||||
|
||||
for (Symbol *S : Symtab<ELFT>::X->getSymbols())
|
||||
if (auto *C = dyn_cast<DefinedCommon<ELFT>>(S->body()))
|
||||
Symbols.push_back(C);
|
||||
|
||||
std::stable_sort(
|
||||
Symbols.begin(), Symbols.end(),
|
||||
[](const DefinedCommon<ELFT> *A, const DefinedCommon<ELFT> *B) {
|
||||
return A->Alignment > B->Alignment;
|
||||
});
|
||||
|
||||
for (DefinedCommon<ELFT> *C : Symbols) {
|
||||
this->Alignment = std::max<uintX_t>(this->Alignment, C->Alignment);
|
||||
Hdr.sh_size = alignTo(Hdr.sh_size, C->Alignment);
|
||||
|
||||
// Compute symbol offset relative to beginning of input section.
|
||||
C->Offset = Hdr.sh_size;
|
||||
C->Section = this;
|
||||
Hdr.sh_size += C->Size;
|
||||
}
|
||||
}
|
||||
|
||||
template class elf::InputSectionBase<ELF32LE>;
|
||||
template class elf::InputSectionBase<ELF32BE>;
|
||||
template class elf::InputSectionBase<ELF64LE>;
|
||||
|
|
@ -695,3 +734,8 @@ template class elf::MipsOptionsInputSection<ELF32LE>;
|
|||
template class elf::MipsOptionsInputSection<ELF32BE>;
|
||||
template class elf::MipsOptionsInputSection<ELF64LE>;
|
||||
template class elf::MipsOptionsInputSection<ELF64BE>;
|
||||
|
||||
template class elf::CommonInputSection<ELF32LE>;
|
||||
template class elf::CommonInputSection<ELF32BE>;
|
||||
template class elf::CommonInputSection<ELF64LE>;
|
||||
template class elf::CommonInputSection<ELF64BE>;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ class SymbolBody;
|
|||
|
||||
template <class ELFT> class ICF;
|
||||
template <class ELFT> class DefinedRegular;
|
||||
template <class ELFT> class DefinedCommon;
|
||||
template <class ELFT> class ObjectFile;
|
||||
template <class ELFT> class OutputSection;
|
||||
template <class ELFT> class OutputSectionBase;
|
||||
|
|
@ -256,6 +257,17 @@ public:
|
|||
const llvm::object::Elf_Mips_RegInfo<ELFT> *Reginfo = nullptr;
|
||||
};
|
||||
|
||||
// A special kind of section used to store common symbols
|
||||
template <class ELFT> class CommonInputSection : public InputSection<ELFT> {
|
||||
typedef typename ELFT::uint uintX_t;
|
||||
|
||||
public:
|
||||
CommonInputSection();
|
||||
|
||||
private:
|
||||
typename ELFT::Shdr Hdr;
|
||||
};
|
||||
|
||||
} // namespace elf
|
||||
} // namespace lld
|
||||
|
||||
|
|
|
|||
|
|
@ -95,7 +95,8 @@ LinkerScript<ELFT>::getSectionMap() {
|
|||
// Returns input sections filtered by given glob patterns.
|
||||
template <class ELFT>
|
||||
std::vector<InputSectionBase<ELFT> *>
|
||||
LinkerScript<ELFT>::getInputSections(const InputSectionDescription *I) {
|
||||
LinkerScript<ELFT>::getInputSections(const InputSectionDescription *I,
|
||||
CommonInputSection<ELFT> *Common) {
|
||||
ArrayRef<StringRef> Patterns = I->Patterns;
|
||||
ArrayRef<StringRef> ExcludedFiles = I->ExcludedFiles;
|
||||
std::vector<InputSectionBase<ELFT> *> Ret;
|
||||
|
|
@ -106,12 +107,17 @@ LinkerScript<ELFT>::getInputSections(const InputSectionDescription *I) {
|
|||
if (ExcludedFiles.empty() ||
|
||||
!match(ExcludedFiles, sys::path::filename(F->getName())))
|
||||
Ret.push_back(S);
|
||||
|
||||
if ((llvm::find(Patterns, "COMMON") != Patterns.end()))
|
||||
Ret.push_back(Common);
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
std::vector<OutputSectionBase<ELFT> *>
|
||||
LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
|
||||
LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory,
|
||||
CommonInputSection<ELFT> *Common) {
|
||||
std::vector<OutputSectionBase<ELFT> *> Ret;
|
||||
|
||||
// Add input section to output section. If there is no output section yet,
|
||||
|
|
@ -128,7 +134,7 @@ LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
|
|||
for (auto &P : getSectionMap()) {
|
||||
StringRef OutputName = P.first;
|
||||
const InputSectionDescription *I = P.second;
|
||||
for (InputSectionBase<ELFT> *S : getInputSections(I)) {
|
||||
for (InputSectionBase<ELFT> *S : getInputSections(I, Common)) {
|
||||
if (OutputName == "/DISCARD/") {
|
||||
S->Live = false;
|
||||
reportDiscarded(S);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ namespace elf {
|
|||
template <class ELFT> class InputSectionBase;
|
||||
template <class ELFT> class OutputSectionBase;
|
||||
template <class ELFT> class OutputSectionFactory;
|
||||
template <class ELFT> class DefinedCommon;
|
||||
template <class ELFT> class CommonInputSection;
|
||||
|
||||
typedef std::function<uint64_t(uint64_t)> Expr;
|
||||
|
||||
|
|
@ -120,7 +122,8 @@ template <class ELFT> class LinkerScript {
|
|||
|
||||
public:
|
||||
std::vector<OutputSectionBase<ELFT> *>
|
||||
createSections(OutputSectionFactory<ELFT> &Factory);
|
||||
createSections(OutputSectionFactory<ELFT> &Factory,
|
||||
CommonInputSection<ELFT> *Common);
|
||||
|
||||
std::vector<PhdrEntry<ELFT>>
|
||||
createPhdrs(ArrayRef<OutputSectionBase<ELFT> *> S);
|
||||
|
|
@ -137,7 +140,7 @@ private:
|
|||
getSectionMap();
|
||||
|
||||
std::vector<InputSectionBase<ELFT> *>
|
||||
getInputSections(const InputSectionDescription *);
|
||||
getInputSections(const InputSectionDescription *, CommonInputSection<ELFT> *);
|
||||
|
||||
// "ScriptConfig" is a bit too long, so define a short name for it.
|
||||
ScriptConfiguration &Opt = *ScriptConfig;
|
||||
|
|
|
|||
|
|
@ -1448,7 +1448,7 @@ SymbolTableSection<ELFT>::getOutputSection(SymbolBody *Sym) {
|
|||
break;
|
||||
}
|
||||
case SymbolBody::DefinedCommonKind:
|
||||
return Out<ELFT>::Bss;
|
||||
return cast<DefinedCommon<ELFT>>(Sym)->Section->OutSec;
|
||||
case SymbolBody::SharedKind:
|
||||
if (cast<SharedSymbol<ELFT>>(Sym)->needsCopy())
|
||||
return Out<ELFT>::Bss;
|
||||
|
|
|
|||
|
|
@ -322,13 +322,15 @@ static int compareDefined(Symbol *S, bool WasInserted, uint8_t Binding) {
|
|||
// We have a new non-common defined symbol with the specified binding. Return 1
|
||||
// if the new symbol should win, -1 if the new symbol should lose, or 0 if there
|
||||
// is a conflict. If the new symbol wins, also update the binding.
|
||||
static int compareDefinedNonCommon(Symbol *S, bool WasInserted, uint8_t Binding) {
|
||||
template <class ELFT>
|
||||
static int compareDefinedNonCommon(Symbol *S, bool WasInserted,
|
||||
uint8_t Binding) {
|
||||
if (int Cmp = compareDefined(S, WasInserted, Binding)) {
|
||||
if (Cmp > 0)
|
||||
S->Binding = Binding;
|
||||
return Cmp;
|
||||
}
|
||||
if (isa<DefinedCommon>(S->body())) {
|
||||
if (isa<DefinedCommon<ELFT>>(S->body())) {
|
||||
// Non-common symbols take precedence over common symbols.
|
||||
if (Config->WarnCommon)
|
||||
warning("common " + S->body()->getName() + " is overridden");
|
||||
|
|
@ -350,9 +352,10 @@ Symbol *SymbolTable<ELFT>::addCommon(StringRef N, uint64_t Size,
|
|||
int Cmp = compareDefined(S, WasInserted, Binding);
|
||||
if (Cmp > 0) {
|
||||
S->Binding = Binding;
|
||||
replaceBody<DefinedCommon>(S, N, Size, Alignment, StOther, Type, File);
|
||||
replaceBody<DefinedCommon<ELFT>>(S, N, Size, Alignment, StOther, Type,
|
||||
File);
|
||||
} else if (Cmp == 0) {
|
||||
auto *C = dyn_cast<DefinedCommon>(S->body());
|
||||
auto *C = dyn_cast<DefinedCommon<ELFT>>(S->body());
|
||||
if (!C) {
|
||||
// Non-common symbols take precedence over common symbols.
|
||||
if (Config->WarnCommon)
|
||||
|
|
@ -388,7 +391,7 @@ Symbol *SymbolTable<ELFT>::addRegular(StringRef Name, const Elf_Sym &Sym,
|
|||
insert(Name, Sym.getType(), Sym.getVisibility(),
|
||||
/*CanOmitFromDynSym*/ false, /*IsUsedInRegularObj*/ true,
|
||||
Section ? Section->getFile() : nullptr);
|
||||
int Cmp = compareDefinedNonCommon(S, WasInserted, Sym.getBinding());
|
||||
int Cmp = compareDefinedNonCommon<ELFT>(S, WasInserted, Sym.getBinding());
|
||||
if (Cmp > 0)
|
||||
replaceBody<DefinedRegular<ELFT>>(S, Name, Sym, Section);
|
||||
else if (Cmp == 0)
|
||||
|
|
@ -404,7 +407,7 @@ Symbol *SymbolTable<ELFT>::addRegular(StringRef Name, uint8_t Binding,
|
|||
std::tie(S, WasInserted) =
|
||||
insert(Name, STT_NOTYPE, StOther & 3, /*CanOmitFromDynSym*/ false,
|
||||
/*IsUsedInRegularObj*/ true, nullptr);
|
||||
int Cmp = compareDefinedNonCommon(S, WasInserted, Binding);
|
||||
int Cmp = compareDefinedNonCommon<ELFT>(S, WasInserted, Binding);
|
||||
if (Cmp > 0)
|
||||
replaceBody<DefinedRegular<ELFT>>(S, Name, StOther);
|
||||
else if (Cmp == 0)
|
||||
|
|
@ -421,7 +424,7 @@ Symbol *SymbolTable<ELFT>::addSynthetic(StringRef N,
|
|||
std::tie(S, WasInserted) =
|
||||
insert(N, STT_NOTYPE, STV_HIDDEN, /*CanOmitFromDynSym*/ false,
|
||||
/*IsUsedInRegularObj*/ true, nullptr);
|
||||
int Cmp = compareDefinedNonCommon(S, WasInserted, STB_GLOBAL);
|
||||
int Cmp = compareDefinedNonCommon<ELFT>(S, WasInserted, STB_GLOBAL);
|
||||
if (Cmp > 0)
|
||||
replaceBody<DefinedSynthetic<ELFT>>(S, N, Value, Section);
|
||||
else if (Cmp == 0)
|
||||
|
|
@ -459,8 +462,8 @@ Symbol *SymbolTable<ELFT>::addBitcode(StringRef Name, bool IsWeak,
|
|||
bool WasInserted;
|
||||
std::tie(S, WasInserted) = insert(Name, Type, StOther & 3, CanOmitFromDynSym,
|
||||
/*IsUsedInRegularObj*/ false, F);
|
||||
int Cmp =
|
||||
compareDefinedNonCommon(S, WasInserted, IsWeak ? STB_WEAK : STB_GLOBAL);
|
||||
int Cmp = compareDefinedNonCommon<ELFT>(S, WasInserted,
|
||||
IsWeak ? STB_WEAK : STB_GLOBAL);
|
||||
if (Cmp > 0)
|
||||
replaceBody<DefinedBitcode>(S, Name, StOther, Type, F);
|
||||
else if (Cmp == 0)
|
||||
|
|
|
|||
|
|
@ -63,8 +63,10 @@ static typename ELFT::uint getSymVA(const SymbolBody &Body,
|
|||
return VA - Out<ELFT>::TlsPhdr->p_vaddr;
|
||||
return VA;
|
||||
}
|
||||
case SymbolBody::DefinedCommonKind:
|
||||
return Out<ELFT>::Bss->getVA() + cast<DefinedCommon>(Body).OffsetInBss;
|
||||
case SymbolBody::DefinedCommonKind: {
|
||||
auto &D = cast<DefinedCommon<ELFT>>(Body);
|
||||
return D.Section->OutSec->getVA() + D.Section->OutSecOff + D.Offset;
|
||||
}
|
||||
case SymbolBody::SharedKind: {
|
||||
auto &SS = cast<SharedSymbol<ELFT>>(Body);
|
||||
if (!SS.NeedsCopyOrPltAddr)
|
||||
|
|
@ -175,7 +177,7 @@ template <class ELFT> typename ELFT::uint SymbolBody::getThunkVA() const {
|
|||
}
|
||||
|
||||
template <class ELFT> typename ELFT::uint SymbolBody::getSize() const {
|
||||
if (const auto *C = dyn_cast<DefinedCommon>(this))
|
||||
if (const auto *C = dyn_cast<DefinedCommon<ELFT>>(this))
|
||||
return C->Size;
|
||||
if (const auto *DR = dyn_cast<DefinedRegular<ELFT>>(this))
|
||||
return DR->Size;
|
||||
|
|
@ -218,8 +220,10 @@ DefinedSynthetic<ELFT>::DefinedSynthetic(StringRef N, uintX_t Value,
|
|||
: Defined(SymbolBody::DefinedSyntheticKind, N, STV_HIDDEN, 0 /* Type */),
|
||||
Value(Value), Section(Section) {}
|
||||
|
||||
DefinedCommon::DefinedCommon(StringRef N, uint64_t Size, uint64_t Alignment,
|
||||
uint8_t StOther, uint8_t Type, InputFile *File)
|
||||
template <class ELFT>
|
||||
DefinedCommon<ELFT>::DefinedCommon(StringRef N, uint64_t Size,
|
||||
uint64_t Alignment, uint8_t StOther,
|
||||
uint8_t Type, InputFile *File)
|
||||
: Defined(SymbolBody::DefinedCommonKind, N, StOther, Type),
|
||||
Alignment(Alignment), Size(Size) {
|
||||
this->File = File;
|
||||
|
|
@ -329,3 +333,8 @@ template class elf::DefinedSynthetic<ELF32LE>;
|
|||
template class elf::DefinedSynthetic<ELF32BE>;
|
||||
template class elf::DefinedSynthetic<ELF64LE>;
|
||||
template class elf::DefinedSynthetic<ELF64BE>;
|
||||
|
||||
template class elf::DefinedCommon<ELF32LE>;
|
||||
template class elf::DefinedCommon<ELF32BE>;
|
||||
template class elf::DefinedCommon<ELF64LE>;
|
||||
template class elf::DefinedCommon<ELF64BE>;
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ public:
|
|||
BitcodeFile *file() { return (BitcodeFile *)this->File; }
|
||||
};
|
||||
|
||||
class DefinedCommon : public Defined {
|
||||
template <class ELFT> class DefinedCommon : public Defined {
|
||||
public:
|
||||
DefinedCommon(StringRef N, uint64_t Size, uint64_t Alignment, uint8_t StOther,
|
||||
uint8_t Type, InputFile *File);
|
||||
|
|
@ -178,12 +178,15 @@ public:
|
|||
|
||||
// The output offset of this common symbol in the output bss. Computed by the
|
||||
// writer.
|
||||
uint64_t OffsetInBss;
|
||||
uint64_t Offset;
|
||||
|
||||
// The maximum alignment we have seen for this symbol.
|
||||
uint64_t Alignment;
|
||||
|
||||
uint64_t Size;
|
||||
|
||||
// Virtual input section for common symbols.
|
||||
CommonInputSection<ELFT> *Section;
|
||||
};
|
||||
|
||||
// Regular defined symbols read from object file symbol tables.
|
||||
|
|
@ -433,7 +436,8 @@ struct Symbol {
|
|||
// assume that the size and alignment of ELF64LE symbols is sufficient for any
|
||||
// ELFT, and we verify this with the static_asserts in replaceBody.
|
||||
llvm::AlignedCharArrayUnion<
|
||||
DefinedBitcode, DefinedCommon, DefinedRegular<llvm::object::ELF64LE>,
|
||||
DefinedBitcode, DefinedCommon<llvm::object::ELF64LE>,
|
||||
DefinedRegular<llvm::object::ELF64LE>,
|
||||
DefinedSynthetic<llvm::object::ELF64LE>, Undefined,
|
||||
SharedSymbol<llvm::object::ELF64LE>, LazyArchive, LazyObject>
|
||||
Body;
|
||||
|
|
|
|||
|
|
@ -68,12 +68,11 @@ private:
|
|||
void writeSections();
|
||||
void writeBuildId();
|
||||
|
||||
void addCommonSymbols(std::vector<DefinedCommon *> &Syms);
|
||||
|
||||
std::unique_ptr<FileOutputBuffer> Buffer;
|
||||
|
||||
BumpPtrAllocator Alloc;
|
||||
std::vector<OutputSectionBase<ELFT> *> OutputSections;
|
||||
std::unique_ptr<CommonInputSection<ELFT>> CommonSection;
|
||||
OutputSectionFactory<ELFT> Factory;
|
||||
|
||||
void addRelIpltSymbols();
|
||||
|
|
@ -223,8 +222,10 @@ template <class ELFT> void Writer<ELFT>::run() {
|
|||
copyLocalSymbols();
|
||||
addReservedSymbols();
|
||||
|
||||
OutputSections = ScriptConfig->DoLayout
|
||||
? Script<ELFT>::X->createSections(Factory)
|
||||
CommonSection = llvm::make_unique<CommonInputSection<ELFT>>();
|
||||
OutputSections =
|
||||
ScriptConfig->DoLayout
|
||||
? Script<ELFT>::X->createSections(Factory, CommonSection.get())
|
||||
: createSections();
|
||||
finalizeSections();
|
||||
if (HasError)
|
||||
|
|
@ -490,30 +491,6 @@ void PhdrEntry<ELFT>::add(OutputSectionBase<ELFT> *Sec) {
|
|||
H.p_align = std::max<typename ELFT::uint>(H.p_align, Sec->getAlignment());
|
||||
}
|
||||
|
||||
// Until this function is called, common symbols do not belong to any section.
|
||||
// This function adds them to end of BSS section.
|
||||
template <class ELFT>
|
||||
void Writer<ELFT>::addCommonSymbols(std::vector<DefinedCommon *> &Syms) {
|
||||
if (Syms.empty())
|
||||
return;
|
||||
|
||||
// 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;
|
||||
});
|
||||
|
||||
uintX_t Off = Out<ELFT>::Bss->getSize();
|
||||
for (DefinedCommon *C : Syms) {
|
||||
Off = alignTo(Off, C->Alignment);
|
||||
Out<ELFT>::Bss->updateAlignment(C->Alignment);
|
||||
C->OffsetInBss = Off;
|
||||
Off += C->Size;
|
||||
}
|
||||
|
||||
Out<ELFT>::Bss->setSize(Off);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
static Symbol *addOptionalSynthetic(SymbolTable<ELFT> &Table, StringRef Name,
|
||||
OutputSectionBase<ELFT> *Sec,
|
||||
|
|
@ -734,7 +711,6 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
|||
|
||||
// Now that we have defined all possible symbols including linker-
|
||||
// synthesized ones. Visit all symbols to give the finishing touches.
|
||||
std::vector<DefinedCommon *> CommonSymbols;
|
||||
for (Symbol *S : Symtab.getSymbols()) {
|
||||
SymbolBody *Body = S->body();
|
||||
|
||||
|
|
@ -743,9 +719,6 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
|||
if (S->IsUsedInRegularObj && Body->isUndefined() && !S->isWeak())
|
||||
reportUndefined<ELFT>(Symtab, Body);
|
||||
|
||||
if (auto *C = dyn_cast<DefinedCommon>(Body))
|
||||
CommonSymbols.push_back(C);
|
||||
|
||||
if (!includeInSymtab<ELFT>(*Body))
|
||||
continue;
|
||||
if (Out<ELFT>::SymTab)
|
||||
|
|
@ -763,7 +736,12 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
|||
if (HasError)
|
||||
return;
|
||||
|
||||
addCommonSymbols(CommonSymbols);
|
||||
// If linker script processor hasn't added common symbol section yet,
|
||||
// then add it to .bss now.
|
||||
if (!CommonSection->OutSec) {
|
||||
Out<ELFT>::Bss->addSection(CommonSection.get());
|
||||
Out<ELFT>::Bss->assignOffsets();
|
||||
}
|
||||
|
||||
// So far we have added sections from input object files.
|
||||
// This function adds linker-created Out<ELFT>::* sections.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
# REQUIRES: x86
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
|
||||
# RUN: echo "SECTIONS { .common : { *(COMMON) } }" > %t.script
|
||||
# RUN: ld.lld -o %t1 --script %t.script %t
|
||||
# RUN: llvm-readobj -s -t %t1 | FileCheck %s
|
||||
|
||||
# q2 alignment is greater than q1, so it should have smaller offset
|
||||
# because of sorting
|
||||
# CHECK: Section {
|
||||
# CHECK: Index: 1
|
||||
# CHECK-NEXT: Name: .common (1)
|
||||
# CHECK-NEXT: Type: SHT_NOBITS (0x8)
|
||||
# CHECK-NEXT: Flags [ (0x3)
|
||||
# CHECK-NEXT: SHF_ALLOC (0x2)
|
||||
# CHECK-NEXT: SHF_WRITE (0x1)
|
||||
# CHECK-NEXT: ]
|
||||
# CHECK-NEXT: Address: 0x200
|
||||
# CHECK-NEXT: Offset: 0x158
|
||||
# CHECK-NEXT: Size: 256
|
||||
# CHECK-NEXT: Link: 0
|
||||
# CHECK-NEXT: Info: 0
|
||||
# CHECK-NEXT: AddressAlignment: 256
|
||||
# CHECK-NEXT: EntrySize: 0
|
||||
# CHECK-NEXT: }
|
||||
# CHECK: Symbol {
|
||||
# CHECK: Name: q1 (8)
|
||||
# CHECK-NEXT: Value: 0x280
|
||||
# CHECK-NEXT: Size: 128
|
||||
# CHECK-NEXT: Binding: Global (0x1)
|
||||
# CHECK-NEXT: Type: Object (0x1)
|
||||
# CHECK-NEXT: Other: 0
|
||||
# CHECK-NEXT: Section: .common (0x1)
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: Symbol {
|
||||
# CHECK-NEXT: Name: q2 (11)
|
||||
# CHECK-NEXT: Value: 0x200
|
||||
# CHECK-NEXT: Size: 128
|
||||
# CHECK-NEXT: Binding: Global (0x1)
|
||||
# CHECK-NEXT: Type: Object (0x1)
|
||||
# CHECK-NEXT: Other: 0
|
||||
# CHECK-NEXT: Section: .common (0x1)
|
||||
# CHECK-NEXT: }
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
jmp _start
|
||||
|
||||
.comm q1,128,8
|
||||
.comm q2,128,256
|
||||
Loading…
Reference in New Issue