parent
029af15086
commit
dcf09476ff
|
@ -205,14 +205,33 @@ private:
|
|||
return a->Value < b->Value;
|
||||
}));
|
||||
|
||||
ArrayRef<uint8_t> secData;
|
||||
StringRef sectionName;
|
||||
if (error_code ec = _obj->getSectionContents(section, secData))
|
||||
return ec;
|
||||
if (error_code ec = _obj->getSectionName(section, sectionName))
|
||||
return ec;
|
||||
uint64_t ordinal = -1;
|
||||
|
||||
// BSS section does not have contents. If this is the BSS section, create
|
||||
// COFFBSSAtom instead of COFFDefinedAtom.
|
||||
if (section->Characteristics &
|
||||
llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
|
||||
for (auto si = symbols.begin(), se = symbols.end(); si != se; ++si) {
|
||||
const coff_symbol *sym = *si;
|
||||
uint32_t size = (si + 1 == se)
|
||||
? section->SizeOfRawData - sym->Value
|
||||
: si[1]->Value - sym->Value;
|
||||
auto *atom = new (_alloc) COFFBSSAtom(
|
||||
*this, _symbolName[sym], sym, section, size, sectionName,
|
||||
++ordinal);
|
||||
atoms.push_back(atom);
|
||||
_symbolAtom[sym] = atom;
|
||||
}
|
||||
return error_code::success();
|
||||
}
|
||||
|
||||
ArrayRef<uint8_t> secData;
|
||||
if (error_code ec = _obj->getSectionContents(section, secData))
|
||||
return ec;
|
||||
|
||||
// We do not support debug information yet. We could keep data in ".debug$S"
|
||||
// section in the resultant binary by copying as opaque bytes, but it would
|
||||
// make the binary hard to debug because of extraneous data. So we'll skip
|
||||
|
|
|
@ -432,7 +432,7 @@ public:
|
|||
|
||||
virtual uint32_t getVirtualAddress() { return _sectionHeader.VirtualAddress; }
|
||||
|
||||
const llvm::object::coff_section &getSectionHeader() {
|
||||
virtual llvm::object::coff_section &getSectionHeader() {
|
||||
// Fix up section size before returning it. VirtualSize should be the size
|
||||
// of the actual content, and SizeOfRawData should be aligned to the section
|
||||
// alignment.
|
||||
|
@ -444,7 +444,7 @@ public:
|
|||
void appendAtom(const DefinedAtom *atom) {
|
||||
auto *layout = new (_alloc) AtomLayout(atom, _size, _size);
|
||||
_atomLayouts.push_back(layout);
|
||||
_size += atom->rawContent().size();
|
||||
_size += atom->size();
|
||||
}
|
||||
|
||||
static bool classof(const Chunk *c) { return c->getKind() == kindSection; }
|
||||
|
@ -578,6 +578,35 @@ private:
|
|||
llvm::COFF::IMAGE_SCN_MEM_WRITE;
|
||||
};
|
||||
|
||||
// \brief A DataSectionChunk represents a .data section.
|
||||
class BssSectionChunk : public SectionChunk {
|
||||
public:
|
||||
// BSS section does not have contents, so write should be no-op.
|
||||
virtual void write(uint8_t *fileBuffer) {}
|
||||
|
||||
virtual llvm::object::coff_section &getSectionHeader() {
|
||||
llvm::object::coff_section §ionHeader =
|
||||
SectionChunk::getSectionHeader();
|
||||
sectionHeader.VirtualSize = 0;
|
||||
sectionHeader.PointerToRawData = 0;
|
||||
return sectionHeader;
|
||||
}
|
||||
|
||||
BssSectionChunk(const File &linkedFile)
|
||||
: SectionChunk(".bss", characteristics) {
|
||||
buildContents(linkedFile, [](const DefinedAtom *atom) {
|
||||
return atom->contentType() == DefinedAtom::typeZeroFill;
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
// When loaded into memory, bss section should be readable and writable.
|
||||
static const uint32_t characteristics =
|
||||
llvm::COFF::IMAGE_SCN_MEM_READ |
|
||||
llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
|
||||
llvm::COFF::IMAGE_SCN_MEM_WRITE;
|
||||
};
|
||||
|
||||
/// A BaseRelocAtom represents a base relocation block in ".reloc" section.
|
||||
class BaseRelocAtom : public coff::COFFLinkerInternalAtom {
|
||||
public:
|
||||
|
@ -701,6 +730,7 @@ public:
|
|||
auto *text = new TextSectionChunk(linkedFile);
|
||||
auto *rdata = new RDataSectionChunk(linkedFile);
|
||||
auto *data = new DataSectionChunk(linkedFile);
|
||||
auto *bss = new BssSectionChunk(linkedFile);
|
||||
BaseRelocChunk *baseReloc = nullptr;
|
||||
if (_PECOFFTargetInfo.getBaseRelocationEnabled())
|
||||
baseReloc = new BaseRelocChunk(linkedFile);
|
||||
|
@ -718,6 +748,8 @@ public:
|
|||
addSectionChunk(rdata, sectionTable);
|
||||
if (data->size())
|
||||
addSectionChunk(data, sectionTable);
|
||||
if (bss->size())
|
||||
addSectionChunk(bss, sectionTable);
|
||||
|
||||
// Now that we know the addresses of all defined atoms that needs to be
|
||||
// relocated. So we can create the ".reloc" section which contains all the
|
||||
|
@ -745,6 +777,7 @@ public:
|
|||
peHeader->setBaseOfData(data->getVirtualAddress());
|
||||
}
|
||||
peHeader->setSizeOfInitializedData(rdata->size() + data->size());
|
||||
peHeader->setSizeOfUninitializedData(bss->size());
|
||||
peHeader->setNumberOfSections(_numSections);
|
||||
peHeader->setSizeOfImage(_imageSizeInMemory);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
.586
|
||||
.model flat, c
|
||||
|
||||
extern ExitProcess@4 : PROC
|
||||
|
||||
_BSS SEGMENT
|
||||
_x DD 064H DUP (?)
|
||||
_y DD 064H DUP (?)
|
||||
_BSS ENDS
|
||||
|
||||
.code
|
||||
start:
|
||||
mov eax, 42
|
||||
mov _x, eax
|
||||
mov eax, _x
|
||||
push eax
|
||||
call ExitProcess@4
|
||||
end start
|
||||
|
||||
end
|
Binary file not shown.
|
@ -0,0 +1,20 @@
|
|||
# RUN: lld -flavor link /out:%t /subsystem:console /force -- %p/Inputs/bss.obj \
|
||||
# RUN: && llvm-readobj -sections %t | FileCheck %s
|
||||
|
||||
CHECK: Section {
|
||||
CHECK: Number: 2
|
||||
CHECK-NEXT: Name: .bss
|
||||
CHECK-NEXT: VirtualSize: 0x0
|
||||
CHECK-NEXT: VirtualAddress: 0x2000
|
||||
CHECK-NEXT: RawDataSize: 1024
|
||||
CHECK-NEXT: PointerToRawData: 0x0
|
||||
CHECK-NEXT: PointerToRelocations: 0x0
|
||||
CHECK-NEXT: PointerToLineNumbers: 0x0
|
||||
CHECK-NEXT: RelocationCount: 0
|
||||
CHECK-NEXT: LineNumberCount: 0
|
||||
CHECK-NEXT: Characteristics [
|
||||
CHECK-NEXT: IMAGE_SCN_CNT_UNINITIALIZED_DATA
|
||||
CHECK-NEXT: IMAGE_SCN_MEM_READ
|
||||
CHECK-NEXT: IMAGE_SCN_MEM_WRITE
|
||||
CHECK-NEXT: ]
|
||||
CHECK-NEXT: }
|
Loading…
Reference in New Issue