[WebAssembly] Support multiple .init_array fragments when writing W… · llvm/llvm-project@8069ce6 (original) (raw)

`@@ -1853,49 +1853,54 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,

`

1853

1853

`if (EmptyFrag.getKind() != MCFragment::FT_Data)

`

1854

1854

`report_fatal_error(".init_array section should be aligned");

`

1855

1855

``

1856

``

`-

const MCFragment &AlignFrag = *EmptyFrag.getNext();

`

1857

``

`-

if (AlignFrag.getKind() != MCFragment::FT_Align)

`

1858

``

`-

report_fatal_error(".init_array section should be aligned");

`

1859

``

`-

if (cast(AlignFrag).getAlignment() !=

`

1860

``

`-

Align(is64Bit() ? 8 : 4))

`

1861

``

`-

report_fatal_error(".init_array section should be aligned for pointers");

`

1862

``

-

1863

``

`-

const MCFragment &Frag = *AlignFrag.getNext();

`

1864

``

`-

if (Frag.hasInstructions() || Frag.getKind() != MCFragment::FT_Data)

`

1865

``

`-

report_fatal_error("only data supported in .init_array section");

`

1866

``

-

1867

``

`-

uint16_t Priority = UINT16_MAX;

`

1868

``

`-

unsigned PrefixLength = strlen(".init_array");

`

1869

``

`-

if (WS.getName().size() > PrefixLength) {

`

1870

``

`-

if (WS.getName()[PrefixLength] != '.')

`

``

1856

`+

const MCFragment *nextFrag = EmptyFrag.getNext();

`

``

1857

`+

while (nextFrag != nullptr) {

`

``

1858

`+

const MCFragment &AlignFrag = *nextFrag;

`

``

1859

`+

if (AlignFrag.getKind() != MCFragment::FT_Align)

`

``

1860

`+

report_fatal_error(".init_array section should be aligned");

`

``

1861

`+

if (cast(AlignFrag).getAlignment() !=

`

``

1862

`+

Align(is64Bit() ? 8 : 4))

`

1871

1863

`report_fatal_error(

`

1872

``

`-

".init_array section priority should start with '.'");

`

1873

``

`-

if (WS.getName().substr(PrefixLength + 1).getAsInteger(10, Priority))

`

1874

``

`-

report_fatal_error("invalid .init_array section priority");

`

1875

``

`-

}

`

1876

``

`-

const auto &DataFrag = cast(Frag);

`

1877

``

`-

const SmallVectorImpl &Contents = DataFrag.getContents();

`

1878

``

`-

for (const uint8_t *

`

1879

``

`-

P = (const uint8_t *)Contents.data(),

`

1880

``

`-

*End = (const uint8_t *)Contents.data() + Contents.size();

`

1881

``

`-

P != End; ++P) {

`

1882

``

`-

if (*P != 0)

`

1883

``

`-

report_fatal_error("non-symbolic data in .init_array section");

`

1884

``

`-

}

`

1885

``

`-

for (const MCFixup &Fixup : DataFrag.getFixups()) {

`

1886

``

`-

assert(Fixup.getKind() ==

`

1887

``

`-

MCFixup::getKindForSize(is64Bit() ? 8 : 4, false));

`

1888

``

`-

const MCExpr *Expr = Fixup.getValue();

`

1889

``

`-

auto *SymRef = dyn_cast(Expr);

`

1890

``

`-

if (!SymRef)

`

1891

``

`-

report_fatal_error("fixups in .init_array should be symbol references");

`

1892

``

`-

const auto &TargetSym = cast(SymRef->getSymbol());

`

1893

``

`-

if (TargetSym.getIndex() == InvalidIndex)

`

1894

``

`-

report_fatal_error("symbols in .init_array should exist in symtab");

`

1895

``

`-

if (!TargetSym.isFunction())

`

1896

``

`-

report_fatal_error("symbols in .init_array should be for functions");

`

1897

``

`-

InitFuncs.push_back(

`

1898

``

`-

std::make_pair(Priority, TargetSym.getIndex()));

`

``

1864

`+

".init_array section should be aligned for pointers");

`

``

1865

+

``

1866

`+

const MCFragment &Frag = *AlignFrag.getNext();

`

``

1867

`+

nextFrag = Frag.getNext();

`

``

1868

`+

if (Frag.hasInstructions() || Frag.getKind() != MCFragment::FT_Data)

`

``

1869

`+

report_fatal_error("only data supported in .init_array section");

`

``

1870

+

``

1871

`+

uint16_t Priority = UINT16_MAX;

`

``

1872

`+

unsigned PrefixLength = strlen(".init_array");

`

``

1873

`+

if (WS.getName().size() > PrefixLength) {

`

``

1874

`+

if (WS.getName()[PrefixLength] != '.')

`

``

1875

`+

report_fatal_error(

`

``

1876

`+

".init_array section priority should start with '.'");

`

``

1877

`+

if (WS.getName().substr(PrefixLength + 1).getAsInteger(10, Priority))

`

``

1878

`+

report_fatal_error("invalid .init_array section priority");

`

``

1879

`+

}

`

``

1880

`+

const auto &DataFrag = cast(Frag);

`

``

1881

`+

const SmallVectorImpl &Contents = DataFrag.getContents();

`

``

1882

`+

for (const uint8_t *

`

``

1883

`+

P = (const uint8_t *)Contents.data(),

`

``

1884

`+

*End = (const uint8_t *)Contents.data() + Contents.size();

`

``

1885

`+

P != End; ++P) {

`

``

1886

`+

if (*P != 0)

`

``

1887

`+

report_fatal_error("non-symbolic data in .init_array section");

`

``

1888

`+

}

`

``

1889

`+

for (const MCFixup &Fixup : DataFrag.getFixups()) {

`

``

1890

`+

assert(Fixup.getKind() ==

`

``

1891

`+

MCFixup::getKindForSize(is64Bit() ? 8 : 4, false));

`

``

1892

`+

const MCExpr *Expr = Fixup.getValue();

`

``

1893

`+

auto *SymRef = dyn_cast(Expr);

`

``

1894

`+

if (!SymRef)

`

``

1895

`+

report_fatal_error(

`

``

1896

`+

"fixups in .init_array should be symbol references");

`

``

1897

`+

const auto &TargetSym = cast(SymRef->getSymbol());

`

``

1898

`+

if (TargetSym.getIndex() == InvalidIndex)

`

``

1899

`+

report_fatal_error("symbols in .init_array should exist in symtab");

`

``

1900

`+

if (!TargetSym.isFunction())

`

``

1901

`+

report_fatal_error("symbols in .init_array should be for functions");

`

``

1902

`+

InitFuncs.push_back(std::make_pair(Priority, TargetSym.getIndex()));

`

``

1903

`+

}

`

1899

1904

` }

`

1900

1905

` }

`

1901

1906

``