[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
``